#clojure log - Feb 07 2009

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

0:02 gnuvince_: I don't get why the type hint doesn't work with .get and .getShort

0:03 Reflection warning, line: 16 - call to and can't be resolved.

0:03 Chouser: yeah, it's the bit-and that's complaining

0:04 i'm working on that

0:04 but I just realized I'm using a patched clojure and it my be acting differently...

0:08 gnuvince_: Got it

0:09 lisppaste8: gnuvince pasted "avoiding reflection" at http://paste.lisp.org/display/75003

0:10 * gnuvince_ starts another profile

0:10 Chouser: you found a pathalogical corner case there. :-)

0:12 gnuvince_: Is that what Rich means when he talks about wanting the JVM to support unboxing?

0:12 I cannot recall the exact wording

0:15 Chouser: it does support unboxing. But he wants tagged numbers, I think it's called, where you'd get number "objects" that are as small and fast as primitives, but can be passed around and introspected like Object

0:16 so you'd still need type hints of the #^ByteBuffer variety, but the mucking about with primitive locals and stuff I think would go away.

0:17 gnuvince_: OK

0:17 That'd be cool.

0:17 Chouser: indeed!

0:17 gnuvince_: The profiling just finished

0:17 the first mention of reflect is at position 460 (for my dump.clj script where I don't use a hint)

0:17 Chouser: good!

0:17 gnuvince_: Calling the unpack function from the REPL takes about 300 ms

0:18 Chouser: is the whole thing any faster?

0:18 gnuvince_: (down from 5-6 seconds)

0:18 Chouser: nice

0:18 gnuvince_: Very much so, yes.

0:18 Thanks for the help

0:18 Chouser: you're welcome

0:18 Raynes: I wish I had a Clojurebot :|

0:18 Chouser: Raynes: ?

0:18 Raynes: ,(doc flush)

0:18 clojurebot: "([]); Flushes the output stream that is the current value of *out*"

0:18 * Raynes hugs clojurebot

0:19 gnuvince_: The first two "performance takers" are Object.wait() and ReferenceQueue.remove

0:20 Chouser: huh! you're multithreaded?

0:24 gnuvince_: no

0:25 That shouldn't be there?

0:25 Chouser: oh, I don't know anything. That just sounds like waiting on a lock, but I really don't know.

0:26 gnuvince_: I see those two in every program I have.

0:26 Even if they are purely functional (as starcraft.replay is)

0:26 Chouser: ok Object.wait() is just blocking until a notify. looks harmless.

1:25 * clojurebot hugs Raynes back

1:25 Raynes: O_O

1:25 * offby1 backs away slowly

1:26 offby1: clojurebot: help

1:26 clojurebot: macro help is http://clojure-log.n01se.net/macro.html

1:26 offby1: clojurebot: source

1:26 clojurebot: I don't understand.

1:37 hiredman: clojurebot: where are you?

1:37 clojurebot: http://github.com/hiredman/clojurebot/tree/master

1:41 offby1: ah.

1:41 I guess one needs to speak the local dialect.

4:45 flap: anyone use Fiji?

4:45 i dont get the scripting part, can i do it inside imageJ?

4:45 i mean inside fiji?

4:45 or just liek i normally do in emacs?

5:57 leafw: to flap, for the record: just open the prompt at "Plugins - Scripting - Clojure Interpreter". See http://pacific.mpi-cbg.de/wiki/index.php/Clojure_Scripting#Using_Clojure_inside_Fiji for how to create and run clojure scripts.

6:02 bakkdoor: i have a problem with using (:use <namespace>) in a (ns ..) declaration within emacs & slime. it tells me that it cant find the specified name within my classpath. how can i tell it to add the current path of the opened file to the classpath?

8:33 lpetit: Hello, all

8:33 metaperl: lpetit: hi!

8:36 lpetit: I've tried the patch to clojure.lang.Compiler.writeClassFile() that ensures that the underlying OS is synchronized before leaving. Works like a charm for me.

8:57 rhickey: is it time to speak about this ? Or do you prefer another time to consider it ? If you please just let me know, I won't bother you with that until the time you decide.

9:43 rhickey: lpetit: what does the call to lastModified do after close()?

9:44 lpetit: Oh sorry, this call does nothing, it was from a previous attempt

9:44 The important part is just the call to sync()

9:45 I should not have published the code with the line containing lastModified(), my apologizes

9:45 rhickey: lpetit: np

9:46 lpetit: Before discovering the right way to force the sync, I was trying indirect ways by calling functions on the File instance ;-)

9:46 I was just writing another e-mail (!), still concerning compilation. It'll be posted within seconds.

9:48 rhickey: lpetit: sync call in svn 1252

9:48 lpetit: Oh thank you very much!

9:49 I must quit in 5 minutes, any chance to quickly talk about the short e-mail I just sent to the ml ?

9:50 clojurebot: svn rev 1252; added sync to writeClassFile

9:51 lpetit: Oh! clojurebot is really up to date :-)

9:53 rhickey: lpetit: I think it's an ok idea, but it's not as simple as you might think

9:55 lpetit: Argh

9:55 If you give me some hints, maybe I can try, or is it really that 'touchy' ?

10:09 rhickey: maybe the file path information should be added first in the source, that is as an additional metadata of the var ?

10:10 rhickey: another option would be to have SOURCE modified to be fully qualified. But I suspect such a change would break a lot of things, even outside clojure's code base, since it would break a published contract with clojure client code ?

10:14 I must quit now. I don't have an very powerful IRC client, so I won't be able to read further answers.

10:14 See you,

12:33 ozy`: ,(first "pizza")

12:33 clojurebot: \p

12:34 ozy`: ,(rest "cheese")

12:34 clojurebot: (\h \e \e \s \e)

12:36 ozy`: ,(first map)

12:36 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: core$map__3634

12:36 ozy`: ,(first 'map)

12:36 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Symbol

12:36 ayrnieu: ,(-> 'map name first)

12:36 clojurebot: \m

12:37 ozy`: ... I need to look that up

12:38 durka42: ,(-> map var .sym name first)

12:38 clojurebot: \m

12:39 ozy`: ahhh

12:39 danlarkin: (doto map name first)

12:39 ,(doto map name first)

12:39 clojurebot: java.lang.ClassCastException: clojure.core$map__3634 cannot be cast to clojure.lang.Named

12:39 danlarkin: bah

12:39 ayrnieu: ,(macroexpand-1 '(doto map name first))

12:39 clojurebot: (clojure.core/let [G__1252 map] (name G__1252) (first G__1252) G__1252)

12:39 durka42: that won't do it

12:39 doto doesn't nest

12:40 ,(macroexpand-1 '(-> map var .sym name first))

12:40 clojurebot: (clojure.core/-> (clojure.core/-> map var) .sym name first)

12:40 durka42: ,(macroexpand '(-> map var .sym name first))

12:40 clojurebot: (first (clojure.core/-> (clojure.core/-> (clojure.core/-> map var) .sym) name))

12:40 danlarkin: durka42: oh duh you're right

12:41 ayrnieu: mixed -> and doto: http://paste.lisp.org/display/74762

12:41 ozy`: ,(macroexpand '(fn [f g] '(fn [xs] (f (g xs)))))

12:41 clojurebot: (fn* ([f g] (quote (fn [xs] (f (g xs))))))

12:42 ozy`: ,(macroexpand '(let (a b) (c d)))

12:42 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: let requires a vector for its binding

12:43 ozy`: ,(macroexpand '(let [a b] (c d)))

12:43 clojurebot: (let* [a b] (c d))

12:43 ozy`: ayrnieu: PLO seems to be down for me

12:43 ayrnieu: PLO?

12:43 ozy`: paste.lisp.org

12:43 durka42: as evidenced by the fact that lisppaste8 just died

12:43 ayrnieu: still responding to me.

12:44 danlarkin: the Palestinian liberation organization?

12:44 durka42: but i don't think it's down

12:44 ayrnieu: People's Liberation Orchestra

13:03 turbo24prg: is there any function in the clojure namespace to check if a list contains an item?

13:04 contains? just works on maps

13:04 danlarkin: turbo24prg: and sets!

13:06 turbo24prg: uh, strange

13:06 doc just tells the [map key] signature

13:08 ayrnieu: ,(map #(.contains % 3) '(1 2 3 4) [1 2 3 4])

13:08 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--1266$fn

13:08 ayrnieu: ,(map #(.contains % 3) ['(1 2 3 4) [1 2 3 4]])

13:08 clojurebot: (true true)

13:10 turbo24prg: ah, .contains

13:10 should be documented, imho

13:10 Chousuke: it's probably documented in the javadoc.

13:11 http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html#contains(java.lang.Object)

13:13 danlarkin: ok, how about terpsichore as the name for my framework

13:14 greek muse of dance and music

13:15 ayrnieu: your what framework?

13:15 turbo24prg: i'd rather call clojure's api than java's

13:16 ayrnieu: (defn scared-of-java-contains [coll mem] (.contains coll mem)) ;; solved

13:17 danlarkin: ayrnieu: port/rewrite/reimagining of django in clojure

13:19 ayrnieu: (defn clj-at-any-cost [coll mem] ((apply hash-map (interleave coll (repeat true))) mem))

13:22 danlarkin: turbo24prg: the "clojurish" way to solve this is (some #{:y} [:x :y :z])

13:22 (some #{50} [1 2 3 4 50])

13:22 ,(some #{50} [1 2 3 4 50])

13:22 clojurebot: 50

13:22 danlarkin: which will evaluate to true

13:24 turbo24prg: why does that work? i thought some takes a predicate, ie. a function?

13:25 ayrnieu: ,(#{50} 50)

13:25 clojurebot: 50

13:25 danlarkin: ,(ifn? #{})

13:25 clojurebot: true

13:28 turbo24prg: thought that works only on maps, cool

13:30 ayrnieu: ,(filter ifn? ["" [] () {} #{} :k 'sym (ref 0) (atom 0) (agent 0) (var +) +])

13:30 clojurebot: ([] {} #{} :k sym #<Ref@16f4ce0: 0> #'clojure.core/+ #<core$_PLUS___3183 clojure.core$_PLUS___3183@1735602>)

13:32 ayrnieu: freaky.

13:32 ,(let [x (ref inc)] (x 1))

13:32 clojurebot: 2

13:33 ayrnieu: ,('hi #{'hi 'there})

13:33 clojurebot: hi

13:45 Lau_of_DK: Good evening gents

13:48 danlarkin: Lau_of_DK: hiya!

13:48 Lau_of_DK: terpsichore?

13:49 durka42: hey lau

13:53 Lau_of_DK: danlarkin: terpischore? Is that some illness you have contracted? :(

13:54 danlarkin: it's the greek muse of song and dance :)

13:54 Lau_of_DK: oh

13:54 Hows Clabango coming along?

13:56 danlarkin: haha well what do you think of terpsichore as a name

13:56 Lau_of_DK: Its pretty bad my friend

13:57 danlarkin: ugh

13:57 Lau_of_DK: :(

13:57 danlarkin: I can't release anything until I come up with a name :)

13:58 Lau_of_DK: Isnt Clabango pretty fun ?

13:59 danlarkin: well it's a step up from barkin' larkin I guess

13:59 Lau_of_DK: Good! Then we're getting somewhere

13:59 But as I understand it, youre delivering the worlds first complete web framework written in a purely functional lisp right? That screams: CLA BANGO!

14:00 durka42: purely?

14:00 ayrnieu: no, not purely.

14:00 Lau_of_DK: ok, impurely

14:00 You kinda missed the point

14:01 Are you specifically going for something greek/outlandish danlarkin?

14:01 * durka42 kind of likes terpsichore more than clabango

14:02 danlarkin: Lau_of_DK: no, not at all, just scrolling through wikipedia trying to think of a name

14:02 Lau_of_DK: k

14:05 Man, I really like Clabango, if you dont use it I will :) It'll be my new brand, ClabangoSQL, ClabangoWeb, ClabangoEuler :)

14:05 danlarkin: hahah

14:05 clabango is *so* bad :)

14:06 Lau_of_DK: Its mine then! Muhahahaahah

14:09 danlarkin: Is the name seriously all thats standing between you and the Github ?

14:09 danlarkin: Lau_of_DK: at this point yup

14:10 Lau_of_DK: Hmm, you reject Barkin' Larkin', you mock Clabango...All thats left is: Funky Web

14:11 danlarkin: haha

14:11 offby1: Poo. It seems that if I want to get anything done in Clojure, I have to learn Java first -- or at least, I have to be familiar with the built-in classes. Can someone recommend a terse cheat-sheet type overview that describes the classes? Specifically I don't know how to append two strings :)

14:12 danlarkin: offby1: (str string1 string2)

14:12 offby1: I have NOT tried Google, since I assume I'll be overwhelmed with 1,000,000 not-quite-relevant hits.

14:12 Chouser: ,(str "one" "two")

14:12 clojurebot: "onetwo"

14:12 offby1: danlarkin: thanks

14:12 Chouser: we are your cheatsheet

14:12 danlarkin: offby1: try reading core.clj or browsing http://clojure.org/api

14:12 offby1: but that's just giving me a fish, so my question still stands: any fairly terse how-to-fish web sites for the Java-ignorant?

14:13 danlarkin: hum, OK.

14:13 from what I've seen in http://clojure.org/api, though, that's all the stuff that _isn't_ already in java.

14:13 zakwilson: There's the Javadoc for the entire Java standard library.

14:13 Wizardofwestmarc: yeah sun's documentation is actually decent

14:13 Lau_of_DK: danlarkin: we have to sort this out now, start here : http://gangstaname.com/mafia_name.php

14:13 Wizardofwestmarc: and it can even be downloaded for local browsing

14:13 danlarkin: offby1: oh yes, that's not really an answer to your question, just an aside

14:13 zakwilson: It's not exactly a cheat sheet, but there's an index, and Sun has some tutorials that help you figure out where to start.

14:14 durka42: terpsichore -> Lightning Fingers Lou

14:14 offby1: danlarkin: and yet it does answer my immediate question, so it's indeed helpful. Thanks

14:14 danlarkin: Dan Larkin -> Paolo the Greaser

14:15 Lau_of_DK: There you go

14:15 durka42: clabango -> donato milano

14:15 offby1: zakwilson: that's probably what I need. I'll confess my fear, though, which is: say I want to read a file. I'll look up the relevant bits in the javadoc ... and I'll find 867 ways to read files, with nothing to help me decide which to choose. I'm probably just a whiner.

14:15 danlarkin: offby1: (slurp "filename") :)

14:16 Lau_of_DK: danlarkin: Youre American right?

14:16 danlarkin: Lau_of_DK: yessir

14:17 Lau_of_DK: great, that makes it easier

14:17 How about "THE LIBERATOR 10.000 ! Get a free car with your first download and porkchops for life!!!"

14:17 danlarkin: haha oh jeez

14:18 ayrnieu: ,(> 10.000 10)

14:18 clojurebot: false

14:18 danlarkin: silly europeans

14:18 Lau_of_DK: You can laugh, but we practically own America now

14:18 offby1: danlarkin: I'm starting to get the sense that there's a lot more in the clojure API itself (as opposed to traditional java classes) than I thought; I'll read that API doc more carefully. Thanks.

14:18 Chouser: ,(> 10,100 10)

14:18 clojurebot: false

14:18 Lau_of_DK: Since your little mishap at the stock exchange :)

14:19 Chouser: ,(> 20,001 10)

14:19 clojurebot: false

14:19 ayrnieu: ,(length '(10,000 10))

14:19 clojurebot: java.lang.Exception: Unable to resolve symbol: length in this context

14:19 durka42: that is (> 20 001 10) isn't it?

14:19 * Chouser forgot to turn his brain on

14:19 durka42: ,(count '(10,000 10))

14:19 clojurebot: 3

14:19 Chouser: ,(> 20,005 1)

14:19 clojurebot: true

14:19 Chouser: ther

14:19 durka42: yeah

14:20 danlarkin: Lau_of_DK: I didn't realize you were chinese :)

14:20 Lau_of_DK: danlarkin: Oh.. that must be because.. im not :)

14:20 danlarkin: well you said you practically own america, that would make you chinese

14:21 Lau_of_DK: EBC gave 800 bill. EUR in loan to the US recently, I think the official letter said "pwned" at the top

14:21 s/EBC/ECB

14:22 zakwilson: And the US govenment is now going to spend it on wasteful projects.

14:22 Lau_of_DK: Of course :)

14:22 zakwilson: But none of that has much to do with Clojure or programming in general.

14:22 Unless they want to pay us to program something cool and utterly useless in Clojure. I'd support that.

14:23 danlarkin: +1 for government funded clojure hacking

14:23 Lau_of_DK: Im just trying to understand the culture zakwilson

14:23 Wizardofwestmarc: just tell them it's java <_<

14:23 danlarkin: is calliope any better than terpsichore?

14:24 Lau_of_DK: What does it mean ?

14:24 danlarkin: another muse

14:24 zakwilson: What culture?

14:24 danlarkin: greek

14:24 Lau_of_DK: The American

14:24 danlarkin: oh, haha sorry

14:25 Lau_of_DK: danlarkin: How about 'calligraphy' ? I means beautiful hand-writing

14:25 zakwilson: Yes, Lau_of_DK, as I was saying... what culture? (I actually mean that in a less insulting way than it may suggest - the thing is there's no single clearly-defined American culture)

14:26 offby1: In the one Java program I've ever written, I used a class called "java.io.FileReader". I thought I could access that in clojure by evaluating (java/io/BufferedReader "some-file-name"), but alas, I get an error: java.lang.Exception: No such namespace: java/io

14:26 What am I misunderstanding?

14:26 Lau_of_DK: zakwilson:

14:26 Youre not american ?

14:26 danlarkin: zakwilson: oh there is too an American culture

14:27 durka42: offby1: use dots

14:27 Lau_of_DK: The European view of Americans is generally that they're greedy, overweight lazy criminals, who crave big cars and mantions. Chouser being the only exception I know personally :)

14:27 offby1: durka42: huh, OK, I'll try that ...

14:27 durka42: and constructors in clojure end with a dot

14:27 Lau_of_DK: s/mantions/mansions

14:27 durka42: ,(java.io.BufferedReader. "file/name")

14:27 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to java.io.Reader

14:27 zakwilson: I am American. There are so many different subcultures that there are few, if any elements that can reasonably be said to be part of American culture as a whole.

14:27 durka42: java needs more red tape to make a BufferedReader but that's the syntax

14:28 Ariens: why does every? return nil when false instead of false?

14:28 offby1: durka42: but I get the same error that you just got

14:28 durka42: well i guess bufferedreader's constructor needs a reader

14:28 Ariens: ,(every #{\space} "dam")

14:28 clojurebot: java.lang.Exception: Unable to resolve symbol: every in this context

14:28 durka42: ,(-> "path/to/file" java.io.FileReader. java.io.BufferedReader.)

14:28 zakwilson: The overweight and big cars part is true. And we're a bit off-topic. I'd be happy to continue this discussion in private should anyone wish to.

14:28 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission path/to/file read)

14:28 durka42: also look at slurp

14:28 or its source

14:28 offby1: thanks

14:28 Ariens: ,(every? #{\space} "dam")

14:28 clojurebot: nil

14:29 Ariens: is there a criteria

14:29 when to return nil and when to return false?

14:32 durka42: ,(and nil false)

14:32 clojurebot: nil

14:32 durka42: ,(and false nil)

14:32 clojurebot: false

14:32 durka42: ,(and nil nil)

14:32 clojurebot: nil

14:32 durka42: ,(and false false)

14:32 clojurebot: false

14:32 durka42: every? uses and internally

14:32 ,(#{\space} "d")

14:32 clojurebot: nil

14:33 durka42: (doc and)

14:33 clojurebot: Evaluates exprs one at a time, from left to right. If a form returns logical false (nil or false), and returns that value and doesn't evaluate any of the other expressions, otherwise it returns the value of the last expr. (and) returns true.; arglists ([] [x] [x & rest])

14:33 durka42: (doc every?)

14:33 clojurebot: Returns true if (pred x) is logical true for every x in coll, else false.; arglists ([pred coll])

14:33 durka42: this could be a bug in every?

14:33 ayrnieu: or in its documentation.

14:34 Ariens: in the API it says it returns false

14:35 Wizardofwestmarc: well, nil and false are interchangeable for boolean purposes, isn't the only time it matters for testing false?

14:35 (false? nil)

14:35 ,(false? nil)

14:35 clojurebot: false

14:36 Ariens: erm if the are interchageable why does (false? evaluate nil to false?

14:37 durka42: (doc false?)

14:37 clojurebot: Returns true if x is the value false, false otherwise.; arglists ([x])

14:37 durka42: (doc nil?)

14:37 clojurebot: Returns true if x is nil, false otherwise.; arglists ([x])

14:38 durka42: ,(= (nil? false) (false? nil))

14:38 clojurebot: true

14:38 Ariens: ok so every? has a bug?

14:39 ayrnieu: or its documentation does.

14:39 durka42: well, the doc should say it returns nil or false, yes?

14:39 ayrnieu: or it should return false.

14:39 durka42: instead of just saying "false otherwise"

14:39 yeah

14:39 Ariens: doc says it returns true or false

14:39 durka42: when does it matter

14:39 ayrnieu: yes, Ariens, we know.

14:39 durka42: ,(boolean nil)

14:39 clojurebot: false

14:40 ayrnieu: every?'s functionality differs from its documentation. This is not enough to say that it or its documentation is in error, it is only enough to say that one of them is.

14:40 durka42: yup

14:40 BigTom: offby1: use duckstreams in clojure-contrib

14:40 Ariens: ayrnieu: since it doesn't make much sence to me everty to return nil I think the error is in the implementation

15:11 Lau_of_DK: clojurebot: compojure?

15:11 clojurebot: compojure is a concise web framework inspired by Sinatra

15:11 Lau_of_DK: LINK!?

15:12 clojurebot: compojure is also http://github.com/weavejester/compojure/tree/master

15:12 clojurebot: Roger.

15:12 Lau_of_DK: clojurebot: compojure?

15:12 clojurebot: compojure is http://github.com/weavejester/compojure/tree/master

15:12 Lau_of_DK: I said also...

15:12 hiredman: Your sevant is disobediant

15:13 danlarkin: it's a random choice I believe

15:13 clojurebot: compojure

15:13 clojurebot: compojure is a concise web framework inspired by Sinatra

15:13 Lau_of_DK: oh

15:14 offby1``: If it's random, teach it Russian Roulette!

15:18 Chouser: ~roulette

15:18 clojurebot: roulette is click

15:19 Chouser: ~roulette

15:19 clojurebot: click

15:19 Chouser: ~roulette

15:19 clojurebot: click

15:21 SuttoL: clojurebot: ~roulette

15:21 clojurebot: bang

15:26 turbo24prg: which objects can hold meta informations? too bad strings itself can't

15:27 Chouser: anything than implements IMeta

15:28 turbo24prg: say, i just want to store meta information for strings, what would be the best choice?

15:28 list, set, ..?

15:29 kotarak: http://clojure.org/metadata

15:30 ayrnieu: ,(filter #(try (do (with-meta % {:meta true}) true) (catch ClassCastException _ false)) [{} #{} [] () "" 1 1/0 'etc])

15:30 clojurebot: It's greek to me.

15:30 Chouser: a one-element list seems about right

15:30 ayrnieu: say what?

15:31 ,(filter #(try (do (with-meta % {:meta true}) true) (catch ClassCastException _ false)) [{} #{} [] () "" 1 1/2 'etc])

15:31 clojurebot: Excuse me?

15:31 durka42: no try

15:32 ayrnieu: ,(filter #(try (do (with-meta % {:meta true}) true) (catch Exception _ false)) [{} #{} [] () "" 1 1/2 'etc])

15:32 clojurebot: excusez-moi

15:32 durka42: i mean to say, clojurebot does not allow try/catch

15:32 Chouser: ,^(with-meta '("hello") {:some :meta-data})

15:32 clojurebot: {:some :meta-data}

15:32 ayrnieu: he should probably say something like "Oh, many apologies, I do not allow try/catch."

15:33 ,(with-meta () {:oops 1})

15:33 clojurebot: ()

15:34 ayrnieu: hm, I get a NullPointerException.

15:34 ah, it's a feature of the lazy branch.

15:52 mofmog: Is programming clojure at a point where it'd be worth it to purchase it?

15:52 technomancy: mofmog: yes

15:52 has been for some time

15:54 * technomancy is thinking about changing server-socket to use duck-streams instead of importing a bunch of Java classes. is that a good idea?

15:54 Chousuke: mofmog: well, you get free upgrades

15:54 mofmog: it's mostly because there aren't that many comprehensive Clojure tutorials

15:54 Wizardofwestmarc: Considering you got all the later versions for free, it's always been worth it.

15:55 mofmog: as far as i can tell, it's either just reading through lots of code or watching the blip.tv videos

15:55 Wizardofwestmarc: or just asking questions here and in the google group. yeah

15:55 technomancy: mofmog: the blip.tv is not very up-to-date IIRC.

15:55 it's good to understand motivation, but not good for specifics

15:57 Wizardofwestmarc: last blip video was his talk to the boston lisp group, so yeah, bit out of date

15:58 mofmog: how in depth is PC's STM section?

16:00 Wizardofwestmarc: the concurrency tools (agents, refs, etc) is an entire chapter

16:01 mofmog: ah cool

16:01 Wizardofwestmarc: ~20 pages long as of beta 5

16:01 clojurebot: I don't understand.

16:01 technomancy: so I want to curry a function, but I want to provide the second arg. If I use partial, it only works if I provide the first arg.

16:01 mofmog: so if i had tomcat installed on an apache server, it should be a fairly easy task of deploying clojure stuff?

16:01 technomancy: is there another function I can use?

16:01 mofmog: swap?

16:02 i dont know if clojure has a swap function but hey

16:02 technomancy: doesn't look like it

16:02 mofmog: so you just want to partially evaluate it? or curry curry it

16:02 danlarkin: technomancy: use #()

16:03 Lau_of_DK: Which webframeworks are actively being developer upon in Clojure atm ? We know danlarkin is almost RC ready with Clabango - Any others?

16:03 Wizardofwestmarc: mofmog: I'd think so but never used tomcat. I know one of the web frameworks already being written in clojure is using Jetty

16:03 technomancy: danlarkin: ok, so there's not a "more functional" approach?

16:03 mofmog: ah, i'm also trying to get jetty installed

16:03 technomancy: whatever that means

16:03 mofmog: from what I've heard, it's easiest to deploy on jetty

16:03 danlarkin: technomancy: well not that I can think of :)

16:03 mofmog: i plan on deploying on a university webserver and i might have to fight with the admins to get them to put jetty on

16:03 technomancy: Lau_of_DK: compojure is active... perhaps webjure, but that may be stalled

16:03 mofmog: you can bundle jetty w/ your app

16:05 mofmog: oh right

16:05 im not to experienced with java for web developing tbqh

16:05 technomancy: danlarkin: I'm looking at the definition of create-repl-server in server_socket.clj from contrib

16:05 danlarkin: if create-server accepted a function first, *then* a port, it's be easier to curry

16:06 but changing that seems like a bad idea

16:06 interesting how currying makes argument order matter a lot more

16:06 mofmog: technomancy: are you currying or partial evaluating?

16:07 curryin takes a function that accepts tuples and returns a function that sorta like a bunch of nested lambdas

16:07 technomancy: mofmog: hrm; maybe my terms are messed up.

16:07 mofmog: partial evaulating is one you "specialize" a function so to say

16:08 *when

16:08 same sorta general idea nonetheless

16:08 technomancy: mofmog: yeah, searching wikipedia for "partial application" redirects to the Currying page. =)

16:09 mofmog: oh yeah, mix it up in #haskell and they'll hunt you down and your family and your pets

16:09 technomancy: hah

16:10 but partial evaluation is what I'm looking at. there's a function that calls create-socket by passing in all the arguments it recieved except one

16:11 since there are three different arg lists to support (the same as create-socket) it'd be nice to be able to turn a seven-line function into one line. but the fixed arg is not the first one, so I don't know if you can do it.

16:12 Lau_of_DK: technomancy: compojure looks a little stalled as well

16:12 skogs: hi all: do all collection implement ISeq interface?

16:12 lpetit: hi

16:12 technomancy: Lau_of_DK: the mailing list is extremely active

16:12 I could use apply, but it's not quite as nice

16:12 Lau_of_DK: k

16:13 lpetit: Could someone explain me if there is a possibility to browser this channel's history (sorry, I'm a real IRC noob)

16:13 mofmog: hmm

16:13 say you have a function foo that takes in arguments x y z and you want to specialize it such that y is always 2

16:13 lisppaste8: technomancy pasted "two create-repl-socket implementations" at http://paste.lisp.org/display/75026

16:14 technomancy: are these two implementations equivalent?

16:14 mofmog: (define (special-foo y) (lambda (x z) (foox x y z)))

16:14 ayrnieu: clojurebot: google clojure irc log

16:14 clojurebot: First, out of 3580 results is:

16:14 #clojure - May 16 2008

16:14 http://clojure-log.n01se.net/date/2008-05-16.html

16:14 mofmog: that's scheme way at least

16:14 the you say, (define foo2 (special-foo 2))

16:15 technomancy: mofmog: what do you think of the version I pasted?

16:15 lpetit: thx, I certainly didn't search with the right keywords (I didn't think to use the "log" keyword)

16:16 mofmog: tbqh i dont really know what's going on

16:16 technomancy: The only disadvantage is that the older version is explicit about its argument list, whereas with the short one you have to refer to create-server's arg list to know what's going on

16:16 mofmog: so the conj operator does what?

16:16 is it like cons?

16:16 technomancy: mofmog: yeah, but it works for all sequences

16:17 not just lists

16:17 mofmog: oh i see

16:17 like a general preappend

16:17 or append i guess

16:17 ayrnieu: also, it has a more convenient argument order for some uses.

16:17 Chouser: no, conj adds to each collection in its own way

16:17 mofmog: ah

16:17 so the difference between defn and def?

16:17 Chouser: conj on a list is exactly like cons, but conj on a map takes a [key val] vector and adds that entry

16:18 mofmog: i've mostly just done scheme

16:18 technomancy: anyway, I think the explicitness of the argument list is enough to justify the verbosity of the original in this case

16:18 mofmog: defn is def + implicit fn

16:18 mofmog: ah i see

16:18 skogs: Hi all

16:18 Chouser: (defn foo [x] body) is essentially (def foo (fn [x] body))

16:18 mofmog: oh so it's like () around the name of something you're defining in scheme

16:18 Chouser: ...plus extra optional args for docstring, etc.

16:19 mofmog: [port & args]?

16:19 is that like .

16:19 (define (dosomethin f . y) (map f y))

16:20 technomancy: mofmog: yeah, it's "rest arguments"

16:20 Chouser: ,(let [[x y & m] (range 9)] {:x x :y y :m m})

16:20 clojurebot: {:x 0, :y 1, :m (2 3 4 5 6 7 8)}

16:20 technomancy: I never got that far in my scheme impl, but I think it's the same idea.

16:20 ayrnieu: ,((fn ([one] one) ([frst & rst] {:first frst :rest rst})) 1)

16:20 clojurebot: 1

16:20 ayrnieu: ,((fn ([one] one) ([frst & rst] {:first frst :rest rst})) 1 2 3)

16:20 clojurebot: {:first 1, :rest (2 3)}

16:20 technomancy: Chouser: do you think it's a good idea for the server-sockets library to be defined in terms of duck-streams instead of calling Java classes directly?

16:21 ayrnieu: technomancy - it provides the false convenience that a lot of people like -- for a while.

16:21 mofmog: oh i see why they chose to use defn, it lets you do the pattern matching deal

16:21 technomancy: or rather that the socket-repl sample function use it

16:21 ayrnieu: that isn't pattern matching, mofmog; it only dispatches on the number of arguments

16:22 for other dispatch, use defmulti/defmethod

16:22 Chouser: ayrnieu: why is it false?

16:22 Lau_of_DK: Any good websites regarding compojure?

16:22 technomancy: Lau_of_DK: docs are sketchy; need to ask on the mailing list for most things

16:23 Chouser: plain fn's can have arity overloading too. (fn ([] 1) ([x] x) ([x y] (+ x y)))

16:23 technomancy: ayrnieu: if you're just looking to understand how the library works, the sample provided shouldn't bring in unnecessary baggage.

16:23 skogs: guys, i need some feedback on a switch statement macro

16:23 technomancy: you can fall back to that if you want to, but if you end up needing it odds are you won't need to base your code off the sample

16:25 ayrnieu: skogs - ... OK?

16:25 Chouser: I haven't even figured out how to use all of condp's features yet.

16:26 skogs: can i paste code somewhere?

16:26 Chouser: lisppaste8: url

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

16:29 skogs pasted "given" at http://paste.lisp.org/display/75027

16:31 skogs: Chouser: did u see the paste

16:31 Chouser: skogs: yep

16:31 skogs: thats an example of the statement

16:31 Chouser: can't use it to see if x is a particular function or regex

16:32 ayrnieu: skogs - please ask a question.

16:32 hiredman: skogs: do you know about condp?

16:32 skogs: no

16:33 hiredman: (doc condp)

16:33 clojurebot: Takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either: test-expr result-expr test-expr :>> result-fn Note :>> is an ordinary keyword. For each clause, (pred test-expr expr) is evaluated. If it returns logical true, the clause is a match. If a binary clause matches, the result-expr is returned, if a ternary clause matches, its result-fn, which must be a unary function, is ca

16:33 skogs: ok

16:33 given is more generic switch than just predicate

16:34 Chouser: skogs: you've started trying to write the macro?

16:34 hiredman: ,(let [a 1] (condp = a 1 "Hey" 2 "Yo"))

16:34 clojurebot: "Hey"

16:34 skogs: i wrote it

16:34 hiredman: ,(let [a 2] (condp = a 1 "Hey" 2 "Yo"))

16:34 clojurebot: "Yo"

16:34 skogs: let me paste it

16:34 ayrnieu: skogs - OK. What is your question about it?

16:37 lisppaste8: skogs pasted "untitled" at http://paste.lisp.org/display/75028

16:38 skogs: (given x

16:38 5 "a number"

16:38 #"c.*e" "matches regex"

16:38 even? "an even number"

16:38 :hashkey "key in map x exists"

16:38 )

16:39 in given, the case statements can be very generic

16:40 ayrnieu: Chouser, -> is very convenient, and very limited, and the effect is that you can start out with an -> expression and then say, oh, wait, I can't do what I want to do with this. And then you have to rewrite the expression, turning it inside-out (outside-in), adding a lot of parentheses, etc.

16:41 Chouser: ayrnieu: yes

16:41 ayrnieu: Chouser - but I wouldn't call it 'false' because of the straightforwardness of this whole process. Even if you make a small change and then have to throw -> out, you still aren't doing a lot of work.

16:41 Chouser: oh!

16:41 oh.

16:42 * Chouser waits patiently for the conclusion.

16:42 ayrnieu: Chouser - but with socket-server you say, "aha, I can use this" -- and you're driven down completely the wrong path.

16:42 Chouser: ayrnieu: because of socket-server, or because of duck-streams?

16:42 hiredman: ,(-> "huh" (#(println % "?")))

16:42 clojurebot: huh ?

16:47 ayrnieu: Chouser - *shrug*, I started doing something else as soon as I saw that the callback only received the duck-streams, because "let's pretend that sockets are files!" is a trap I'm familiar with, but server-socket's one-client-per-thread is also problematic.

16:48 technomancy: ayrnieu: well both those assumptions fit great with the vast majority of the simple cases.

16:49 if you've got a more complicated need you probably shouldn't be using server-socket to begin with

16:49 it's not a lot of code

16:49 Chouser: I've only had positive experiences with duck-streams. I haven't look at server-socket at all yet.

16:50 ayrnieu: skogs, you never asked a question about this 'given' thing.

16:51 skogs: i guess i am not fully ready yet

16:51 since i have no doc, its hard to explain what it does

16:51 Chouser: we might be able to figure out what it does enough to answer your question, if you ask one.

16:51 skogs: so started creating a github project to put the code and examples

16:52 ayrnieu: oh, do you just want comments on it?

16:52 skogs: yes

16:52 http://paste.lisp.org/display/75028

16:53 Chouser: skogs: have you had use cases where you actually mix different types of values as conditions in the same 'given' form?

16:53 skogs: yes

16:54 could match a specific value or a regex

16:54 Chouser: hm, sure, that's plausible.

16:54 skogs: (given "dude" "sam" "its sam" #"rx" "its all these ppl")

16:54 ayrnieu: skogs, you can use a# b# etc in place of prepared gensyms. So (let [x (gensym)] `(let [~x ...] ...)) can just be `(let [x# ...] ...)

16:55 ,[a# b# a#]

16:55 clojurebot: java.lang.Exception: Unable to resolve symbol: a# in this context

16:55 ayrnieu: ,`[a# b# a#]

16:55 clojurebot: [a__1414__auto__ b__1415__auto__ a__1414__auto__]

16:55 offby1: technomancy: I didn't know about re-split, but was considering something like that ... it seems a little wrong, though, since it requires that I snarf the whole file into memory up front.

16:55 Lau_of_DK: technomancy: What am I not getting, I clone compojure, I run ant, I java -jar compojure.jar, and it boorks, they removed the old script/run, so hows it supposed to be launched?

16:55 technomancy: offby1: oh sure, you'd want a lazy version?

16:56 offby1: ideally

16:56 skogs: ayrnieu: i tried but needed to use symbol during macro expansion stage

16:57 technomancy: offby1: I haven't done a much with constructing lazy sequences, but I suspect it would involve binding *in* to (reader "/path/to/file") and using lazy-cons

16:57 or perhaps lazy-seq

16:57 ayrnieu: skogs - ifn? shadows map? in #'type; also, #'type could be replaced by dispatching on (class x) instead

16:58 hiredman: the whol thing could be a special predicate passed to condp

16:58 whole

16:58 skogs: gotcha.. i will fix

16:59 hiredman: i just learned condp, will change

16:59 Chouser: offby1: re-split is lazy. you might try using mmap/slurp, which would allow the OS to load the file from disk as re-split demands it

16:59 lisppaste8: technomancy pasted "booting a compojure app for Lau" at http://paste.lisp.org/display/75030

16:59 technomancy: Lau_of_DK: that's what I use

17:01 Chouser: slick.

17:01 Chouser: re-split is not lazy

17:01 skogs: how do i know if a value is a sequence without causing a runtime error

17:01 hiredman: seq?

17:01 (doc seq?)

17:01 clojurebot: Return true if x implements ISeq; arglists ([x])

17:02 Chouser: sorry, I had that wrong. re-partition *is* lazy and should work well with mmap/slurp

17:02 skogs: but (seq? [3 4]) fails

17:02 hiredman: [] is a vector

17:02 ,(vector? [])

17:02 clojurebot: true

17:02 technomancy: but /me suspects offby1 is prematurely optimizing

17:02 offby1: probably.

17:02 hiredman: ,(seq? (seq []))

17:02 clojurebot: false

17:03 offby1: given that the slurpy way is simpler than the lazy way

17:03 hiredman: grr

17:03 ,(seq? (seq [1]))

17:03 clojurebot: true

17:03 technomancy: offby1: plus slurp is fun to say

17:03 skogs: oh

17:03 hiredman: ,(seq [])

17:03 clojurebot: nil

17:03 skogs: ,(seq? 3)

17:03 clojurebot: false

17:03 Lau_of_DK: Seriosly, isnt there anything better than compojure out there? (ie., something that actually runs) Or am I just too dumb to use it?

17:04 technomancy: functions that are onomatopoeic are the best

17:04 hiredman: Lau_of_DK: ring is nice

17:04 technomancy: Lau_of_DK: you can check out my lil app if you want more sample code

17:05 Chouser: skogs: I think you can replace your macro with (defmacro given [& r] `(condp match ~@r nil))

17:05 technomancy: ring looks nice but really low-level

17:05 hiredman: erm

17:05 Lau_of_DK: technomancy: link?

17:05 hiredman: if anything I would say it is higher level

17:05 technomancy: hiredman: well it doesn't contain any functions for HTML generation or session abstractions, right?

17:06 hiredman: last time I used compojure you had to def a servlet then create a list of url mapings

17:06 ring you just hand it a function

17:06 skogs: Chouser: wow! I will try that

17:06 hiredman: technomancy: I believe that is correct

17:07 but that is confusing featureful and abstraction level

17:07 technomancy: hiredman: compojure handles routing for you, ring hands off the path and lets you write your own routing mechanism

17:08 Lau_of_DK: I don't have it on github, but I can upload a tarball

17:08 hiredman: technomancy: have you used ring?

17:08 Lau_of_DK: Thanks, appreciate it

17:09 technomancy: hiredman: I've used rack extensively, which ring is a port of.

17:09 danlarkin: my <yet to be named web project> is based on ring

17:09 technomancy: maybe ring has been extended to be more than a port since I looked at it?

17:10 hiredman: I dunno

17:10 I know nothing about rack

17:10 Chouser: skogs: you also might be interested in this thread: http://groups.google.com/group/clojure/browse_thread/thread/e750b045d8701f7/b93846216491e4e5

17:12 technomancy: Lau_of_DK: there's some bitrot here; hold on

17:12 anyway, what I mean about ring is that ring is designed to build frameworks or APIs on, whereas compojure is designed to build applications on.

17:13 Lau_of_DK: Ring looks good

17:13 I especally like that its not broken out of the box

17:14 hiredman: they could add that to the feature list

17:14 skogs: chouser: there's already lot of thought here

17:15 i was just translating perl6's smart match and given control statement

17:16 the tough part is the conditional part dispatch and what the sensible defaults

17:17 Chouser: right, I think condp is already doing what you want for the macro, it's just a matter of the matching function

17:17 skogs: yeah, the matching is where the smarts go i mean

17:18 and to be universably useful, it should be DWIMish as Perl6 ppl say

17:18 technomancy: Lau_of_DK: http://p.hagelb.org/concourse.tar.gz <= ~5MB because it bundles all the jars

17:18 Lau_of_DK: Thanks big guy

17:19 danlarkin: Oooooo concourse

17:20 Lau_of_DK: danlarkin: You seem to energetic, did you just drink a bottle of hansard?

17:20 danlarkin: Lau_of_DK: hahaah

17:20 it's a good name, alright?!

17:21 Lau_of_DK: Yea, I like my Budweiser and my Hansard, they go well together

17:21 But when you mix german sausages and Hansard.. then youre in for some stomach trouble

17:22 danlarkin: pahhh

17:22 I did just figure out how to implement conditionals in my templating language

17:22 maybe that has made me cheery

17:23 Lau_of_DK: :)

17:23 Thats nice

17:24 Ring doesnt seem too big in the template department

17:25 danlarkin: ring is just a layer between your app and the http spec

17:26 * clojurebot blinks

17:26 danlarkin: *gasp*!

17:26 it's sentient!

17:27 Lau_of_DK: (doc sentient)

17:27 I really miss RSchulz, everytime he wrote something in the chan, I had to reach for my dictionary

17:27 That was nice

17:27 durka42: (defn sentient [] (/ 1 0)) ; singularity

17:30 hiredman: (doc test)

17:30 clojurebot: test [v] finds fn at key :test in var metadata and calls it, presuming failure will throw exception; arglists ([v])

17:34 danlarkin: yeah he was a character

17:40 ayrnieu: always with the NullPointerExceptions.

18:16 technomancy: sets aren't ordered, are they?

18:17 Wizardofwestmarc: maybe I'm insane but aren't there hashed AND ordered sets?

18:17 just like there's hash-map and sorted-map

18:18 technomancy: that sounds right

18:18 but the one you get from #{"a" "b" "c"} is hashed?

18:19 Wizardofwestmarc: yeah

18:20 ,(sorted-set :a :b :c)

18:20 clojurebot: #{:a :b :c}

18:21 technomancy: ,(= (sorted-set :a :b :c) #{:a :b :c})

18:21 clojurebot: true

18:21 technomancy: ,(= (hash-set :a :b :c) #{:a :b :c})

18:21 clojurebot: true

18:21 technomancy: interesting

18:22 Wizardofwestmarc: yeah, #{} is just the reader macro for hash-set

18:23 forest: there are both PersistentHashSet and PersistentTreeSet in clojure sources, that is sorted and unsorted

18:23 Wizardofwestmarc: huh, I hadn't noticed treeset

19:24 te: 'lo all

19:32 durka42: hi te

19:33 ayrnieu: since I criticized server-socket earlier: http://github.com/ayrnieu/clj-actors/tree/master

19:38 bakkdoor: hi

19:39 te: I'm trying to figure out Clojure. This is my first introduction to lisp, java, etc.

19:39 This is a totally different way of programming.

19:40 durka42: having fun so far?

19:41 forest: clojure sources are so poorely documented

19:42 ayrnieu: they aren't a work of Literate Java. What question do you have?

19:43 te: durka42: Yes I suppose

19:43 durka42: I must say I'm getting a little anxious

19:43 * durka42 hopes Literate Java isn't a real thing, that would be just way too much typing

19:44 durka42: te, about what

19:45 te: I want to start /doing stuff/, but understanding the fundmanetal structure of how things fit together seems to be a large undertaking

19:45 I'd like to write a script to open a file, take the user input and add it to the file on a new line, and then close the file

19:45 cemerick: te: IMO, clojure is *very* well documented, though the delivery format and arrangement is very different from classic java project styles. I'll definitely grant that the style difference takes a little getting used ot

19:45 te: cemerick: forest was critiquing the docs, not me

19:46 cemerick: however, that is helpful advice, thanks

19:46 cemerick: te: oooh, sorry, my bad :-)

19:46 durka42: cemerick: mark volkmann would beg to differ

19:46 forest: just noticed, probably we are not supposed to look into sources

19:46 ayrnieu: te - so, what problems do you have with that?

19:47 te: ayrnieu: truthfully i just dont know where to start -- im not very comfortable i guess

19:47 ayrnieu: forest - I often dig through them.

19:47 cemerick: durka42: mark being who? I'm bad with names of people I don't talk with regularly :-|

19:48 ayrnieu: forest, don't confuse newbie source where every line is (add 1 2) ;; ADD TWO NUMBERS, RETURNING THE SUM with normal source that assumes a measure of language and system familiarity by the reader

19:48 te: ayrnieu: do you think you could show me some code and then i could ask questions about it?

19:48 durka42: te: might want to look at clojure.contrib.duck-streams, with-open

19:48 te: ayrnieu: or maybe you could walk me through it?

19:48 durka42: i can look into that

19:48 durka42: cemerick: there was a big thread on the mailing list about clojure being poorly documented in general

19:49 ayrnieu: te - well, can you do the 'write a script' part? Can you write a script that accepts a single argument and complains if it gets zero ore more than one arguments?

19:50 * SimonAdameit is somewhat lost in setting up a clojure dev environment

19:50 te: ayrnieu: probably, but id need to look around a bit

19:50 durka42: SimonAdameit: have you downloaded clojure and contrib?

19:50 ayrnieu: Simon - I just use emacs and vim, a clj script, some ~/.zshrc stuff to populate CLASSPATH

19:50 forest: ayrnieu: i mean the java sources, not clojure ones

19:50 durka42: are you trying to use emacs, vim, or neither?

19:51 SimonAdameit: exactly this CLASSPATH stuff is killing me..

19:51 durka42: whAT

19:51 te: ayrnieu: (defn myfunc [myval])

19:51 durka42: oops

19:51 cemerick: durka42: ah, that one, right. Eh, I just let stuff like that float by. I try not to convince people of things that they seem to have already made up their minds about.

19:51 durka42: what's your command to run java

19:51 stimuli: hi

19:52 * durka42 responds to external stimuli

19:52 SimonAdameit: I tried to use netbeans + enclojure and the REPL wont work, because of some classpath or whatever issue. Now I am trying emacs and slime, and I dont have swank in my classpath it says

19:52 ayrnieu: te - sorry, what about that myfunc ?

19:52 SimonAdameit: clojure works fine, just invoking java -jar clojure.jar

19:52 te: ayrnieu: that takes an input value, thats the script part

19:52 ayrnieu: no?

19:52 durka42: i installed enclojure and netbeans decided not to start anymore... haven't tried to fix it yet

19:53 stimuli: has anyone here seen pmap go wonky ?

19:53 durka42: wonky?

19:53 ayrnieu: te - well, I was thinking of something with #! /usr/bin/env clj , *command-line-args* , etc.

19:53 stimuli: I have a prog w/ a bunch of pmaps and when I use maps is works, but blows up if I use pmap

19:53 I'm not doing any other concurrent stuff

19:54 te: ayrnieu: ah okay -- well i dont have the binary i dont thinkg

19:55 ayrnieu: te - the binary?

19:55 te: i dont have a clj

19:55 in my PATH

19:55 i have a clojure.jar becase i compiled from source

19:56 ayrnieu: te - get it from here: http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started

19:56 I especially recommend the rlwrap setup

19:57 stimuli: so anyway, I figure that other than the multiple cpu thing .. pmap should ahve the same semantics as map

19:57 so I suppose there is a bug somewhere

19:58 ayrnieu: stimuli - I suppose so. You could copy src/clj/clojure/core.clj:pmap into your program and add debugging hooks into it -- to track agents, for instance, and see if they get errors.

19:58 stimuli: hmmm

19:59 sounds like a plan

19:59 the only "debugging hooks" i've figured out so far are print statements, though :)

20:00 ayrnieu: (def pmap-agents (ref nil)) (defn rem [x] (dosync (commute pmap-agents conj x)))

20:00 Raynes: http://www.debloggers.de/wp-content/uploads/bilder/getstringfromobject.jpg

20:00 ayrnieu: well, rem is already a function.

20:01 durka42: print statements are good :)

20:01 you can replace any x with (doto x prn)

20:01 ,(+ 3 (doto 4 prn))

20:01 clojurebot: 7

20:01 4

20:01 ayrnieu: ooh, nice.

20:01 stimuli: ah ... so add all the agents to a ref and watch them ?

20:02 ayrnieu: or you could just (filter agent-errors pmap-agents) afterwards

20:02 stimuli: then use the "get-agent-errors" thingy

20:04 I'll try that and report back

20:04 ayrnieu: (def OMG-count (ref 0)) (defmacro OMG [expr] `(doto ~expr (println (dosync (alter OMG-count inc)))))

20:04 (def OMG-count (ref 0)) (defmacro OMG [expr] `(doto ~expr (println ~(dosync (alter OMG-count inc))))) ;; rather

20:05 durka42: you want the dosync evaluated at compile time?

20:06 ayrnieu: yes. (def agent-hell [] ... (OMG x) ... (OMG y)) => (def agent-hell [] ... (doto x (println 1)) ... (doto y (println 2)))

20:06 durka42: ah good

20:06 ayrnieu: I feel that the name is the best part of this.

20:06 durka42: :p

20:17 offby1: So I'm in the REPL, and I'd like to use "re-split". Just typing "re-split RET" yields, not surprisingly, "java.lang.Exception: Unable to resolve symbol: re-split ...". However I can't figure out how to get it "imported". What should I do?

20:17 (import 'clojure.contrib.str-utils) ain't it ... tried various combinations ...

20:18 durka42: use, not import

20:18 or require

20:18 import is for java classes

20:22 * durka42 out

20:22 SimonAdameit: Is anyone using enclojure here?

20:23 How can I get anything into the repl? When I do (def foobar 234) in the file and compile, change REPL namespace to file namespace type foobar into the REPL, I get an error, symbol foobar not found.

20:29 stimuli: so I got this agent error: (def pmap-agents (ref nil)) (defn rem [x] (dosync (commute pmap-agents conj x)))

20:29 oops

20:30 I mean this : java.lang.ClassCastException: clojure.lang.LazyCons cannot be cast to clojure.lang.Agent (NO_SOURCE_FILE:0)

20:30 from inside of pmap

20:31 oh wait ....

20:31 I mean I got this: ava.lang.RuntimeException: java.lang.RuntimeException: java.lang.UnsupportedOperationException: nth not supported on this type: Keyword>)

20:31 I'm learning as I got

20:31 go

20:31 Chouser: ,(nth :foo 5)

20:31 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: Keyword

20:31 stimuli: but everything works fine if I use a normal map

20:31 and I get the correct results

20:49 skogs: how to get the class/interface hierarchy of a clojure type like vector

20:50 (class [3 4]) only tells me class but i'd like to all interfaces it defines as well

20:50 stimuli: I don't think you can nest pmaps safely

20:51 which means I'll have to write my own parallization code

20:51 oh well

20:52 ayrnieu: ,(-> [3 4] class ancestors)

20:52 clojurebot: #{java.util.Collection java.lang.Object clojure.lang.IObj java.lang.Iterable clojure.lang.AFn java.lang.Runnable clojure.lang.Streamable clojure.lang.IFn clojure.lang.IMeta java.util.List java.util.concurrent.Callable clojure.lang.Obj clojure.lang.Sequential clojure.lang.APersistentVector java.io.Serializable java.util.RandomAccess clojure.lang.Associative clojure.lang.IPersistentStack clojure.lang.IPersistentCollection c

20:53 stimuli: does the bot let us run arbitrary code ?

20:53 isn't that sort of ... dangerous

20:54 skogs: ayrnieu: thanks! btw now i also know how to use -> op

20:54 ayrnieu: stimuli - it's the point of having a bot.

20:56 obviously there are measures you should take.

20:56 offby1: stimuli: I know a guy who specialized in crashing bots

20:57 s/specialized/specializes/

20:57 he sho' 'nuff crashed mine a lot

20:57 ayrnieu: are you talking about me?

20:57 offby1: nope

20:57 I'm talking about "eli" in #scheme

20:59 stimuli: I mean .. can I call out to java ?

21:00 ayrnieu: stimuli - yes, although there's a security model in place.

21:00 stimuli: ,(.. Runtime getRuntime availableProcessors)

21:00 clojurebot: 1

21:00 stimuli: wow

21:01 that requires a certain level of trust

21:01 I hope he's running in a chroot or something

21:01 ayrnieu: hiredman isn't completely reckless. I wouldn't worry too much about a bot running under OpenBSD systrace and some quotas.

21:01 stimuli: anywho ... my pmaps call a bunch of functions who themselves call a bunch of pmaps

21:02 so that means I'm sending agent messages inside another agent

21:02 I wonder if that is what is breaking things

21:02 ayrnieu: the messages only get sent after the function on that agent returns.

21:02 so that could very well be the problem.

21:03 stimuli: YES!

21:03 ayrnieu: wait, that's definitely true of dosync. Let me check.

21:03 stimuli: I see it now

21:03 rats !

21:03 and pmap looked so easy

21:03 I thought clojure was supposed to make concurrency utterly easy (j/k) :)

21:04 now I have to think

21:04 ayrnieu: (pragma :sprinkle-on-parallelism) is always tricky :-)

21:04 stimuli: yes

21:04 on the other hand I figured out some really tricky graph algorithm code that seems to be working

21:05 ayrnieu: try using send-off instead.

21:05 stimuli: well, I want to keep things in a thread pool

21:06 ayrnieu: send-off also uses a thread pool, just an expandable one.

21:06 stimuli: I'll figure something out .. but not tonight

21:06 ayrnieu: (better control over thread pools is an agent feature that I'd like, too)

21:06 stimuli: I think I'd still have the same "wait until the outer agent finishes before the inner agent returns" problem

21:07 I mean ... I don't think the semantics changes w/ send-off

21:07 regarding waiting

21:07 ayrnieu: I'm not sure that that's true, sorry.

21:07 stimuli: hmmm

21:07 ayrnieu: but 'send' has a potentially very small thread pool (it's based on the number of processors) that does not expand

21:08 so you could have this problem even if I'm wrong about delayed sends.

21:08 stimuli: from the website: # If during the function execution any other dispatches are made (directly or indirectly), they will be held until after the state of the Agent has been changed.

21:08 I think it is the same for send off

21:09 of course ... it will take me 30 seconds to test .. be right back

21:09 ayrnieu: ah, OK.

21:09 geez, that's #5 on that list. It's too early for me to read this poorly :-/

21:09 stimuli: same behavior

21:10 I can just create a java ModuleExecutor

21:10 and do it myself

21:10 Clojure is still > Java

21:10 I wonder though .. if that risks deadlock

21:11 there is a reason the sends are delayed

21:11 it could deadlock

21:11 hmmm

21:12 I'm going to sleep for a while .. thanks for the help .. you guys saved me hours

21:40 skogs: is there a function that tells me if given item is in the collection?

21:41 ayrnieu: ,(.contains "hello" "e")

21:41 clojurebot: true

21:41 skogs: would this work on all collections?

21:41 Chouser: skogs: it's best to use a map or set if you're going to do this kind of lookup

21:42 ,(let [s '#{a b c d}] (s 'c))

21:42 clojurebot: c

21:42 Chouser: ,(let [s '#{a b c d}] (s 'e))

21:42 clojurebot: nil

21:42 skogs: i'm doing a type based dispatch, hence a really general method

21:43 ayrnieu: use defmulti, then

21:43 Chouser: other kinds of collections would require a linear search through the whole thing -- not recommended.

21:44 ayrnieu: http://paste.lisp.org/display/74647 - defmulti examples.

21:44 skogs: this is in a defmulti dispatch, needed for resolving hierarchies

21:45 chouser: given an item and a possible collection, need to find if item exists in the collection

21:45 Chouser: "possible collection"?

21:46 if the collection is a map, you want to look up by key or by value?

21:46 skogs: isa? IPersistentCollection i mean

21:46 map is a special case, dealt with it in earlier defmethod

21:48 Chouser: ,(some #{'b} '[a b c d])

21:48 clojurebot: b

21:48 Chouser: ,(some #{'e} '[a b c d])

21:48 clojurebot: nil

21:51 skogs: chouser: is ur idiom more generic than using .contains

21:52 ayrnieu: it's different.

21:52 ,(some #{'a 'b} '[a x c d])

21:52 clojurebot: a

21:52 ayrnieu: ,[(.contains "hello" "el") (some #{\e} "hello")]

21:52 clojurebot: [true \e]

21:53 skogs: i just need the truth value

21:54 .contains seems cleaner, but uses java method

21:54 ayrnieu: ugh.

21:54 skogs: how do i know which class/iface implemented .contains

21:57 Chouser: java.util.Collection

21:59 skogs: is there a one-liner for method lookup

22:00 ayrnieu: ,(sort (map #(-> % .getName symbol) (.getMethods (class ""))))

22:00 clojurebot: (charAt codePointAt codePointBefore codePointCount compareTo compareTo compareToIgnoreCase concat contains contentEquals contentEquals copyValueOf copyValueOf endsWith equals equalsIgnoreCase format format getBytes getBytes getBytes getBytes getChars getClass hashCode indexOf indexOf indexOf indexOf intern isEmpty lastIndexOf lastIndexOf lastIndexOf lastIndexOf length matches notify notifyAll offsetByCodePoints regionMatc

22:01 Chouser: I use clojure.contrib.repl-utils/show to do that sort of thing

22:01 ayrnieu: ,(filter #(.contains % "in") (map #(.getName %) (.getMethods (class ""))))

22:01 clojurebot: ("indexOf" "indexOf" "indexOf" "indexOf" "toString" "codePointAt" "codePointBefore" "codePointCount" "offsetByCodePoints" "substring" "substring" "contains" "intern")

22:01 ayrnieu: I still haven't explored clojure.contrib

22:02 skogs: cool!

22:02 ayrnieu: this is an example in Programming Clojure

22:02 Chouser: it's probably a bit intimidating at this point. could use a nice summary of the libs I suppose

22:05 Raynes: ,(doc get)

22:05 clojurebot: "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."

22:05 Raynes: Neat.

22:06 Chouser: Raynes: clojurebot or get?

22:07 Raynes: Chouser: get

22:07 Well, both, but get was the source of the "Neat".

22:08 Chouser: yep. But 'get' is hardly every used.

22:08 ,(:a {:a 1 :b 2})

22:08 clojurebot: 1

22:08 Raynes: I'm easily amused. I love functional programming.

22:08 Chouser: ,(:c {:a 1 :b 2} :not-found)

22:08 clojurebot: :not-found

22:09 Chouser: ,({:a 1 :b 2} :c :not-found)

22:09 clojurebot: :not-found

22:09 Chouser: ,({:a 1 :b 2} :b :not-found)

22:09 clojurebot: 2

22:09 Chouser: no need to use 'get'

22:10 ayrnieu: ,(let [x (ref {1 2})] (dosync (alter x get 1)) @x)

22:10 clojurebot: 2

22:10 skogs: ,(.contains :a {:a 3})

22:10 clojurebot: java.lang.IllegalArgumentException: No matching method found: contains for class clojure.lang.Keyword

22:10 ayrnieu: ,(.contains {:a 3} :a)

22:10 clojurebot: java.lang.IllegalArgumentException: No matching method found: contains for class clojure.lang.PersistentArrayMap

22:10 ayrnieu: that's the right order, even if it doesn't work.

22:11 skogs: ,(some #{:a} {:a 3})

22:11 clojurebot: nil

22:11 ayrnieu: ,({:a 3} :a)

22:11 clojurebot: 3

22:11 ozy`: (fetch-url "http://blog.fogus.me/2009/01/15/on-lisp-clojure-prolog-pt-1/&quot;) ;; hooray for literate programming

22:11 Chouser: skogs: you said maps were handled separatly/

22:12 Raynes: Chouser: Stu used it in his book.

22:12 skogs: i'm wondering if i could cheat ;(

22:12 would keys function work on a java map?

22:13 Chouser: skogs: maps implement java.util.Map not java.util.Collection

22:13 skogs: ic

22:14 ayrnieu: it's possible to be so general that your brains fall out.

22:14 Chouser: so you get .containsKey and .containsValue instead

22:15 skogs: ,(.containsKey {:a 3} :a)

22:15 clojurebot: true

22:16 Chouser: ,(some #{[:b 2]} {:a 1 :b 2 :c 3})

22:16 clojurebot: [:b 2]

22:21 ozy`: ,(atom 1)

22:21 clojurebot: #<Atom@1542cdc: 1>

22:21 ozy`: huh

22:21 ayrnieu: what do you huh about?

22:24 ozy`: ,(atom 'desu)

22:24 clojurebot: #<Atom@4c8422: desu>

22:24 ozy`: nothin'

22:25 ayrnieu: you're not going through The Little Schemer, are you?

22:25 ozy`: nope

22:25 Chouser: http://code.google.com/p/clojure/issues/detail?id=56

22:27 ayrnieu: putting your crazy patches into clojurebot so that they can seep insiduously into the channel, eh?

22:28 Chouser: heh, um, what?

22:28 ayrnieu: ,(-> 1 inc (+ 1 _))

22:28 clojurebot: java.lang.Exception: Unable to resolve symbol: _ in this context

22:28 Chouser: that's already in. I wondered if ozy` was noting the new(ish) printing behavior of atoms

22:28 ozy`: ,'desu

22:28 clojurebot: desu

22:29 ozy`: Chouser: (atom) returns a new, unique symbol, right?

22:29 ayrnieu: no, that's (gensym); atams are simpler refs.

22:29 ozy`: all right

22:29 see

22:29 ayrnieu: also, atoms. I guess I've been getting the new revisions but not actually building them...

22:29 Chouser: no, it returns an atomic reference http://clojure.org/atom

22:29 ozy`: I don't actually know clojure.

22:30 I just hang out here.

22:30 Chouser: http://clojure.org/atoms

22:30 * ozy` looks around shiftily

22:30 Chouser: heh

22:31 skogs: wow, nasty surprise with defmethod ordering

22:31 ozy`: ,(gensym)

22:31 clojurebot: G__1646

22:32 ayrnieu: Chouser - I don't see the new behavior.

22:32 skogs: i guess they r not ordered as they r written in source

22:32 ayrnieu: clojurebot: latest

22:32 clojurebot: latest is 1252

22:32 Chouser: skogs: I don't think the order matters

22:32 ayrnieu: yeah, nothing.

22:32 skogs: unless multiple method match the args

22:33 ayrnieu: skogs - that's an advantage, actually; it lets http://github.com/ayrnieu/clj-actors/blob/edab5efb3626e00901e24ca4b0b538776c341e61/src/act/simple_server.clj work

22:33 Chouser: then it should use the inheritence tree

22:33 ayrnieu: (github, why do you have horrible URLs?)

22:34 that sets up default methods that can be overriden later on.

22:37 lisppaste8: skogs pasted "smart match" at http://paste.lisp.org/display/75037

22:38 skogs: just posted the smart match using defmulti, plz comment

22:40 Chouser: you can use import so you don't need to repeat package names each time you mention a class

22:43 skogs: aha

22:43 user=> (match 3 [3 4])

22:43 java.lang.IllegalArgumentException: Multiple methods match dispatch value: [java.lang.Integer clojure.lang.LazilyPersistentVector] -> [java.lang.Object java.util.Collection] and [java.lang.Object clojure.lang.IFn], and neither is preferred (NO_SOURCE_FILE:0)

22:45 ayrnieu: ,(doc prefer-method)

22:45 clojurebot: "([multifn dispatch-val-x dispatch-val-y]); Causes the multimethod to prefer matches of dispatch-val-x over dispatch-val-y when there is a conflict"

22:45 ayrnieu: ,(doc prefers)

22:45 clojurebot: "([multifn]); Given a multimethod, returns a map of preferred value -> set of other values"

22:46 ayrnieu: but even if biordered arguments is more smart matchy, perl6 ~~y, it's odd in Clojure.

22:47 skogs: i'm planning on using this as a switch macro

22:48 condp with this smart-matcher as predicate => define a new macro called: given

22:48 Chouser: ,(:foo #{:foo}) (#{:foo} :foo)

22:48 clojurebot: :foo

22:49 ayrnieu: Chouser, that doesn't demonstrate biordered arguments.

22:49 Chouser: ok, then I don't know what you mean. :-)

22:50 ayrnieu: (f a b) and (f b a) having the same semantics. iFn? true keys is something different.

22:50 Chouser: oh, I see.

22:50 (+ 1 2) (+ 2 1) ?

22:51 ayrnieu: ,[(- 1 2) (- 2 1)]

22:51 clojurebot: [-1 1]

22:51 Chouser: some clojure functions care about the order of their args, others don't.

22:51 ayrnieu: some don't care, pretty much everything does.

22:51 skogs: (given "chouser" #"c.*r" "yes") is same as (given #"c.*r" "chouser" yes")

22:52 ayrnieu: ah, OK.

22:53 skogs: its basically perl6's switch statement

22:55 (given x nil? "nil" even? "even number" #(= 3 %) "its 3")

22:56 Chouser: ruby has a similarly powerful case statement, using a === operator, but it doesn't let you reverse regex and string

22:56 skogs: oh

22:57 Chouser: just fyi. :-)

22:57 case "foo" when /f/; 1 end ==> 1

22:57 case /f/ when "foo"; 1 end ==> nil

22:58 skogs: given works biorder in DWIMish way ala perl6 or perl5's switch.pm

22:59 Chouser: I can certainly imagine having a string and wanting to test several regexs against it.

23:00 which as far as I can tell couldn't be done with ruby's "case"

23:01 skogs: with clojure, we r the same footing as the lang developer

23:01 i love macros

23:03 Chouser: yeah, me too

23:04 Rich won't let us have reader macros, though.

23:05 skogs: i just started on macros, so readers ma be too much power

23:05 Chouser: :-)

23:07 stimuli: I doubt I'll ever miss reader macros

23:07 and it stops people who try to be *clever*

23:07 dreish: You could always write your own reader.

23:07 stimuli: yeah

23:07 Chouser: you can fork clojure and add whatever you want.

23:08 stimuli: well yeah

23:08 Chouser: ...so unsatisfying.

23:09 ayrnieu: the Tower of Babel solution to design complaints.

23:10 stimuli: well .. you'll never satisfy everyone ... and for folks who can only bitch and bitch about things they don't like "fork and do it yourself" is ultimately the only answer

23:11 they almost never do it, of course

23:11 Chouser: I've not seen a whole lot of that kind of complaining about Clojure, though.

23:11 stimuli: well .... it helps that it is so awesome ! :)

23:11 Chouser: heh. yeah.

23:12 ayrnieu: stimuli, I don't mean that rich has taken the Tower of Babel approach to complaints, but that "fork it and change it incompatibly with everyone else" is the Tower of Babel solution to one's own design complaint.

23:13 Chouser: ayrnieu: that's how I understood your statement.

23:13 stimuli: yeah

23:13 I was speaking in generalities

23:14 I haven't been using Clojure long enough to really have any opinion about how Rich does things

23:14 ayrnieu: oh, OK. Well, it's good that they almost never do this, because they'd be impoverishing themselves.

23:14 Chouser: well, technically I guess I do have my own running fork of clojure.

23:15 git-svn makes this easy to do.

23:15 stimuli: you could call it an "experimental branch"

23:16 Chouser: I've only got patches in there that I reasonably expect Rich to take someday, and none of them create breaking changes.

Logging service provided by n01se.net