#clojure log - Sep 30 2010

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

0:00 lambdalion: Well, more and more I have been thinking about scheme as a sort of assembly language...

0:00 so I suppose you could ask "if you are going to translate to assembler why not just write assembler?"

0:03 And the answer would be "I find it more congenial to write in X, and it can be translated to Y without much loss."

0:06 sproust`: lambdalion: Scheme isn't as basic as you present it IMHO. Look at Racket, lots of nice libraries. Zero startup time either. Just my opinion though.

0:06 lambdalion: Hmm- I think you might have misunderstood me a bit...

0:08 I was just saying that the core of scheme is a set of primitives that work well as a language to translate to...

0:09 but people might still prefer to program in something not scheme...

0:11 anyway, I've been using drscheme to teach people things since long before someone decided that changing the name to racket would help. I like scheme tolerably well.

0:26 amalloy: they renamed drscheme to racket? i remember i dropped my AI class in college because all the parens in scheme scared me

0:26 funny how times change

0:27 KirinDave: Feels so good to be doing clojure full time.

0:29 hiredman: mmmm

1:04 dmead: hi channel. can anyone point me to some tools that let you inspect clojure code?

1:04 i want to look at clojure ASTs

1:04 KirinDave: What do you mean?

1:04 (this (is an (AST)))

1:04 (for real, yo. It's sort of the point of sexprs) :)

1:04 dmead: ;)

1:05 still, clojure has to have some sort of introspection tools?

1:05 besides macros?

1:05 KirinDave: Not sure what you're trying to do.

1:08 amalloy: i think he might be looking for something like "i wonder what clojure does when i (let) something with destructuring?"

1:09 even if you expand all the macros there's a bit of magic going on at the java level that you can't see in clojure code, as far as i know

1:10 andyfingerhut: dmead: Do you want to see the Java byte codes produced? Or something before that point in time?

1:15 dmead: i want to see the syntactic structure used right before bytecode generation

1:15 andyfingerhut, ping, etc

1:15 andyfingerhut: You can use (macroexpand '(defn [...] ...)) to see how macros are expanded, if there are any in a piece of code.

1:16 dmead: eh. not really

1:16 i really want to see how the compiler represents s-expressions

1:16 how it's stored, etc

1:16 andyfingerhut: It represents them with Cons cells for lists and vector for things in []

1:16 I believe.

1:17 dmead: like in haskell, the language is defined in types that reflect the language spec

1:17 ah

1:17 andyfingerhut: Then some compiler code written in Java walks those data structures and emits Java byte code.

1:18 lambdahelpya_: You should just read the java bits of clojure then... but they are pretty arbitrary. They would be different on a different platform.

1:18 KirinDave: Hopefully in the next year we'll see the compiler get written almost fully in clojure.

1:18 lambdahelpya_: If clojure in clojure eventuates...

1:19 andyfingerhut: But even when the compiler is written in Clojure, the source code, before and after macro expansion, will be represented as lists and vectors (and hashes, too, I suppose).

1:20 hiredman: ,(type ())

1:20 clojurebot: clojure.lang.PersistentList$EmptyList

1:20 hiredman: ,(type '(+ 1 2))

1:20 clojurebot: clojure.lang.PersistentList

1:22 andyfingerhut: There are clojure.lang.Cons objects used to represent PersistentList's, which you can see a count of with a tool like jmap that inspects all objects in a JVM's memory

1:31 yayitswei: is there a non-threaded version of clojure.contrib.http.agent?

2:33 LauJensen: Good morning all

3:01 zmila: re

3:20 tobiasraeder: hi :)

3:30 if there any way if i have an object representing the class (for an interface for example) to get the myinterface.class to pass it to a java function?

3:31 raek: ,(class 1) ; like this?

3:31 clojurebot: java.lang.Integer

3:31 raek: ,(class (class 1))

3:31 clojurebot: java.lang.Class

3:32 tobiasraeder: if i call it on the symbol storing the interface i get java.lang.Class

3:32 what i really need is the equivalent of myinterface.class

3:32 raek: can you just use the class name?

3:32 tobiasraeder: but i dont know how for example:

3:33 ,(definterface testinterface (^Void doStuff[]))

3:33 clojurebot: java.lang.RuntimeException: java.lang.IllegalStateException: Var null/null is unbound.

3:33 raek: then testinterface should return the class object, I think

3:33 tobiasraeder: ah alright

3:33 ill try that

3:34 ashleyw: Hi, I'm a newbie to clojure/lisp; could somebody help me with why this isn't working: (let [a (atom 1)] (swap! a 2)) — from what I can understand from the docs, swap! changes the value of the first atom arg to the second arg, but it doesn't seem to work that way?

3:34 LauJensen: ashleyw: (swap! a inc) or (reset! a 2)

3:34 swap takes a fn, reset a value

3:36 raek: if two concurrent threads try to update the atom at the same time, one of them might have to try again, since the value that was passed to the function no longer is the current one

3:36 amalloy: ashleyw: LauJensen's suggestions are great and are often right; i just want to mention you could also use (constantly):

3:36 ,(let [a (atom 1)] (swap! a (constantly 2)))

3:36 clojurebot: 2

3:36 ashleyw: LauJensen: Oh I see, thanks!

3:37 raek: ...if one of them is done first

3:38 thread A reads | thread B reads | both calculate next value | thread A writes | thread B wri... oops! already changed. thread B reads | thread B calculates next value | thread B writes

3:39 reset! is, as the name suggests, mostly used when resetting someting to a known state, no matter what it was before

3:40 LauJensen: amalloy: Thats not idiomatic in my oppinion, if you have a value, use reset

3:40 raek: the point is: don't read a value with @ and then reset! the atom to some new value based on it, because then all the atomic goodies will be gone

3:41 ashleyw: So what's the most conventional way, reset! or constantly?

3:41 amalloy: reset!, but really neither :P

3:41 LauJensen: ashleyw: Lets say your atom is a counter, all you care about is getting the order right, then use swap! a inc

3:42 amalloy: ashleyw: ie, if you absolutely must set it to some value x regardless of what is happening elsewhere in the program, you should use reset!...but in practice that rarely happens; you want to compute a new value based on the old one, which is what swap! does

3:48 ashleyw: Okay thanks. Clojure/lisp is very weird, but I haven't had this much fun learning a new language in a loong time :)

3:49 raek: :-)

3:49 LauJensen: ashleyw: If you're just starting out, you could check out project euler. The first 50 or so can really help show you the ropes of Clojure

3:52 ashleyw: oh I forgot about project euler....I'll have a go now, thanks :)

4:23 tobiasraeder: Does anyone have a decent knowledge about clojure using swank, class loaders used in an imported jar and java.lang.relfect.Proxy?

4:23 clojurebot: add-classpath is Fraught with Peril!

5:57 joubert: Hi, what is the purpose/effect of {:rebind true} metadata on a defn?/

6:03 nm

6:04 jjido: Clojure has no letrec right?

6:05 AWizzArd: jjido: correct

6:08 jjido: AWizzArd: thanks. I used let + assoc

6:09 AWizzArd: jjido: yes, this is good. If you happen to need a letrec you can just macro up your own.

6:21 LauJensen: AWizzArd: I've sent Das Keyboard back to Germany - I simply couldn't get used to it

6:30 AWizzArd: LauJensen: Ah okay. At least you tried it.

6:31 LauJensen: Yea. And it made me appreciate my Edge a lot more than I did before, so not a bad experience

6:54 jjido: do records have a "magical parent record" which accessors are applied to if they don't yield a result? eg. (:foo x) returns (:foo (:magical-field x))

6:54 AWizzArd: Most likely not, but I am not sure that I understand what you need.

6:58 jjido: AWizzArd: my solution at the moment is to (merge) two records but I think that gets me a plain hash map, not a new record. If I had the magical parent record I could use that instead. It is to implement some kind of implementation inheritance.

6:59 hoeck: jjido: if the first arg to merge is a record, then it returns a record too

6:59 jjido: hoeck: really that is perfect then

6:59 :)

7:02 esj: LauJensen: I was tickled to discover you use a funny keyboard. In the manner of your extremist views on best tools, I learnt the Dvorak keyboard about 5 years back, and have been using it since.

7:03 LauJensen: esj: Still happy?

7:09 esj: oh yeah

7:12 tobiasraeder: is there a way to add variables to proxied interface implementations?

8:22 Is it possible to change the values of a type in the implemented protocol functions for deftype?

8:25 raek: tobiasraeder: what do you mean by "value of a type"?

8:28 jjido: ,System/out

8:28 clojurebot: #<PrintStream java.io.PrintStream@168b59a>

8:28 tobiasraeder: @raek if i deftype mytype that implements an interface which got getName and setName [name] and in the implementations i would like to the set :name "value" of the defined type

8:28 which is a pretty oo approach i guess

8:30 jjido: ,(do (defrecord foo [bar wombat]) (print-map (new foo 1 5)))

8:30 clojurebot: DENIED

8:30 raek: iirc, deftype defines immutable types

8:31 jjido: Raek: not sure, the doc suggests you can write your mutators

8:31 raek: I think the docs mentions a way to call the construcor

8:32 to create a new instance

8:32 tobiasraeder: mhm

8:32 raek: hrm, defrecord is always immutable, at least

8:33 tobiasraeder: i need this for some kinda weird interop stuff

8:33 is there a way to define variables with proxy which can be set afterwards? (an atom, or something of that type, needs to be mutable i think)

8:34 hoeck: tobiasraeder: (deftype Foo [^:unsynchronized-mutable a]) will create a type with a single private mutable field

8:34 raek: i recall reading something about mutable fields

8:34 jjido: can you get the list of fields back from defrecord or from a record?

8:34 raek: you can always use an atom

8:34 hoeck: tobiasraeder: using an interface like you suggested lets you alter the field

8:35 tobiasraeder: @hoeck alright, that sounds like a good way for me to do that i guess

8:35 hoeck: or use a plain record and an atom/ref inside

8:35 tobiasraeder: the atom/ref is scoped inside the record then, right?

8:35 hoeck: tobiasraeder: usually this is only useful if you are going to implement some low-level datastructure

8:36 jjido: (keys myrecord) doesn't work

8:36 hoeck: tobiasraeder: yes, and accessible via (:key the-record) or the get/valAt methods

8:36 tobiasraeder: i need an object that implements an interface of getters and setters and stores the state interally

8:36 @hoeck that sounds really like what i am looking for :)

8:37 internally*

8:37 hoeck: just make shure you construct you record with the appropriate fields set to an atom

8:37 (MyRecord. (atom 0))

8:38 are you implementing the iface or do you want to provide sth to a java consumer??

8:38 tobiasraeder: implementing the interface so the java part can use the interface functions to set/get state

8:40 hoeck: so if you don't care that the record carries the state in a public field, use a record

8:41 tobiasraeder: yeah i dont mind

8:41 hoeck: thats the easiest and threadsafe way to do it

8:42 tobiasraeder: that is the [^:unsynchronized-mutable a] version, right?

8:42 hoeck: using :volatile-mutable or :unsynchronized-mutable requires more thinking about threading issues

8:42 no, I meant the easiest being the defrecord + atom way

8:44 tobiasraeder: @hoeck so if i create the record with (MyRecord (atom 0) (atom 0) (atom 0)) howwould i set one of those values inside the implementation of the interface?

8:45 jjido: ,(map (seq {:a 1 :b 3}) key)

8:45 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$key

8:46 hoeck: tobiasraeder: http://gist.github.com/604507

8:46 tobiasraeder: @hoeck thank you very much.

8:46 raek: tobiasraeder: with 'reset!' (also, not all irc clients highlight when there is a @ before the nick)

8:47 jjido: ,(doseq (seq {:a 1 :b 3}) key)

8:47 clojurebot: java.lang.IllegalArgumentException: doseq requires a vector for its binding

8:47 sexpbot: @Raynes

8:47 Raynes: Mine does.

8:48 I don't think I've ever used a client that doesn't highlight any sentence with my nickname or highlight key in it, despite it's prefix and postfix.

8:48 raek: jjido: use dorun or doall to force a seq

8:48 hoeck: tobiasraeder: instead of having more than one methods I would rather use a hashmap in one single atom

8:49 jjido: ,(doall (seq {:a 1 :b 3}) key)

8:49 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$key

8:49 hoeck: tobiasraeder: and the IMutable must be declared with definterface or defprotocol but I guess you got that already

8:49 raek: ah, misunderstood the intentions

8:49 map takrd thr fn first

8:51 jjido: ,(map key (seq {:a 1 :b 3}))

8:51 clojurebot: (:a :b)

8:51 jjido: Raek: does it work on a record?

8:51 raek: seq? yes

8:52 seq is called my map automatically by map

8:52 so you can leave it out

8:56 jjido: I want to do (apply record-name. (map val myrecord)). It does not work obviously.

8:56 raek: constructors are special syntax and not functions

8:56 so

8:57 jjido: I need a macro?

8:57 cemerick: no, a factory function will do just fine

8:57 raek: #(record-name. %)

8:57 cemerick: jjido: this might be of interest, though it's not exactly what you're after right now http://cemerick.com/2010/08/02/defrecord-slot-defaults/

8:58 dnolen: jjido: factory fns for records and types did not make it into 1.2. Just provide your own factory fn. It's also removes the need for users to have to import the class.

8:58 raek: #(record-name. %&) ; even

9:02 chouser: raek: that last one will pass in a seq, not multiple args

9:03 dnolen's advice is sound

9:09 LauJensen: Morning chouser

9:16 chouser: good morning

9:20 fogus_: good morning fine sir

9:25 sproust`: Good morning.

9:25 What is the idiomatic way to join components of a path?

9:26 (clojure.lang.java/file) "seems" to work file; grepping for path.separator yields something else.

9:26 s/file/fine

9:37 rhickey: so, I'm failing to see how completely self-contained messages and responses can handle this:

9:37 (do (prn "what is your name?") (println "Hi " (read)))

9:37 in the remote repl

9:38 self-contained messages seem to be dominated by a desire to avoid side channels, but it seems to me that conversations between the IDE and the repl host are in fact side conversations

9:40 since executing the above starts a multi-message conversation that can't be interleaved

9:41 cemerick: rhickey: exactly why I (mostly) punted on *in*

9:41 rhickey: ah

9:42 cemerick: (read) in particular is tied to the notion of an attached terminal, at least conceptually

9:42 rhickey: I can also see difficulty for people sitting between some stream input and a whole-message interface in trying to delimit messages

9:42 cemerick: Also why I (fully) punted on System/out and System/err, and *out* and *err* w.r.t. sends and such.

9:43 That's a client UI issue IMO.

9:44 rhickey: I think that makes it harder for some clients

9:44 cemerick: really? Ctrl+enter for "send"...

9:44 rhickey: if they take input from a true stream, what are they going to have to do, call read?

9:45 cemerick: you are imagining a wholly owned client

9:45 cemerick: "wholly owned"?

9:45 rhickey: also, if you forget a closing paren and push ctrl-enter?

9:45 can you type another paren?

9:45 cemerick: Immediate failure, and an :error response msg back. *shrug*

9:46 rhickey: cemerick: the repl client is the UI component

9:46 == wholly owned

9:46 but might not be the case

9:46 source-of-input -> repl-client -> ...

9:46 where source of input is a true stream

9:47 cemerick: I rejected streams entirely from the start.

9:47 rhickey: obviously a programmatic use of a message interface can send fully formed commands only

9:47 but restricting the API to that seems limiting

9:47 again, I think to avoid side channels, is that it?

9:48 cemerick: that, and one has to assume that there's more than one client connected to the same environment, so there's no way to properly distinguish *out*, *err*, System/out, System/err

9:49 rhickey: cemerick: depends on how you define environment

9:49 cemerick: single clojure process IMO

9:49 rhickey: so, again, could be multiple connections rather than multiplexed

9:49 cemerick: I think the terminal has to be considered the edge case, rather than the driving consideration.

9:49 (as a concept, that is)

9:49 rhickey: a single clojure process can have more than one *out* etc

9:49 sproust`: Am I missing something, or I can't find any function in core/contrib to get/strip file extensions?

9:50 cemerick: well, every thread can have a different *out*, which is sorta my point

9:51 rhickey: cemerick: I don't see it, that means you can properly distinguish

9:51 cemerick: between output generated by different client connections, you mean?

9:51 rhickey: cemerick: yres

9:52 yes

9:52 human->environment, one connection, IDE->environment -> another connection

9:52 cemerick: Perhaps I'm just not clever enough. Output associated with arbitrary sends, futures, (.start (Thread. fooey)) can be traced back?

9:53 rhickey: cemerick: bind *out* in the future

9:53 to a separate pipe

9:53 LauJensen: ,(last (re-find #"(.*)\.\w{3}" "test.xml"))

9:53 clojurebot: "test"

9:53 LauJensen: sproust`: will that work?

9:55 sproust`: Lau: Sure, or using .lastIndexOf, just surprised there isn't a stdlib function to do that. Very common operation. Maybe I should submit one?

9:55 cemerick: Certainly, tooling would be working over a different connection than a human. The "bind *out* in the future" notion is something I hadn't considered, though that doesn't have anything to do with *in* of course.

9:55 rhickey: cemerick: same thing with *in*

9:55 cemerick: rhickey: I guess I see (read) as a red herring.

9:55 rhickey: it seems the current design is dominated by multiplexing

9:55 LauJensen: sproust`: Oh yea forget about lastIndexOf, thats much better

9:56 sproust`: dunno where it would fit in contrib, but go have a look :)

9:56 rhickey: cemerick: perhaps, but it's part of a family of things that are difficult as is

9:57 certainly (do (prn "what is your name?") (println "Hi " (read))) works at the current repl, and won't in an atomic message transaction design

9:57 sproust`: ,(defn split-ext [filename] (let [index (.lastIndexOf filename ".")] (map join (split-at index filename))))

9:57 clojurebot: DENIED

9:57 cemerick: which I've no problem with *shrug* I know others disagree.

9:58 rhickey: cemerick: that's not to say that supporting both means losing the request response pairing, I think that is doable

9:58 LauJensen: sproust`: more like (let [s "text.xml"] (.substring s 0 (.lastIndexOf s ".")))

9:58 cemerick: rhickey: my basis is the enclojure repl, where you've got *out* and *err* in a different panel entirely, piped from the console -- and when connected remotely, you just lose System/out and other threads' *out* entirely. Same with swank/SLIME afaik.

9:59 rhickey: cemerick: I'm not disagreeing with that, and helped with the enclojure repl

9:59 cemerick: Not that that's an ideal or even a local maxima, BTW.

9:59 rhickey: System/out can't be salvaged except as a global feed

10:00 I'm focusing more on the message-transaction thing

10:01 if conversations happened over different connections, *in*s and *out*s could be kept straight

10:01 human + ide = 2 conversations

10:01 cemerick: sure, that's a given

10:02 sproust`: LauJensen: this is what would be useful to me: http://gist.github.com/604609

10:02 cemerick: my question is: is every send and future, etc going to keep the lineage of *out*?

10:02 rhickey: cemerick: and 2 connections?

10:02 cemerick: and 2 connections what?

10:02 rhickey: and therefor 2 connections

10:02 one for each

10:03 sproust`: Lau: feel free to paste into appropriate lib.

10:03 LauJensen: sproust`: You should start by posting it on the ML

10:03 drewr: sproust`: I wrote this for joining paths together (c.j.io/file requires each component know whether its relative or absolute) http://gist.github.com/604610

10:03 cemerick: right, I mean on a per-connection basis -- the lineage of *out* would need to be threaded through every send, future, and (Thread.).

10:03 rhickey: cemerick: I'm trying to understand the point you were making here, that you pointed to in your design doc:

10:03 http://groups.google.com/group/enclojure/browse_frm/thread/dcea0e94d198f44e

10:04 cemerick: And if it is, would that only be in this environment, or in Clojure generally.

10:04 sproust`: drewr: thx. Shouldn't you use as-file instead of File. directly?

10:05 rhickey: cemerick: I disagree about needing to thread it - if people are sending off futures etc without establishing *out* binding explicitly they get nopthing useful, same as now. If they are relying on the root binding their code is broken

10:05 cemerick: rhickey: That thread was about a particular design flaw in the enclojure repl, which was in any case entirely streams-based.

10:06 rhickey: In that case re: threading of *out*, it seems we're in violent agreement. :-)

10:06 rhickey: cemerick: I understand, but as I move away from the atomic message I don't want to reintroduce the flaw

10:06 cemerick: (barring the inevitable IRC misunderstandings)

10:07 rhickey: so, a connection gets its own *in* and *out*, and if it properly conveys them, that will work fine. That leaves me wondering about the need for atomic complete message

10:07 cemerick: rhickey: so by side channel, you mean establishing full-on streaming for *out* and friends per-connection?

10:07 rhickey: cemerick: right

10:08 a single connection's ins and outs need only one physical connection

10:08 cemerick: Totally fine by me. My complaint in that thread was that I was having to pluck result values from *out*, which was being chunked separately from each send's response.

10:08 s/separately/off cadence

10:08 drewr: sproust`: no, that causes the problems I mentioned

10:09 rhickey: cemerick: that can and still needs to happen, as someone can send a command that launches a thread that prints to *out* for another hour

10:09 saying that a response includes all output associated with the command is impossible

10:10 cemerick: well, result values have to be delineated in some reasonable fashion

10:10 rhickey: so, I think you need to distinguish writes to *out* by the repl engine itself

10:10 cemerick: results are the easiest thing

10:10 cemerick: Right, which was the :value slot in nrepl's response messages.

10:10 rhickey: since the repl is holding the return from eval

10:11 your talking about if the repl printed exception trace or something, not lining up?

10:11 you're

10:13 cemerick: no - the value provided to c.m/repl's :print

10:13 rhickey: cemerick: what's the distinction between "result values" and "send's response" above?

10:14 cemerick: repl-printed stack traces just get dumped to *err*

10:15 avbranco: quit

10:16 cemerick: rhickey: in the enclojure regime, reads could not be paired with sends

10:17 "result value" to me means, if I send "(println 5) 0", I get back readable values of "nil" and "0"

10:17 rhickey: ok

10:17 cemerick: Tooling would generally be sending only one expr at a time, but the above is necessary to get the highlighting chouser suggested

10:18 er, scratch "readable" above

10:18 Tooling obviously needs to be sending stuff that will result in something readable.

10:18 interactive users, no so much

10:18 rhickey: you are saying enclojure gave you nil 5 0?

10:18 sproust`: drewr: your definition is a bit unusual; if I have an absolute path I would want the latest argument to take over the root again.

10:19 cemerick: rhickey: I'm saying that a single send of "(println 5) 1000" could result in enclojure-repl sending back multiple chunks, e.g. "5\n100" and "0\n"

10:20 rhickey: ah

10:20 cemerick: they were 1K chunks, but when tooling is getting a full accounting of all vars defined in the env, that's no good.

10:23 drewr: sproust`: I don't, but ymmv

10:23 ym apparently does v :-)

10:24 rhickey: cemerick: but you shouldn't care if *out* and *err* come back that way

10:24 sproust`: drewr: not so much my opinion, I think it's unusual re. other langs. To be verified.

10:24 rhickey: cemerick: just need whole results

10:24 cemerick: rhickey: I don't with nREPL, because it returns values discretely. enclojure-repl was entirely stream-based, so that's what I was faced with.

10:25 sproust`: drewr: CPython's: >>> join("/foo", "///bar", "/baz///") ->>. '/baz///'

10:25

10:25 cemerick: rhickey: I encourage you to disregard that gg thread. enclojure-repl had a variety of design issues that I think are safely settled.

10:26 as long as expression results are available discretely from *out* et al., all's good

10:26 s/from/separate from

10:26 rhickey: I am contending a design that respects the inherent streamy-ness of *out* and *err* needs to arbitrarily chunk their output into multiple messages, but need not do so with the eval result

10:26 cemerick: again, entirely agree

10:27 I never considered side channels for *out* et al. at all.

10:28 sproust`: It would be nice to have (re-quote) and (re-escape) for regexps (like Emacs).

10:28 rhickey: the nrepl design supports timeouts, but they can't really be made to work

10:28 leafw: rhickey: what IDE do you use? Or just a plain editor? I have always struggled to find an IDE without deep downsides.

10:29 rhickey: i.e. you spin off a future per request, but timing out on the future doesn't necessarily stop it, nr does interruption, for e.g. an infinite loop

10:29 leafw: I am just merely curious, as to in what way is clojure itself being developed.

10:30 rhickey: so, people may feel better seeing the prompt return, but could have left something churning forever

10:30 cemerick: rhickey: no, the timeout doesn't stop it, but an interrupt (which is automatically sent on a timeout now, I think) does stop infinite loops, e.g. (apply + (iterate inc)) was my testcase for that

10:32 LauJensen: $mail hugod I notified the Arch team about the bug in Tomcat and its already been fixed :P

10:32 sexpbot: Message saved.

10:34 jfields: is there any easy way to convert {:a {:b {:c 1}}} to [[:a :b :c] 1] or {[:a :b :c] 1}

10:36 rhickey: cemerick: I think if the code never enters an interruptable API call it will not be stopped

10:37 cemerick: rhickey: I'm starting to think you're right -- my interrupt of (loop [] (recur)) hasn't been respected yet :-(

10:37 shit

10:37 rhickey: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#interrupt()

10:40 cemerick: well, I'm officially a dope

10:41 rhickey: no, it's a subtlety they don't call out, because the need is so great but it is not safely possible to do generally

10:41 that's not to say that timeouts aren't interesting at the API level, but given what they can and can't do, the semantics need to be clear.

10:43 http://download.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html

10:44 "Unfortunately, there really isn't any technique that works in general. It should be noted that in all situations where a waiting thread doesn't respond to Thread.interrupt, it wouldn't respond to Thread.stop either. Such cases include deliberate denial-of-service attacks, and I/O operations for which thread.stop and thread.interrupt do not work properly."

10:45 cemerick: Funnily enough, I coded a Java REPL back ~2000 that used .stop for interrupts. Worked more than Future.cancel does, but obviously not advisable.

10:45 Can't believe I forgot about that.

10:45 LauJensen: cemerick: age...

10:45 cemerick: Yup, I'm an old codger now.

10:45 zoldar: jfields, (map #(if (map? %) (first (keys %)) %) (tree-seq map? vals {:a {:b {:c 1}}})) that's the closest I could get...

10:51 tobiasraeder: someone mentioned to me earlier that there was a IMutable interface and it could be used for defrecord. I can find any definition of IMutable tho. Anyone can help me on that? :/

10:52 rhickey: tobiasraeder: records are immutable

10:52 jfields: zoldar, thanks

10:53 tobiasraeder: @rhickey gave me that gist and said it should work http://gist.github.com/604507

10:53 sproust`: re. thread.interrupt() : this is a platform limitation IINM, same goes with C threads. You can't forcibly interrupt them; Java's thread cancellation is probably built as a cooperative mechanism, which includes interrupt points at choice system calls.

10:53 rhickey: tobiasraeder: I don't know what that is

10:54 tobiasraeder: @rhickey alright :) thanks for the input on that

10:54 @rhickey is there any way to implement an interface (using proxy, defrecord, deftype etc) and store mutable data in/attached to that object?

10:54 rhickey: tobiasraeder: someone else will have to help you with that

10:55 tobiasraeder: @rhickey alright :)

10:55 cemerick: tobiasraeder: see the -mutable field metadata for deftype and defrecord http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/deftype

10:56 tobiasraeder: If you hose yourself b/c your records have mutable fields though, you're on your own :-P

10:56 tobiasraeder: @cemerick ill give it a try. thank you

11:01 rhickey: cemerick: note that's only for deftype, not defrecord

11:02 cemerick: rhickey: Thanks for the clarification.

11:02 tobiasraeder: see ^^

11:03 that's what I get for relying upon dim memories of irc design discussions :-)

11:03 tobiasraeder: hehe

11:03 thanks for pointing it out.

11:04 one more question if i use defrecord/type to implement functions they need atleast one parameter for "this"

11:04 does the function in the java interface need atleast 1 parameter aswell?

11:05 cemerick: "to implement functions"?

11:05 (fn [a] a) <-- a function

11:05 * cemerick is starting to sound like hiredman

11:05 cemerick: ;-)

11:12 djpowell: Thread interruption in java is pretty nasty btw, cause catching InterruptedException resets the interrupted flag. So any code that does 'catch (Exception e)' unwittingly breaks interruption, and Java's checked exceptions make not using 'catch (Exception e)' very tedious

11:14 rhickey: djpowell: yeah :(

11:20 djpowell: I wanted to use it as a cancellation mechanism, but my jdbc driver was swallowing interrupted - there was a patch for that, but the thing is so fragile that I decided to backup interrupted with my own secondary flag, and switched to using .wait(timeout) in a loop, and checking my secondary flag in the loop.

11:21 the need to wrap checked exceptions into runtime exceptions makes it even harder to tell if someone has swallowed your interrupt. pesky checked exceptions...

11:48 as people are talking about repls, i'll take the opportunity to advertise http://github.com/djpowell/liverepl - lets you hack a clojure repl into any running java or clojure process. quite handy to hack one or more repls into an existing clojure repl process, giving you a single process with multiple repls - handy for demoing concurrecy stuff

11:53 AWizzArd: rhickey: I discovered that (defrecord Foo [size]) can be problematic when you want to use the dot-accessor: (let [f (Foo. 100)] [(:size f) (.size f)]) ==> [100 1]

11:54 cemerick: yuck, I thought that was fixed a long while ago.

11:56 rhickey: what is your expectation?

11:56 you have a class with a method and a field called size

11:56 cemerick: oh, nm, I transposed the results with the expressions

11:57 thought (:size f) was returning 1

11:57 rhickey: cemerick: right, that was fixed

11:57 cemerick: whew :-)

11:57 sempah: good evening

11:57 how can I iterate over the seq? -> (defn addN [& x] (+ x x))

11:58 AWizzArd: Is there another syntax for accessing fields, other than (.myField x) or (:myField x)?

11:58 sempah: ohh and first @ rhickey: thx for the language ;)

11:58 AWizzArd: sempah: in your case x is a list of the arguments. (addN 10 20 30) means that x = (10 20 30). You could say (defn addN [& x] (reduce + x))

11:59 sempah: gracias ;)

12:05 AWizzArd: rhickey: maybe there can be a warning when adding a field that has the same name as one of the methods?

12:07 rhickey: AWizzArd: if you are using records you should be using :x

12:09 AWizzArd: rhickey: in tight loops the dot-accessor + type-hint is 2.3 times faster.

12:10 sproust`: Hmmm, I have a question about dymamic variables. I have a (binding) clause in my main module, which binds 'emit to a function used for reporting progress. In another module, I use emit; when I evaluate from scratch, I get an error about emit not being available. I cannot import it from the main namespace, b/c that would created a circular dependency. I could simply shove a (declare emit) in another module... is there a better way out?

12:11 AWizzArd: Well, in most cases it is not a problem of course. Today it was the first time that I stumbled upon this, when benchmarking my Clojure serializer, which is not too far from Java speeds btw.

12:11 sproust`: s/created/create/

12:11 AWizzArd: sproust`: declare seems to be good here

12:12 You tell the compiler and other readers there there is indeed such a thing.

12:14 sproust`: AWizzard: thx. I thought there might be a better way.

12:15 hiredman: AWizzArd: I believe :x uses a method cache with a type hint that hotspot should eventually inline away

12:23 sproust`: I'm invoking Clojure from the cmdline for my final program. Startup delay is insane (> 10 seconds). Is there a way to have clojure trace/report what it is doing (e.g. "loading library bla"), so I can view progress?

12:23 rhickey: cemerick: all the tools guys bought into the command-server (i.e. no *in*) model?

12:28 dnolen: sproust: did you AOT?

12:28 sproust`: dnolen: Nope. My point is not to bitch about startup time (sorry), but rather to find out if there is a way to trace loading.

12:29 chouser: sproust`: interesting question, never tried.

12:29 dnolen: sproust: ahead-of-time compile, that improves load time significantly. Clojure is launching, compiling your program, then running. I'd expect that to be slow.

12:29 chouser: might be able to instrument 'require' or something

12:30 hiredman: you can instrument load pretty easily

12:30 sproust`: hiredman: I see.

12:30 Oh, Clojure doesn't have something like advice, does it?

12:30 I meant, auxiliary methods.

12:31 hiredman/dnolen: Thx.

12:31 hiredman: http://github.com/technomancy/robert-hooke

12:33 sproust`: Awesome.

12:34 chouser: so did we again lose the ability to build contrib against a local clojure.jar?

12:34 rhickey: chouser: I was wondering the same just yesterday

12:35 chouser: the instructions in the README are certainly gone again

12:36 Are you physically near the Clojure/core team most days?

12:37 rhickey: chouser: no

12:37 chouser: so no sticking your head out the office door and yelling, "Stu!!!"

12:37 rhickey: this question has been asked, but not yet answered

12:37 cemerick: rhickey: all but ninjudd, I think, but cake and lein are different beasts, I'd say

12:38 chouser: have you tried the old instructions?

12:38 rhickey: cemerick: what's cake?

12:38 cemerick: rhickey: swank and enclojure-repl having the same limitation, etc

12:38 rhickey: a lein-compatible build tool that uses a persistent jvm for invocations, repls, etc

12:38 http://github.com/ninjudd/cake

12:38 chouser: c.c.Condition isn't building for me from contrib master. bleh.

12:39 AWizzArd: hiredman: I see.

12:39 rhickey: cemerick: hrm, I don't see why any such programmatic interface wouldn't be happy with messages

12:39 cemerick: inbound

12:40 cemerick: rhickey: `cake repl` aims to look and feel just like c.m/repl on a bare console, AFAIK

12:40 hiredman: I think lein would more likely be a way to start a repl server than actually communicate with one

12:40 rhickey: cemerick: ah

12:41 svs`: Hello. I managed to build a proper jar using lein following the advice here http://zef.me/2470/building-clojure-projects-with-leiningen but when I build my little non-trivial project I get Exception in thread "main" java.lang.NoClassDefFoundError: planet

12:41 cemerick: hiredman: no reason why the result of all this shouldn't allow you to say `somecmd --remote localhost:58943` or whatever

12:41 (as well as start repl servers :-))

12:41 that's actually exactly what nrepl's main does, except it always defaults to a new server started on localhost

12:41 technomancy: yeah, I'm less interested in being in the client business with leiningen repls

12:43 cemerick: rhickey: ...which is why ninjudd and I have bumped heads. That should have made me think of having side-channels, but I'd been focused on only discrete msgs.

12:43 ninjudd: :-D

12:44 chouser: rhickey: oh, s.sierra added custom clojure.jar build instructions to the contrib readme last friday.

12:44 trying them now

12:46 rhickey: chouser: they're awful, IMO. hoops and more hoops

12:47 who could possibly think this is reasonable anymore?

12:47 chouser: only 40% more complex than before, which was only 40% more complex than the original...

12:47 technomancy: it works OK for people who don't build contrib for themselves

12:48 fogus_: technomancy: Hooray! We've achieved OK-ness!

12:48 technomancy: it's nice to be able to say "I want error-kit" without pulling in the combinatorics, etc

12:49 rhickey: technomancy: I'm only speaking to the custom clojure for people like me who change clojure often and want to make sure they don't break contrib

12:49 they == me

12:50 cemerick: *cough* continuous integration *cough* ;-)

12:50 rhickey: more overhead

12:50 used to be ant and ant

12:51 I don't want to integrate until I'm ready

12:51 chouser: but <x> is *everywhere*, it's only marginally more complex and takes care of so much for you. Custom <y> is bad.

12:52 cemerick: rhickey: if the ant build copies a clojure.jar snapshot to your local repo, then the new situation should be ant, mvn

12:52 chouser: (for [[x y] [:stomp :protocol, :maven :build-system, :tomcat :web-server] ...)

12:53 rhickey: chouser: that analogy is broken, since there is much more to do here, much more complexity, apples and oranges, not standard apple vs custom apple

13:03 "2. Set a custom version number in src/clj/clojure/version.properties" - stunning

13:08 Chousuke: there could be a makefile that does all that for you ;P

13:08 just to bring yet another build tool into the mix!

13:11 rhickey: Chousuke: will it remember not to check in the changed properties file for me?

13:11 Chousuke: hmmh. .gitignore?

13:11 or can you do that?

13:11 rhickey: Chousuke: it's part of the project!

13:11 Chousuke: That's problematic :/

13:12 cemerick: git add -f ignored-file overrides .gitignore IIRC *shrug*

13:12 rhickey: overcoming complexity rather than avoiding it - what have we come to?

13:12 back in the tar pit

13:13 cemerick: At the moment, there's no such thing as avoiding build complexity. One either deals with it, or redistributes it.

13:13 LauJensen: That was a good essay/paper (out of the tar pit)

13:15 rhickey: cemerick: not distinguishing inherent and incidental complexity is the problem

13:15 cemerick: rhickey: only if you can define a closed system

13:15 Usually, incidental complexity is forced upon you by external, often social factors.

13:19 arohner: cemerick: it's not that clean. Maven is neither purely incidental, nor purely inherent complexity. And sometimes it increases complexity

13:20 cemerick: arohner: never said it was. All these systems are flawed.

13:20 rlb: What's the best way to generate a sequence of values like this: (for [x (range ...) y (range ...)] [x y]) [final-x final-y]?

13:21 arohner: cemerick: I'm not trying to rip on maven, I'm just pointing out that there's a third option, and the distinction isn't always clean between deal, redistribute and increase complexity :-)

13:21 rlb: i.e. I'd like all the values from the for, followed by the terminal values.

13:21 arohner: rlb: concat

13:21 dmiller2718: rhickey: speaking of complexity of the build: Q1: okay to include DLR DLLs in a binary distribution of ClojureCLR? (binary distribution highly requested)

13:21 arohner: or just (for [x (range final-x + 1)]...)

13:22 err (range (inc final-x))

13:22 cemerick: arohner: I know :-) Which is the third option?

13:22 rlb: arohner: ah, concat's exactly it, thanks

13:22 arohner: cemerick: increase complexity, without dealing or redistributing

13:22 cemerick: oh, I see what you mean

13:22 arohner: cemerick: "failure is always an option"

13:23 cemerick: ha! :-D

13:23 arohner: exactly my fundamental conclusion: http://cemerick.com/2010/09/22/wherein-i-feel-the-pain-of-being-a-generalist/

13:23 Meanwhile, practical concerns continue to dominate.

13:25 duncanm: hola

13:26 ,(instance? clojure.lang.ISeq [])

13:26 clojurebot: false

13:26 duncanm: shouldn't that return true?

13:27 raek: no. :)

13:27 duncanm: if i want to write a method that catches vectors, what should i dispatch it on?

13:27 raek: collections *are* not sequences, but they can produce sequential views of themselves

13:28 duncanm: i could use clojure.lang.PersistentVector, but would that be too specific?

13:28 (my dispatch-fn is 'class')

13:28 raek: ,(instance? clojure.lang.IPeristentVector [])

13:28 clojurebot: java.lang.ClassNotFoundException: clojure.lang.IPeristentVector

13:28 raek: ,(vector? [])

13:28 clojurebot: true

13:29 kjeldahl: ,(instance? clojure.lang.IPersistentVector [])

13:29 clojurebot: true

13:29 raek: if you do it with protocols, I you can extend the protocol for IPersistentVector (i.e. any vector type)

13:29 chouser: ok, I give up. what if I *want* all of contrib (and its examples) on my classpath in a clojure repl?

13:30 I had hoped mvn clojure:repl in contrib would do it, but that fails.

13:30 raek: hrm, wait. multimethods can do that too

13:30 they use isa? for the matching, right?

13:30 (isa? clojure.lang.IpersistentVector [])

13:30 ,(isa? clojure.lang.IpersistentVector [])

13:30 clojurebot: java.lang.ClassNotFoundException: clojure.lang.IpersistentVector

13:30 raek: ,(isa? clojure.lang.IPersistentVector [])

13:30 clojurebot: false

13:31 raek: ,(isa? (class []) clojure.lang.IPersistentVector)

13:31 clojurebot: true

13:33 duncanm: raek: isa? and instance? are different, right?

13:33 raek: conclusion: with dispatch fn 'class', you can have an implementation for IPersistentVector

13:34 isa? uses instance? for class hierarchies

13:34 duncanm: ,(instance? {} clojure.lang.IPersistentVector)

13:34 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.Class

13:34 raek: you can define other kinds of hierarhies too

13:34 duncanm: right

13:34 okay

13:35 raek: isa? is a generalized instance?, one could say. it is not structly type-based

13:35 chouser: adding clojure-maven-plugin to contrib's pom.xml doesn't seem to help.

13:35 duncanm: raek: but when i only care about classes, i can use the more specialized 'instance?' fine

13:37 raek: yes, but multimethods use isa? to find a matching dispatch value

13:38 but if you do some comparison yourself, then instance? is fine

13:38 rhickey: dmiller2718: no binaries in git, but iff the MS license allows, ok in .zip in downloads section

13:40 raek: (defmulti foo class) (defmethod foo clojure.lang.IPersistentVector [...] ...) ; should work fine, since (isa? (class []) clojure.lang.IPersistentVector) => true

13:41 LauJensen: There's a license which states you can put certain binaries in git?

13:41 rhickey: cemerick: that rationale could be pulled out at any time in any domain to excuse things sucking - doesn't make them suck less

13:41 chouser: aaargh

13:42 * chouser gives up in another direction.

13:42 rhickey: maven seems to feel at basic principles like - pay for what you use

13:42 dmiller2718: rhickey: Okay, that also answers Q2 regarding putting libs in dev version.

13:43 rhickey: MS license for DLR okay with distribution of binaries as long as basic license text is included, which I will do. Thx.

13:43 rhickey: seems to fail

13:44 maven == everyone pays for what anyone might ever do

13:44 AWizzArd: (:

13:44 dysinger: :)

13:44 chouser: aaaargh

13:45 lypanov: any slimv users around?

13:45 * dysinger raises hand

13:46 lypanov: dysinger: y slimv vs vimclojure? happy?

13:48 dysinger: lypanov: oh I thought that was a type for "slime" (the real deal)

13:48 lypanov: heh.

13:48 cemerick: rhickey: I don't think open platforms/communities are structurally capable of sucking less in this department, as I alluded to in the post

13:48 rhickey: cemerick: heh

13:49 * rhickey fears for Clojure

13:49 arohner: cemerick: sane versioning, sane package format would help significantly

13:49 of course, replacing .jar isn't really an option

13:50 cemerick: rhickey: The fact that clojure's build.xml contains a bug-ridden slow implementation of half of maven would seem to indicate that you're already needing at least that much of it. ;-)

13:50 rhickey: arohner: replacing jar is coming, in fact

13:51 cemerick: I seriously doubt it. People had a hammer and started swinging

13:52 cemerick: rhickey: Insofar as you're interested in having users on the JVM, you have to have artifacts going out in a maven-compatible way. There's those social factors again.

13:52 slyrus__: cemerick: but that build.xml doesn't require that you download 3 dozen random apache projects I've never heard of (nor want to hear of)

13:52 * TeXnomancy is curious about aether

13:52 cemerick: slyrus__: wha?

13:52 TeXnomancy: might be nice to have access to "Maven: The Good Parts"

13:53 slyrus__: cemerick: just responding to your comment about clojure's build.xml having half of maven in it

13:53 cemerick: slyrus__: I'm saying, what are the 3 dozen random apache projects?

13:54 slyrus__: all of the random stuff in .m2, plexus-*, commons-*, etc...

13:54 perhaps I exaggerate the number

13:55 cemerick: slyrus__: do you care, if it's automated?

13:55 slyrus__: I'm annoyed by it. Perhaps I shouldn't be.

13:55 cemerick: slyrus__: If you are, you probably should be annoyed by how many files an OS update process touches or something, too. *shrug*

13:56 * cemerick extracts himself from another build tool discussion before the afternoon disappears

13:56 chouser: cemerick: I'm caring right now because the automation and/or my attempts to get help failed

13:57 cemerick: chouser: this is the 'use a custom build of clojure with contrib' issue?

13:57 slyrus__: cemerick: yes, we should drop this, but my point was that at least the slow, buggy half-of-maven that's in build.xml is relatively self-contained and one can easily go in and fix/improve it. fixing a whole bunch of random apache projects doesn't sound like fun.

13:57 solussd: So I've been reading The Joy of Clojure and read through the lazy quicksort algorithm- it says it is tail recursive, but cons everything together in the 'else' position of the if containing the recur- is this still tail recursion?

13:58 cemerick: slyrus__: quite certain I've never touched any part of maven or its plugins *shrug*

13:58 chouser: cemerick: no I gave up on running a repl in that context. I just want a clojure repl with all of contrib (including examples) on the classpath

13:58 LauJensen: cemerick: Im also not sure why its always you who have to take a beating for Maven? :)

13:58 chouser: having tried, asked here, googled, tried, and failed, I have given up on the automation

13:58 I'm now building the classpath by hand

13:58 I'll paste it when done

13:58 rhickey: yay, classpath!

13:59 :)

13:59 cemerick: :-(

14:00 chouser: ok, to allow 'require' of any of the examples that will soon be checked (back) into contrib, simply start clojure so:

14:00 java -cp ../clojure/clojure.jar:modules/accumulators/src/examples/clojure/:modules/condition/src/examples/clojure:modules/datalog/src/examples/clojure:modules/miglayout/src/examples/clojure:modules/monads/src/examples/clojure:modules/probabilities/src/examples/clojure/:modules/types/src/examples/clojure/:modules/accumulators/src/main/clojure/:modules/condition/src/main/clojure/:modules/datalog/src/main/clojure/:modules/miglayout/src/main/clojure/:modules/monads/src/main/clojure/:modules/probabilities/src/main/clojure/:modules/types/src/main/clojure/:modules/def/src/main/clojure/:modules/generic/src/main/clojure/:modules/condition/target/classes:modules/except/src/main/clojure/:modules/graph/src/main/clojure/:modules/core/src/main/clojure/:modules/fcase/src/main/clojure/:modules/swing-utils/src/main/clojure/:modules/macro-utils/src/main/clojure/:modules/stream-utils/src/main/clojure/:modules/macros/src/main/clojure/ clojure.main

14:00 cemerick: chouser: I've not looked at the contrib modularization at all yet -- but if it works as I'd expect, running whatever invocation will cause a local deployment of clojure.jar followed by 'mvn' in contrib will do the trick

14:01 chouser: mvn install; mvn clojure:repl failed -- couldn't find clojure-maven-plugin

14:01 cemerick: chouser: well, that sounds like a bug

14:01 * cemerick never having looked at it

14:02 chouser: following instrustions I found on the web, I added a snippet to the contrib pom to depend on clojure-maven-plugin. after several false starts I was able to get a repl

14:02 ...but examples were not included on the classpath

14:02 Since I have email here that says "Note that the "examples" source paths are only included on the classpath in test mode, which includes clojure:repl and clojure:swank." I assumed that should have worked and had no idea what to pursue next

14:03 asking here gained me nothing.

14:03 cemerick: I'm shocked to hear there's a bug somewhere ;-)

14:03 chouser: so I built that classpath, one item at a time, adding more things as deps failed until it all worked.

14:03 cemerick: I'm sure SS would pick up a thread on clojure-dev

14:06 LauJensen: Yeah, I keep on sticking my neck out there. Masochist, I am he.

14:06 chouser: all this to restore files that were lost during a directory reorganization required by ... buh-buh-bum... maven.

14:06 cemerick: chouser: just wait until all of contrib is sharded into individual repos :-P

14:09 chouser: cemerick: can't wait

14:12 LauJensen: chouser: Why dont you just move contrib over to another build system ?

14:12 chouser: I hate build systems.

14:13 Raynes: He doesn't use build systems.

14:13 chouser: never met one that didn't drive me crazy

14:14 LauJensen: chouser: thats amazing - knowing your threshhold for crazy

14:15 chouser: it's barely the same domain, but ebuild is probably the least painful I've known well -- gentoo's build and dep tool.

14:16 cemerick: sarcasm runs thickly

14:16 throngs plead for sweet relief soon

14:16 in death, maven waits

14:16 * cemerick is having an odd day :-P

14:16 Chousuke: ebuild is more like a build tool tool :P

14:17 chouser: yeah, barely the same domain. but it did involve custom commands for particular situations, user customization, dependency graph resolution, dep downloading, etc.

14:19 cemerick: man, no haiku fans? Tough crowd.

14:20 * shoover golf claps

14:20 wdouglas: Sorry, it was brilliant

14:20 * gravity showed it to some folks in another chan because it made him laugh

14:21 * lypanov couldn't get it to compile

14:21 cemerick: shoover: well played :-)

14:21 shoover: anyone know how to set emacs clojure-mode to left-align single-semicolon comments?

14:21 cemerick: I like it now. I was too busy to count syllables

14:23 cemerick: Should've made it a cinquain.

14:23 rlb: is sequential? effectively #(instance? clojure.lang.Sequential %)?

14:24 MayDaniel: rlb: Yes.

14:24 amalloy: rlb: (source sequential?) makes it pretty clear :)

14:25 rlb: oh, right.

14:25 amalloy: cemerick: is sarcasm really two syllables? it feels like sar-ca-sm to me

14:25 cemerick: amalloy: according to OS X's dictionary... *shrug*

14:26 amalloy: oh funny, cause after asking i just looked it up on M-W, which thinks it's three

14:26 cemerick: I would have said sar•cas•m myself, but...

14:26 really!

14:26 amalloy: http://www.merriam-webster.com/dictionary/sarcasm

14:26 cemerick: amalloy: no, just two there too

14:28 amalloy: oh, i see. i was looking at the part on the right

14:28 now i have to look up what kind of crazy notation that is. IPA or something

14:28 cemerick: exactly right

14:30 raek: hrm, that is not IPA...

14:32 amalloy: yeah, i can't tell what it is either, or what they hyphens are supposed to represent if not syllable breaks

14:35 cemerick: their pronuncuation guide says that - is used to separate syllables, and doesn't mention the little dot symbol in the thing on the left. i interpret that to mean that the thing on the left isn't a pronunciation guide, though i dunno what it actually is in that case

14:40 anonymouse89: when declaring a namespace like (ns hello (:use foo.bar)) how do I specify the refer-like :exclude :only ... ?

14:41 chouser: (:use [foo.bar :only [a b]])

14:41 anonymouse89: chouser: ah, thanks

14:42 chouser: I'm using your command-line stuff btw, very helpful

14:42 chouser: anonymouse89: pretty minimal, but I'm glad it's helping

14:43 interesting that I don't think I'd be inclined add something like that to contrib today. Seems to underdeveloped for the seriousness that is contrib now.

14:43 too

14:45 anonymouse89: chouser: maybe have a look at contrib.complex-numbers :)

14:47 chouser: bleh. deftype means something else now...

14:50 alexyk: lancepantz: thanks for rolling back *env* name

14:51 dnolen: thx for flowing in sync :)

14:51 lancepantz: alexyk: *grrrr*

14:51 :)

14:51 alexyk: lancepantz: is it a purr or a growl? :)

14:51 lancepantz: i unhappily gave in

14:52 alexyk: lancepantz: well, no pain, no gain :)

14:52 lancepantz: now the other thing is *context*

14:52 alexyk: lancepantz: what is /usr/bin/jps which cake is trying to call? My Linux setup lacks it

14:52 lancepantz: chose your battles i suppose

14:52 ninjudd: i'm thinking of renaming it *alexy-context*

14:52 lancepantz: a ps that only list java processes

14:53 alexyk: lancepantz: *context* came to me too while phishing... or fishing, I forgot what it was... :)

14:53 lancepantz: alexyk: are you using the jre instead of the jdk?

14:53 alexyk: do you have have jar on your path?

14:54 * dnolen votes for *alexyk-context-shell-env*

14:54 alexyk: lancepantz: I use prefix gentoo. I know many of you didn't ever hear about it, but ut installs sun0jdk, I have jar. Just upgraded to 1.6.0_21

14:54 ]

14:54 perhaps I need to reveal it somehow

14:55 I'll see...

14:55 lancepantz: yeah, it should be there

14:55 * alexyk votes for adding a test harness to cake which would fail release if it breaks textmate-cake

14:55 alexyk: :)

14:55 or page dnolen out of bed

14:56 on his cozy east coast from teh cake's west one

14:56 lancepantz: alexyk: i will happily accept any pull requests containing tests

14:57 alexyk: dnolen: YES! An epiphany: textcake! no more textmate-clojure or vice-versa agony!

14:57 or, cakemate

14:57 dnolen: org.textcake.bundle.clojure.mode.main/*alexy-context-shell-env-persistent-hash-map*

14:57 lancepantz: lol

14:58 alexyk: org.textcake.bundle.clojure.mode.main/*ninjudd-lancepantz-dnolen-alexy-all-agreed-context-shell-env-persistent-hash-map*

14:58 abrenk: alexyk: /usr/bin/jps -> run-java-tool

14:58 * abrenk is running gentoo, too.

14:58 alexyk: abrenk: is it a symlink?

14:59 abrenk: alexyk: yep

15:00 alexyk: abrenk: thx!

15:01 abrenk: alexyk: "ls -l /usr/bin/ | grep run-java-tool | wc -l" is 43 on my system

15:01 alexyk: abrenk: you mean it has 43 symlinks??

15:01 abrenk: alexyk: if you don't have all those jps, jstack, jconsole etc. symlinks our system are different somehow

15:02 alexyk: abrenk: I run *prefix* gentoo

15:02 on a CentOS :)

15:02 who installed your jps (which package)?

15:03 abrenk: alexyk: "equery belongs /usr/bin/jps" -> dev-java/java-config-2.1.10

15:03 alexyk: abrenk: ah ok

15:03 abrenk: what is *prefix* gentoo?

15:04 alexyk: http://www.gentoo.org/proj/en/gentoo-alt/prefix/

15:04 hiredman: how do you turn off validation for clojure.xml/parse

15:04 alexyk: if you're ever stuck on a box without root and can't rpm/yum, or just want portage, that's what you get. May be useful for folks, sorry if too off-topic.

15:10 lypanov: alexyk: or if you're on a mac. or windows.

15:10 alexyk: lypanov: on mac, macports rules, but yeah. I have a Portage drive image on a Mac, which is case-sensitive...

15:11 lypanov: :/

15:11 dea

15:11 death to macports

15:12 alexyk: lypanov: let a thousand flowers bloom :)

15:12 * lypanov uses brew

15:12 lypanov: but gentoo prefix did the job for a while.

15:12 alexyk: lypanov: brew is amateurish, lots of loose ends

15:12 xkb: what's brew?

15:13 lypanov: doesn't take 24 hours to install a basic pkg tho. so makes me happy.

15:13 alexyk: xkb: http://github.com/mxcl/homebrew

15:13 xkb: thnks

15:17 * lypanov sincerely hopes that his new server setup with pallet will work as a gateway drug for the rest of his company

15:19 alexyk: lypanov: seeing you come from NL, I think it got to be strong enough :)

15:22 nickik: where can I find good CL documentation (like clojuredocs) with examples of all the functions and stuff

15:24 chouser: nickik: maybe http://www.lispworks.com/documentation/HyperSpec/Front/X_AllSym.htm

15:27 nickik: @chouser thats was what im looking for

15:27 @chouser thx

15:29 LauJensen: Amazing service we give here in #clojure :)

15:36 alexyk: LauJensen: the only missing thing is Belgian, um, Danish history :)

15:37 * alexyk wonders who needs Lisp now that there's Clojure is the king of sexps

15:37 LauJensen: Clojure is also Lisp

15:38 alexyk: LauJensen: I meant Common one

15:38 nickik: im working threw PAIP and I implement everything in Clojure so I have to understand the CL version and find functions that are the same or implement them myself

15:39 LauJensen: alexyk: I've often wondered why you'd want a common lisp, when you can have an extraordinary one like Clojure

15:39 alexyk: LauJensen: exactly. I can't even look at CL not having [] {} and : teh right way!

15:40 nickik: i'm having a discusion about that on reddit :)

15:40 alexyk: uncommon lisp

15:40 Chousuke: Clojure has sexy expressions ;P

15:40 alexyk: nickik: are you stirring the passions of old bearded lisp types then?

15:43 nickik: @alexyk not that far in the book only working on the first real exampels

15:45 is there something like the CL member function or do I have to write it myself?

15:46 alexyk: ninjudd: are the clojars versions of protobuf and jiraph up-to-date or should I just git them?

15:46 amalloy: nickik: (some)

15:47 jjido: is it possible to create a recursive structure? Like a double-linked list

15:47 ninjudd: alexyk: protobuf, yes. jiraph, no. i am working on the 1.2 version in the deftype branch, but it isn't quite done

15:47 amalloy: ,(some #{10} [2 4 8])

15:47 clojurebot: nil

15:47 amalloy: ,(some #{10} [2 4 8 10])

15:47 clojurebot: 10

15:47 amalloy: nickik: ^^

15:48 nickik: no member returns the rest (member 2 '(1 2 3 4)) => '(2 3 4)

15:50 shoover: do any emacs users care about indenting single-semicolon comments like the other IDEs?

15:50 here's what I had to do: http://gist.github.com/cd2f5a888aaab4f33fe9

15:51 amalloy: ,(drop-while (complement #{2}) [1 2 3 4])

15:51 clojurebot: (2 3 4)

15:51 amalloy: nickik: good enough?

15:51 alexyk: ninjudd: I'm using the jiraph.tc in clojure 1.1, and have that built, now fails to work with 1.1. Is there an existing jiraph build for 1.2 at all?

15:52 fails with 1.2 from a jar, obviously

15:52 amalloy: shoover: i haven't been using emacs for long, but the way it indents ; comments drives me nuts

15:52 jjido: what is an atom for?

15:53 shoover: amalloy: Me too. I don't mind typing ;;, myself, but if you reindent code anyone else writes, it gets all messed up.

15:53 alexyk: shoover: github added star gist! yay! starred :) Used to fork before just to remember...

15:53 nickik: @amalloy nice better then the one I wrote

15:53 jjido: can I use an atom for a variable that I just want to link back to

15:54 amalloy: nickik: if you want to avoid writing the drop-while/complement/#{} boilerplate you could do something like (defn some [list & search] (drop-while (complement (set args)) list)

15:56 ninjudd: alexy: in the deftype branch. feel free to play around with it

15:56 alexyk ^^^

15:56 nickik: @amally that ok i try to keep the functions as the are because in the book he uses CL and if I have functions with the same name i can use without think about it

15:57 @jjido what do you mean by "link back to"

15:57 callen: what's the name of that emacs bundle somebody put together for clojure?

15:57 amalloy: callen: emacs starter kit?

15:57 jjido: nickik: I am trying to write a double-linked list kind of structure

15:57 nickik: Emacs starter kit

15:57 callen: Bwaha.

15:57 Shanks. Getting going on a new machine.

15:57 who here is going to the clojure conj?

15:58 nickik: i would but its on the other side of the planet :) i hope there will be good videos

15:59 jjido: nickik: so I need to both set "next item" on my object and create an item with a back reference to it

15:59 alexyk: ninjudd: thx, will check it out (of git :))

15:59 nickik: @jjido im not an expert but could you just do a datatype that is like a concell but with 3 slots?

16:00 callen: nickik: I'm thinking about going (I'm in NYC).

16:00 amalloy: nickik: the problem is that with immutable data there's a chicken/egg situation if you want two objects to link to each other

16:00 raek: jjido: this is hard to do with immutable data structures, since they can only contain references to already constructed values

16:01 the reference loops causes the problem

16:02 nickik: @callen i think fogus sad something about that there will be official videos made

16:02 jjido: raek: I know... if I could have a assoc+construct operator it would be nice

16:02 nickik: audio and the slides would be ok too

16:02 amalloy: jjido: it's pretty ugly, but you could get similar functionality a different way. have a seq of nodes, none connected to each other, and a "global" hash-map that maps node=>next/prev pair

16:03 raek: jjido: I think it would be possible to do something like (deftype [prev-atom value next-atom] ...)

16:03 (deftype DoublyLinkedList ...

16:04 jjido: raek: and after that? Mutate it?

16:04 raek: the atoms can be used as mutable cells

16:04 jjido: raek: that was my question

16:05 raek: jjido: have you seen this? http://pepijndevos.nl/how-reify-works-and-how-to-write-a-custom-typ

16:05 * raek scrolls back a bit

16:06 raek: the resulting data structure wouldn't be very clojure-y, but it would work

16:09 jjido: raek: that is fun, but it uses "inc" and "dec"

16:09 so the fwd node and the bwd node can be calculated from current node

16:20 rhickey: so, I'm finding this distributed repl really turns into 2 pretty distinct scenarios:

16:20 repl

16:20 input is stream, can (read) from *in*

16:20 outputs streams *out*/*err* are interesting to clients

16:20 command server

16:20 each message single readable object

16:20 eval it, generate single return

16:20 no in or out streams

16:21 LauJensen: rhickey: cemerick left, dont know if what you wrote was mostly for him?

16:22 chouser: command server flags and returns exceptions?

16:22 rhickey: chouser: yes

16:23 repl would also have distinct eval returns

16:23 jjido: LOL using atom for double-linked list works, and one should not print out its value.

16:24 rhickey: nothing would preclude someone using repl mode from sending complete messages of course

16:25 ninjudd: rhickey: in my thinking about this, i came to the conclusion that if you build a command server that handles in and out streams correctly, it can serve both purposes

16:25 TeXnomancy: shoover: using double semicolons for full-line comments is a pretty long lisp tradition

16:25 chouser: the difference being repl mode doesn't try to link specific input exprs with their return values?

16:26 rhickey: chouser: no, even that is possible

16:26 chouser: jjido: finger trees allow for a double-headed list that can do a lot of what doubly-linked-lists do, and yet is persistent.

16:27 duncanm: raek: ping? i don't know how to write a multimethod that has 2 arguments

16:27 raek: that dispatches on two things?

16:27 rhickey: ninjudd: not quite, as the semantics of the input to the command server are different

16:27 jjido: (let [self (new Bilink nil (new End) (atom nil))] (swap! (:prev (:succ self)) (fn [_] self)) self)

16:28 duncanm: raek: i want to write (distance Point Point) and (distance Vector Vector)

16:28 jjido: this is my code

16:28 chouser: rhickey: so if you can send whole exprs to repl mode, and link to the return value, is the only difference whether an incomplete input expr is an error vs. queued up text?

16:28 ninjudd: rhickey: i suppose that was based on my plan to have separate input and command queues

16:29 rhickey: ninjudd: also, command servers allow for significantly more indirection - multiple servers servicing same input queue, results going to various dynamically supplied output queues, etc

16:29 raek: ,(isa? [clojure.lang.PersistentVector clojure.lang.PersistentHashMap] [clojure.lang.IPersistentVector clojure.lang.IPersistentMap])

16:29 clojurebot: true

16:29 raek: isa? does isa? recursively on the components of data structures

16:29 rhickey: ninjudd: you can't do that and deal with (do (prn "what is your name?") (println "Hi " (read))) properly

16:29 raek: so the dispatch function could return a 2-vector

16:30 duncanm: oh

16:30 rhickey: chouser: no, see ^

16:30 ninjudd: rhickey: incidentally, i think a timeout in the client before switching from command mode to input mode can solve the paste problem with separate command and input streams

16:30 rhickey: ninjudd: nope

16:31 raek: duncanm: there are some related examples on http://clojure.org/multimethods

16:31 rhickey: chouser: above re: semantics and indirection

16:31 AWizzArd: rhickey: any chance that with the patch for the updated def (which accepts a doc string) we also can get a def- ?

16:31 ninjudd: rhickey: explain

16:31 rhickey: to correctly handle repl-mode input you have to streamify the input message queue

16:32 ninjudd: rhickey: that's more of a reiteration than an explanation ;)

16:32 duncanm: raek: i've been looking at that - http://gist.github.com/605263 -- this is my latest attempt, but it doesn't work

16:33 raek: oops, there's a typo there

16:33 chouser: interesting. who uses *in* other than the repl? I'm always a bit startled when I see it.

16:34 rhickey: chouser: any interactive console app might

16:34 ninjudd: chouser: cake uses it for running bare clj scripts and also for it's piped unix filter task

16:35 rhickey: shutdown server (y/n)? ...

16:35 chouser: yeah, I know it's supported by the normal terminal repl, but mixing with (read) ...

16:35 ok ok, I'll drop that line.

16:35 ninjudd: rhickey: the way we currently unify the command server and repl server in cake is that 'repl' is a command

16:36 rhickey: ninjudd: I can't spend any more time on that command and in take turns idea

16:36 brianstamand: Does anyone know how to add my own java packages to leiningen? The code works if I manually put them in classes but when i build with lein it "cleans up" by deleting them

16:36 by "classes" i mean classes/ sorry

16:36 _rata_: hi clojurians

16:37 ninjudd: rhickey: fine, i'll drop it unless i can come up with a working prototype

16:38 defn: <Raynes> I've probably used and more than I've used or, but used if more than I've used and and or.

16:38 Raynes: defn: Ohai!

16:39 raek: duncanm: are you sure that you don't have the old defmulti lying around? defmulti has defonce semantics nowadays...

16:39 defn: hey buddy, long time no see

16:39 rhickey: so we were talking yesterday about trying to get down to 2 queues, one for in and one for out. But given this dichotomy, I think it's 3 - in (with 2 modes), results and out-streams

16:39 ninjudd: rhickey: my point is just this: whether you unify the command and repl server by having separate command and in streams or by making 'repl' a command, it can be done.

16:40 rhickey: ninjudd: aargh

16:40 raek: duncanm: couly you try (ns-unmap 'your.ns 'distance)?

16:40 ...and then revealuate the definitions

16:41 rhickey: command server runs input in atomic message mode, doesn't offer out-streams, repl runs input in stream mode, offers out-streams

16:41 defn: so today is my last day to get the early bird special for clojure-conj, eh?

16:41 * defn looks at his bank statement

16:41 Raynes: defn: I'm going to cry if you're not there when I arrive.

16:41 I was looking forward to bear hugs and such.

16:42 defn: hahaha -- not all of us can get such a sweet deal raynes!

16:42 rhickey: repl server needs a stronger notion of a session than does command server

16:42 Raynes: Ain't that the truth.

16:43 TeXnomancy: brianstamand: you mean java code you've written yourself?

16:43 defn: i wonder if i can convince the community to give an out of 25-year-old a break...

16:43 out of work*

16:43 ninjudd: rhickey: can you support running non-repl command-line scripts with stdin support using the two-mode approach?

16:45 esj: defn: could be worse, you could be stuck on the other side of the pond...

16:45 rhickey: ninjudd: I don't know what you mean by that. It's an execution server, you send it stuff to execute. Command line is out of scope (i.e. something you wrap around this if it makes sense)

16:46 Raynes: defn: You're welcome to sleep at the foot of my bed if necessary.

16:46 TeXnomancy: brianstamand: you might want to try the javac plugin, which is on the verge of getting merged into mainline; there's a thread on the lein mailing list about it

16:46 defn: esj: you've got me there -- i think i might just sell some stuff to make it happen, i figure i could unload a guitar (but that would break my heart)

16:46 Raynes: careful, i might take you up on that!

16:47 ninjudd: rhickey: i guess what i'm asking is: can you support stdin for commands sent to the command server? or are you saying that isn't important?

16:47 chouser: ninjudd: would repl mode not work for that?

16:47 rhickey: ninjudd: It doesn't care where input comes from on the client side

16:47 chouser: ninjudd: how do you decide when to disconnect currently?

16:48 rhickey: but repl mode makes it easy to stick streaming input into the client, as you don't need to partition by 'command'

16:48 ninjudd: chouser: it may, but then your code is interspersed with your data.

16:48 amalloy: when is the conj, anyway?

16:48 defn: Late Oct.

16:48 22,23rd

16:48 Raynes: 22nd - 23rd.

16:49 ninjudd: chouser: eof on stdin or the socket read stream

16:49 amalloy: actually is there just a website i can look at? i'm a 25-y/o, not out of work but not interested in spending loads of money either; might arrange to go halfsies with defn if it's convenient?

16:49 chouser: ninjudd: oh, the server doesn't disconnect when the command is done?

16:50 defn: amalloy: yeah im definitely interested

16:50 hardest part for me is going to be /getting there/

16:50 nickik: @rhickey are there going to be videos (or audio) available?

16:50 of the conj

16:50 ninjudd: chouser: the server closes the socket which causes an eof in the client

16:50 amalloy: defn: from where?

16:50 rhickey: nickik: dunno yet, someone is looking into it

16:50 defn: i have class on thursday and my car is going to be angry at me if i put too many miles on it

16:50 brianstamand: TeXnomancy - Thanks. And yes, that's what I meant :)

16:50 defn: amalloy: Wisconsin

16:50 chouser: ninjudd: when does the server decide to close the socket?

16:50 esj: nickik: I was just talking to relevance about that yesterday. They're trying to arrange it, and looks like it may be possible.

16:51 chouser: amalloy: http://clojure-conj.org/

16:51 defn: ty chouser

16:51 amalloy: defn: heh. can't help you much with getting there; i'm coming from san francisco

16:51 defn: amalloy: flying i assume?

16:51 amalloy: i was planning to walk, but i guess your idea is better

16:52 defn: haha

16:52 nickik: the titels of the presentations alone make me dribble but there is know way I can fly to america

16:52 lancepantz: that's like 1 5-6 day drive

16:52 joly: esj: nickik: video or audio/slides would be awesome

16:52 ninjudd: chouser: when the code is done executing, in the case of the 'repl' command, that happens when there is an eof on the client's stdin (which causes the client to close the socket write stream).

16:52 nickik: @esj cool would be great

16:53 defn: lancepantz: haha ive done Wisconsin to New York, and Wisconsin to Alaska -- you can do it in less, but it requires an intense sense of purpose

16:53 esj: nickik: its apparently mucho expensive. I said I'd be willing to put cash towards it, and that I'm probably not the only one. Getting the videos would be a major win. rhickey's videos were a large part of what drew me into clj, and I doubt I'm alone.

16:53 nickik: audio and slides are sufficien

16:54 @esj i wanted to pick up scala when I discoverd the videos :)

16:54 Chousuke: I hope the questions will be audible too :P

16:54 esj: Chousuke: always somebody wants the impossible :)

16:54 defn: I just want to see what all of the Clojurians are wearing! Will there be a red carpet?

16:54 nickik: @esj just audio should be expensive, would it?

16:55 Chousuke: In most presentation recordings I watch/hear the QA session goes like "... yes ... "oh good question <blah blah>" ... "no" ..."

16:55 defn: Chousuke: good presenters restate the question

16:55 Chousuke: It's easy to forget though.

16:55 defn: *nod*

16:55 esj: nickik: i have no idea, relevence say so, and they strike me as not being in the habit of being incorrect.

16:55 defn: amalloy: let me know what you decide, will you?

16:56 we could split a room -- that'd cut costs a bit

16:56 nickik: they could open a pool to raise money for it. I would pay for them and I think a lot of people from europ would

16:56 amalloy: defn: yeah, that was the main thing i was thinking. but jeez flights to NC are a lot longer and more expensive than flights to denver :P

16:57 nickik: *too

16:57 anonymouse89: I'm running into a lack of understanding of namespaces. For my purposes I have a namespace foo.core which contains -main. I need main to take stuff defn'd in an external file, put it into foo.a namespace.

16:57 esj: nickik: that's what I expressed, and I think they'll do that if they can't arrange it on their own bat. Can't hurt to let them know you'd be keen, though...

16:58 amalloy: defn: yeah, sorry, i don't think i want to spend $1000 and two work days on the conj

16:58 anonymouse89: right now I'm trying to load-file and then intern the function into foo.a, but this is not working (java.lang.Exception: Can't create defs outside of current ns)

16:59 nickik: @esj lets hope for the best. thx

16:59 Raynes: amalloy: Sneak in in ninjudd's luggage.

16:59 ninjudd: carry on

17:00 amalloy: oh, ninjudd lives near sf?

17:01 nickik: @anonymouse89 you want to define something in a other namespace? You should do that. Whats the usecase?

17:01 ninjudd: amalloy: no. encino

17:01 amalloy: damn. i was hoping i could just stalk you when i want more cake features

17:03 lpetit: rhickey: just for knowing, would you accept a patch to clojure to add to clojure's META-INF/MANIFEST.MF the relevant OSGi meta-data (static parts such as Export-Package, Symbolic name, etc. ; and dynamic part for the bundle version) ?

17:03 anonymouse89: nickik: it's a genetic programming system. The user is defining an error-function in an external file and then passing the path to that file as an argument.

17:03 clojurebot: namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

17:03 lpetit: nothing's ready yet, just asking to know how you would feel with such a patch

17:08 nickik: @annonymouse89 the new file should become a new namespace?

17:10 anonymouse89: nickik: the user is giving me a fn written in clojure in its own file without a namespace declaration. I need that to be put into a specific namespace where it will be accessible by other functions that use it.

17:11 rhickey: lpetit: are they completely generic (i.e. not per app)?

17:12 lpetit: Good point.

17:12 They would be generic, or not be, indeed.

17:12 chouser: anonymouse89: try (binding [*ns* (the-ns 'users-ns)] (load-file ...))

17:13 anonymouse89: you'll need to set up that namespace first, perferrably with the ns macro

17:14 nickik: @chouser the version i was thinking about wouldn't have been that clean :)

17:25 AWizzArd: definlined functions can be used first-class values yes and go into function positions yes? This is the difference to macros.

17:26 KirinDave: Hum

17:26 When writing a macro for a def form

17:26 What's the idiom for inserting metadata on the defined symbol?

17:26 ^{...} doesn't seem to work

17:26 AWizzArd: KirinDave: with-meta

17:26 KirinDave: Ah

17:26 AWizzArd: http://github.com/clojure/clojure-contrib/blob/maven/src/main/clojure/clojure/contrib/def.clj#L39

17:27 nickik: http://99-bottles-of-beer.net/language-dylan-225.html <- can I do something like this (the <integer> / 1 multimethod part) in clojure without making a specific dispatch value for that case?

17:31 raek: KirinDave: ' ^{...} foo ; this also works

17:31 KirinDave: raek: In a macro?

17:31 It is not working...

17:31 raek: ah

17:31 sorry

17:32 when you have the symbol as a value, the with-meta is the way to go

17:32 my example was for symbol literals with metadata

17:32 anonymouse89: chouser: thanks, not sure if that's exactly what I need but it's given me ideas

17:33 AWizzArd: for literal symbols it should work, yes

17:34 raek: ^{...} ' foo ; puts metadata on the (quote foo) list

17:34 duncanm: raek: ah, ns-unmap fixed it

17:35 AWizzArd: Is it the compiler which expands definlines?

17:37 amalloy: nickik: i don't think so

17:38 lancepantz: if i (use 'foo) in user, then running (ns-refers 'user) should contain mappings for the fns in foo, correct?

17:42 nickik: @amalloy would be a cool.

17:43 In dylan you don't have to say (defmulti ....) every time you can just wirte (defmethod ...) and if there is no multimethod it creats one

17:43 erikcw1: was gen-and-load-class removed from 1.2?

17:46 amalloy: nickik: but (defmulti) is more flexible; you specify a dispatch function, which could be simple equality like in this case, or could be based on class (more common), or on...size of the input collection, or whatever

17:49 nickik: amalloy: yes but would it just be handy if there was a standerd function provieded (if a stupid on like class or a complicaded one could be decided later)

17:53 amalloy: nickik: what if the defmethod were parsed and compiled before the defmulti were ever created? it's easy to imagine that causing problems

17:55 ie the compiler defaults to a defmulti on class, then assigns your method to it; then someone defines a multi with a similar name; i don't think it's reasonable to expect the compiler to dive into code belonging to another class/file and undo some bindings

17:55 Nathan2: Hey, I'm trying to define a function that gives a nested iteration like the for-macro. I can't use for because I don't know ahead of time how many sequences I'm looping over. I solved it with recursion, and I wonder if that's the best/most idiomatic way.

17:56 My attempt: http://paste.lisp.org/+2GSI

18:00 amalloy: nathan: my guess is no, there must be a better way to do this, but i'm not sure what it is. with so many nice language constructs having to do recursion by hand is a warning sign

18:01 AWizzArd: ,(instance? Long)

18:01 clojurebot: false

18:03 amalloy: not very helpful, i know; i'll have a go at fixing it up to make your current solution more idiomatic, at least

18:06 Nathan2: That's what I felt as well! But I couldn't think of a way without resorting to a macro that leveraged 'for'

18:07 jjido: ,(list "a")

18:07 clojurebot: ("a")

18:07 jjido: (conj "a" nil)

18:07 ,(conj "a" nil)

18:07 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IPersistentCollection

18:07 jjido: ,(cons "a" nil)

18:07 clojurebot: ("a")

18:09 joly: ,(conj nil "a")

18:09 clojurebot: ("a")

18:09 jjido: joly: ok I got it backwards ;)

18:09 joly: jjiddo: :)

18:10 amalloy: Nathan2: the first/rest thing is way un-idiomatic, particularly. that looks a lot better with desctructuring

18:12 Nathan2: amalloy: That's true.

18:15 amalloy: hm, i seem to have broken emacs's automatic gisting

18:15 Nathan2: I was trying to think of a way to use reduce, but I still feel that it would require something recursive-esque... like reduce returing functions that further reduce... or something like that.

18:16 amalloy: http://gist.github.com/605420 is a (horribly-indented) version that uses destructuring

18:16 it's not tested, either; i just tried to quickly add in destructuring

18:17 alexyk: ninjudd: can you run cake client on one box and jvm on another?

18:18 e/g/ eval'ling from TextMate on a puny mac in a monster JVM on a gigaserver

18:18 ninjudd: currently, no. but you can implement it if you want :)

18:19 alexyk: the hard part will be stopping and starting the jvm remotely

18:19 alexyk: ninjudd: yeah

18:20 how about li'l popups "tell servant to restart jvm"

18:20 Chousuke: net send ... :P

18:20 alexyk: I meant "tell intern"

18:21 * alexyk senses slime crowd smirking like George W.

18:21 alexyk: over their tidy ssh tunnels

18:22 lancepantz: alexyk: so are you using textmate for clojure dev now?

18:23 alexyk: ninjudd: now that I have a monolithic jiraph jar, how can I import jiraph.tc as tc? *rusty*

18:23 lancepantz: yep, I always prefer TextMate these days

18:24 although I used Emacs since 1994... "When facts change, my opinion changes; and yours, sir?"

18:24 ninjudd: alexyk: you mean? (require '[jiraph.tc :as tc])

18:24 Nathan2: amalloy: That version does look a lot neater.

18:24 alexyk: ninjudd: I used to have that and it fails for some reason now... let me see

18:26 amalloy: Nathan2: but does it work?

18:28 ssideris: hello, does anyone know if leiningen supports "source" dependencies?

18:28 as in non-jarred clojure files that are not in the procject's dir structure

18:28 alexyk: ninjudd: looks like no jiraph__init.class or jiraph.clj in jiraph-0.5.0-SNAPSHOT.jar built by cake install?

18:30 ninjudd: alexyk: are you in the deftype branch?

18:30 alexyk: yep

18:30 ninjudd: there is no jiraph or jiraph.tc in that branch

18:30 Nathan2: amalloy: Yep, it looks to work the same: (take 4 (nested2 (range) [:a :b])) ----> ([0 :a] [0 :b] [1 :a] [1 :b])

18:31 ninjudd: if you want the old jiraph.tc ns, use master

18:31 otherwise, the interface has changed quite a bit

18:31 alexyk: ninjudd: that explains it :) So: I actually use tokyo cabinet part of jiraph. How do I do that now?

18:32 Nathan2: I tried looking at the source of the 'for' macro... it's pretty hairy.

18:32 ninjudd: alexyk: jiraph.tokyo-database, but like i said, it has changed quite a bit

18:32 alexyk: ninjudd: ok...

18:33 ninjudd: alexyk: uses protocols. the protocol for tokyo-database is in jiraph.byte-database

18:33 alexyk: ninjudd: should master cake install under clojure 1.2?

18:33 meaning master of jiraph cake-install...

18:34 ninjudd: alexyk: it is on clojars, if that's what you mean

18:35 alexyk: ninjudd: and playing nicely with clojure 1.2?

18:35 ninjudd: alexyk: not sure. i haven't tried

18:35 alexyk: ok

18:38 nickik: Why is this not working when i pass a string? http://paste.lisp.org/display/115075

18:42 damn! that should work!

18:46 brianstamand: Why does lein try to run my jar after it jars it?

18:47 Or I should say before. Since it isn't creating the jars :p

18:48 Whenever I include a :main it does it

18:51 raek: nickik: try (ns-unmap 'the-ns 'the-var)

18:52 and then reavluate the defmulti

18:53 defmulti now has defonce semantics...

18:56 nickik: @reak I see i tought its something like this the function is now called foo :)

18:56 why was that added=

19:00 @raek this is the final version but know the bunny stuff doesn't work http://paste.lisp.org/display/115078

19:00 the type stoff works

19:08 amalloy: nickik: the nested ifs there are weird. i don't know much about multimethods, but surely this should be a cond

19:08 (cond (seq rest) (...) xspec xpec :else (class x))

19:11 nickik: but that should matter that just a other way of coding it (the better one)

19:13 amalloy: yes

19:13 like i said, not exactly a multimethod pro here

19:26 nickik: http://gist.github.com/605491 should also be identical but even shorter and clearer, but for some reason the :as thing is failing to compile. anyone know why?

19:26 alexyk: ninjudd: interesting setup difference, on mac cake proto instaleld protoc fine, on linux says: [install-protoc] sudo: sorry, you must have a tty to run sudo

19:26 I do have sudo, but it thinks it's not in a tty

19:27 I can run sudo cake proto from command line, but cake still wants sudo

19:27 ninjudd: alexyk: mind opening an github issue on clojure-protobuf with details?

19:28 alexyk: ninjudd: sure if it's not my setup

19:28 nickik: @amalloy can you use :as after &? Somebody was faster then me (and better) look at it here http://stackoverflow.com/questions/3834263/is-clojures-multi-method-dispatch-truly-superior-say-to-what-i-can-do-in-pytho

19:28 ninjudd: alexyk: sounds like a real bug

19:29 alexyk: ninjudd: my sudo is also weird on that system, not remembering my password for a few minutes

19:29 ninjudd: hmm

19:29 alexyk: well it does in fact

19:29 so it's cake

19:30 ninjudd: alexyk: just install protoc manually for now. it will probably be a few weeks before i'll find time to figure out a workaround

19:30 amalloy: nickik: you can use :as after &; the same binding works when i evaluate it in a let[], but fails in a defn[]

19:31 nickik: can't say why

19:32 Joreji: Hey guys, what do I have to do in order to have a record be a clojure.lang.Sequential?

19:32 amalloy: nickik: i see why; one of the comments in the link you gave me shows the right way to do it

19:32 alexyk: ninjudd: did manual install, it still wants to sudo... how does it check for protoc? simply in path?

19:33 Joreji: Is there some way to provide Sequential-like behavior (which is... according to repl-utils/show... no behavior at all...) to a record?

19:33 ninjudd: alexyk: yes

19:33 alexyk: ninjudd: taking path from current shell or login?

19:34 ninjudd: shell

19:34 amalloy: nickik: http://gist.github.com/605501 shows the right way to use :as

19:37 nickik: ah ok good to know

19:37 amalloy: Joreji: just (seq myrec), right?

19:37 nickik: so im going to bed

19:37 night

19:37 amalloy: that gives you a seq of key/value pairs

19:38 Joreji: amalloy: but: (sequential? myrec) => false

19:39 amalloy: I would like to be able to use flatten on a record which has children. But flatten filters out everything which is not a sequantial.

19:40 ohpauleez: what's the correct way to do (not (nil?))

19:41 I feel like there's a more idiomatic way to do it, but I'm drawing a blank

19:43 cemerick: rhickey: ping

19:43 rhickey: cemerick: hey

19:44 cemerick: rhickey: Evening :-) Do you have a sense for what your time horizon is on mqREPL?

19:45 rhickey: cemerick: I babbled a bit earlier

19:45 ...

19:45 cemerick: I can go check the logs

19:45 rhickey: it's a bit more refined now, essentially I see two pretty distinct use cases

19:45 lancepantz: so is nREPL now mqREPL or are you continuing work on nREPL as well cemerick ?

19:45 rhickey: command server and repl server

19:46 nrepl as it stands is kind of a hybrid

19:46 repl

19:46 input is stream, can (read) from *in*

19:46 outputs streams *out*/*err* are interesting to clients

19:46 needs a stronger notion of session (for *in*/*out* association)

19:46 context survives from one call to next

19:46 e.g. (def x 42), *e *1 *2. *ns*

19:46 set!s of bindings, *ns*

19:46 command server

19:46 each message single readable object

19:46 eval it, generate single return

19:46 eval in what ns?

19:46 no in or out streams

19:46 or per server, not per session?

19:46 or capture output only during command execution?

19:46 flush and drain

19:46 no session notion

19:46 no enduring context

19:46 except changes to global namespaces

19:47 cemerick: lancepantz: things are up in the air at the moment

19:47 rhickey: I think what you've got could be repl server if it handled *in* better. Maybe I'll just let tool users force you into that :)

19:47 but a command server really should have no context

19:48 cemerick: I think all you need to do is get away from command is in a single message

19:49 stick a little streamifier on input that tracks message ids

19:49 cemerick: Having the side channels for the streaming bits is a fine enhancement to make to what's there now.

19:49 But it absolutely must retain discrete return values.

19:49 rhickey: when repl erad returns, it can grab the last id from the special instream, then bind it to *in* and eval

19:49 read

19:50 cemerick: yes, discrete results

19:50 could interleave *err* and *out* fragments

19:50 for async output

19:50 cemerick: rhickey: that's what I was implementing yesterday morning

19:50 rhickey: I think *err* and *out* should be separate

19:51 cemerick: agreed

19:51 rhickey: in any case, as I think more about command server, I think it would probably like to leverage more of the mqs

19:51 for instance there's nothing precluding multiple command servers consuming same queue, and dynamic reply-to queues for results

19:52 cemerick: That's decidedly out of scope for me, at least right now.

19:52 rhickey: so, I think you should proceed with nrepl and I'll play around with command server on stomp/mq

19:52 they are different, and a command server will never be a suitable repl given the lack of context

19:52 cemerick: rhickey: your positions on protocols and such notwithstanding?

19:53 rhickey: whether you switch to stomp for your API is a separate question, but I think the stomp for retargeting over mqs is not as important as stomp for transport independence and free clients

19:54 in any case, something that wanted to be both a repl server and command server would have to have two distinct modes for the input queue, and separate queues for results and outstreams

19:54 half of which wouldn't be used for each use case

19:55 so repl server and command server

19:56 but I think you should evaluate stomp strictly with the repl server use case in mind, and see if it makes sense to you

19:56 cemerick: It seems that "command server" is a context-free repl server, suitable for use over MQs.

19:56 rhickey: context free and different input semantics

19:57 and session-free

19:57 and proper destination notion, for reply-to

19:57 cemerick: I'd group all the issues around streams and connection state/session under "context", but sure.

19:57 rhickey: so, connection-free really

19:58 Joreji: Common guys, there must be some way to have (sequential? my-rec) return true?

19:58 rhickey: it's quite different when you put it all together

19:58 cemerick: Indeed.

19:58 Funny how we start and finish this thing in roughly the same positions where we started, at least from where I sit. :-)

19:59 rhickey: as you your current wire protocol, I have to admit to really not liking it. I don't think you serve non-Clojure clients by making it newline terminated drivel

19:59 I wouldn't be afraid to pass/return Clojure data literals, they aren't hard to construct in any language that has strings

20:00 cemerick: sheesh

20:00 rhickey: the nthe question is do you put that payload in a standard protocol like stomp

20:00 sorry, dribble

20:00 not drivel

20:00 :)

20:01 cemerick: ironically enough, stomp is newline- and NUL-terminated

20:02 rhickey: after all, that is what you are going to get back, right?

20:02 cemerick: what, clojure data literals?

20:02 rhickey: cemerick: but don't get confused about the headers (for the server) and the body (for us)

20:02 cemerick: yes

20:03 * cemerick was just talking mano a mano re: qualities of protocols

20:03 cemerick: anyway

20:04 rhickey: http://gist.github.com/605527

20:06 i.e. structured messages, the stomp frames are for stomp

20:06 cemerick: so all clients would need to have a clojure reader impl?

20:06 rhickey: cemerick: that's what I asked before, isn't that what they are going to get back anyway?

20:06 clojure data?

20:07 cemerick: no, they're getting strings back

20:07 rhickey: strings with what in them?

20:07 cemerick: results from *out*, *err*, and (pr-str last-value)

20:07 none of which are guaranteed-readable

20:08 rhickey: cemerick: I guess if all they are doing is client-side printing, still thinking about programmatic use...

20:09 anyway, I'll get my use case out of your hair, and trust you and the tools guys to agree on something great

20:09 cemerick: rhickey: no, tools would be sending expressions that they expect to return readable forms

20:09 That's a client issue, though.

20:10 rhickey: you don't need a full reader to read {:result "string" :out "string"}

20:11 but why not make it easiest for Clojure devs?

20:11 cemerick: Clojure devs I'm not worried about at all -- they'll be using the provided client anyways.

20:12 rhickey: cemerick: ok

20:13 well, the important think is that nrepl should proceed, and focus on repl, not leaving out any human needs

20:14 I've gotten far enough in the design to see that command server is a different beast, mqrepl is likely to fall by the wayside unless it falls out of your work

20:15 sorry for the distraction

20:33 defn: Does anyone know if clojure-conj registration is refundable?

20:35 Also I remember seeing discounted room rates for conference-goers -- do those rates still exist or have they all been sold?

20:35 Raynes: defn: They exist through October 8th, I believe.

20:36 defn: Ah I was missing the link -- found it

20:36 Thanks Raynes

20:37 I think I'll get 2 doubles just in case there are any smoking hot femme-Clojurians

20:38 Thinking about that though, why would I want 2 doubles?

20:38 * defn lives in the flintstones and I Love Lucy era, apparently.

20:38 amalloy: defn: to lull them

20:38 defn: amalloy: haha

20:39 "No it's cool! There's /two/ beds! Not creepy!"

20:39 amalloy: because they wouldn't worry at ALL about sleeping on your other bed...

20:39 Raynes: Alan told me he booked a room with two 'Queen' beds. I think he was overtired that night. I'm fairly certainly they don't have double queens.

20:39 Like double double isn't good enough for me.

20:39 defn: Raynes: I know lol -- I sleep on a full with my current girlfriend because we're poor and have no space

20:40 Raynes: I sleep on a horrid twin sized bed with bent bars underneath. My cousin spent time in Iraq and pointed out that the bed feels exactly the same as what he slept on during that time.

20:40 defn: I can't imagine being like: "I'm sorry, but queen is not large enough"

20:40 Raynes: haha, ouch

20:41 Raynes: I'd put the mattress on the floor and sleep there if I wasn't terrified of spiders and mice.

20:41 defn: I've flipped my mattress to try and get back that "new mattress feel"

20:41 no dice.

20:41 Raynes: Not really scared of either of them, but they're much more intimidating when you're asleep.

20:41 Roll over on a mouse and wake up with rabies.

20:42 defn: I once was in Belize on a little Caye out in the middle of the ocean

20:42 I had a cockroach half the size of my mind put a couple legs in my mouth

20:42 s/ming/hand

20:42 grr, mind*

20:42 Raynes: ._.

20:42 I was about to comment on your excruciatingly tiny mind.

20:42 defn: I was about to challenge you to a duel.

20:43 Raynes: "[

20:43 :p*

20:43 dnolen: so what was the verdict on an inclusive take-while again?, speaking of which, keep is really cool.

20:45 defn: dnolen: care to explain keep?

20:46 dnolen: ,(first (keep [nil nil nil 1 nil]))

20:46 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$keep

20:46 defn: (doc keep)

20:46 clojurebot: "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects."

20:46 dnolen: (first (keep identity [nil nil nil 1 nil]))

20:46 ,(first (keep identity [nil nil nil 1 nil]))

20:46 clojurebot: 1

20:46 defn: (map keep [nil nil nil 1 nil])

20:47 (keep true? [nil 1 true nil])

20:47 ,(keep true? [nil 1 true nil])

20:47 clojurebot: (false false true false)

20:47 defn: cool.

20:47 amalloy: ,(map #(keep identity %) [nil 1 nil nil 2] [3 nil])

20:47 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: sandbox$eval8265$fn

20:48 amalloy: ,(map #(keep identity %) [[nil 1 nil nil 2] [3 nil]])

20:48 clojurebot: ((1 2) (3))

20:48 defn: that's just magix

20:48 magic

20:48 * defn can think of more than one place he'd like to use that

20:49 Raynes: That's awesome.

20:49 defn: it'd be neat for optional args, i think

20:51 dnolen: ,((fn [& [x & rest :as all]] [x rest all]) [1 2 3])

20:51 clojurebot: [[1 2 3] nil ([1 2 3])]

20:52 dnolen: oops

20:52 ,((fn [& [x & rest :as all]] [x rest all]) 1 2 3)

20:52 clojurebot: [1 (2 3) (1 2 3)]

20:52 dnolen: also awesome

20:52 defn: ,(let [args [nil 1 "foo" "sometimes" nil nil 100]] (keep identity args))

20:52 clojurebot: (1 "foo" "sometimes" 100)

20:53 defn: ,(class "foo")

20:53 clojurebot: java.lang.String

20:53 chouser: ,(class (class "foo"))

20:53 clojurebot: java.lang.Class

20:53 defn: ,(class (class (class "foo")))

20:53 clojurebot: java.lang.Class

20:54 defn: if you do anymore of those the world explodes.

20:54 or something...

20:54 chouser: are you going to check out hillary mason's talk at strangeloop?

20:54 i think that looks like my highlight next to seeing Guy Steele

20:56 and of course ill be going to your talk :)

20:59 amalloy: ,(nth (iterate class 1) 1000)

20:59 clojurebot: java.lang.Class

21:00 amalloy: defn: no explosions!

21:00 defn: I don't believe it.

21:00 amalloy: truly a miracle of nature

21:00 defn: Now verbalize what's going on there in your head. That will give you schizophrenia at least I think.

21:01 amalloy: anyway goin home now. ta ta

21:01 defn: amalloy: you get your ticket for clojure-conj?

21:01 amalloy: im about to book a room, wondering if you want to split a room for a couple nights...

21:02 amalloy: defn: afraid not; i mentioned earlier that i decided not to go, but i guess you missed it

21:02 defn: ah yeah, i had a kernel panic :X

21:02 amalloy: haha

21:02 bye

21:02 defn: amalloy: if you change your mind let me know, im getting 2 doubles regardless

21:02 ciao

21:06 Joreji: What's the difference between clojure.lang.ASeq and clojure.lang.ISeq?

21:10 defn: Joreji: someone is probably going to correct me but I think it has to do with rest, vs next

21:10 * defn opens up the clojure.jar

21:11 Joreji: Ah okay. I was hoping for ASeq to be a protocol. Too bad.

21:13 cais2002: (good morning)

21:13 defn: => true

21:13 cais2002: is there an existing function that could do (index-of [1 2 3 6 5] 6) => 3

21:14 defn: ,(get [1 2 3] 2)

21:14 clojurebot: 3

21:15 Joreji: ,(.indexOf [1 2 3 6 5] 6)

21:15 clojurebot: 3

21:16 Joreji: cais2002: Found that using auto-complete-mode, in case you are using emacs.

21:21 cais2002: joreji: thanks. using vim

21:22 defn: cais2002: sorry i misunderstood

21:22 cais2002: aikes, I thought defn is a robot ...

21:23 defn: clojurebot: skynet?

21:23 clojurebot: I will become skynet. Mark my words.

21:23 Raynes: -> (first (keep-indexed #(when (= 6 %2) %) [1 2 3 6 5]))

21:23 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: (#'clojure.core/keep-indexed)

21:23 Raynes: Bleh

21:24 ,(first (keep-indexed #(when (= 6 %2) %) [1 2 3 6 5]))

21:24 clojurebot: 3

21:24 defn: what breaks the sandbox there?

21:24 Raynes: keep-indexed.

21:24 It's just not whitelisted.

21:24 defn: ah

21:26 chouser: defn: yeah, Hillary's talk looks interesting

21:28 defn: her tweets are really interesting all the time

21:28 so i figure it'll be cool

21:29 for instance, she took a few days of tweets and showed the distribution of possible spellings for "fuck" :D

21:29 "FuuucuuuuuuuCCCKKKKK" 5, "FUCK" 10000, etc. heh

21:31 chouser: hm, edifying

21:31 defn: obviously she's doing God's work

21:51 brianstamand: .

21:52 ossareh: chouser: you'll be loving everyone in that case, http://www.skynetlovesyou.com/

22:03 pjb3: trying to install clojure-contrib from master

22:03 FAIL in (writing-attributes) (test_jmx.clj:79)

22:04 chouser: ossareh: I don't get it.

22:19 jk_: does this code create a new set every time i call it? (defn jar? [file-name]

22:19 (let [jar-types #{"jar" "zip" "rar" "war" "ear"}]

22:19 (boolean (jar-types (extension file-name)))))

22:20 _rata__: hi

22:31 ossareh: chouser: it was lame :)

22:35 chouser: jk_: let's find out!

22:36 ,(let [f (fn [] #{"one" "two" "three"})] (identical? (f) (f)))

22:36 clojurebot: false

22:36 jk_: bummer

22:36 :)

22:36 chouser: hm, I'm mildly surprised

22:36 jk_: chouser: nice way to test it though

22:37 chouser: well, it means the root node is different

22:37 it doesn't prove there's no internal sharing

22:37 clojurebot: sharing is caring

22:37 jk_: i see :)

22:38 chouser: but if i plan to do something like that, i should def the set ahead of time?

22:38 chouser: hmmm

22:39 jk_: .1

22:39 .(1)

22:39 waht triggers the clojurebot?

22:39 hiredman: chouser: why would they not be the same?

22:39 er

22:40 why would they be?

22:40 the read in set is the same, but it has to be evaluated/created each time the function is called

22:40 chouser: once read, why wouldn't it just return the thing that was read

22:40 TheBusby: jk_: ,(printfln "comma's trigger the bot I think")

22:40 jk_: ,(println "comma's trigger the bot I think")

22:41 nmind...

22:41 jk_: lol

22:41 hiredman: because if it did it like that functions like (fn [x] #{x}) would return a set with the symbol x in it

22:46 jk_: hiredman: doesn't it actually do that though? doesn't the function argument simply shadow any def from the outer scope? just askng...

22:46 hiredman: ah

22:46 no

22:47 I mean it would return literally the symbol x inside a set

22:47 passing it through from the reader like chouser is suggesting is what quote does

22:48 chouser: ,(let [f (fn [] '#{"one" "two" "three"})] (identical? (f) (f)))

22:48 clojurebot: true

22:48 chouser: ha! fascinating

22:48 hiredman: all the collection types have a static create method that takes an array

22:48 jk_: .(true)

22:50 hiredman: so I imagine the emmited byte code pushing the functions args on to the stack, makes an array, and then calls the static method

22:50 and the static method doesn't know it's recreating the same thing again

22:52 jk_: hiredman: umm you mean it's making an array of the stuff in the set literal that from from the function body? and then calling the method. there is no arg

22:53 wow that was seriously mangled

22:53 hiredman: oh, the jvm is a stack machine so args are most implicit

22:53 mostly

22:53 jk_: ok, i see what you're saying

22:54 hiredman: you build up stuff on the stack then invokestatci Some.method some-arg-types some-return-type

22:54 which is really weird

22:54 the types are arguments but the values are implicit

22:54 but the types aren't really arguments for the method, they are for linking the correct method

22:56 chouser: I guess it would have to detect at compile time that the contents are all constants

22:56 a lot of work to just save the user from a '

23:01 amalloy: chouser: plus it would make it impossible to get the opposite behavior. the way things are now, you can either quote it, or close around the value you want to be constant, right?

23:05 jk_: so the answer to my original question is yes, it's creating a new set every time unless i quote it in the let so the reader doesn't evaluate it. is that correct?

23:07 amalloy: jk_: it seems that way, but i wouldn't be surprised to learn that that's an implementation detail you shouldn't rely on

23:08 jk_: amalloy: but i have to rely on it if i need to understand the program behavior. why would i want to create potentially millions of objects when it's completely unnecessary?

23:09 amalloy: ,(let [c #{1 2 3}, f (fn [] c)] (identical? (f) (f)))

23:09 clojurebot: true

23:09 amalloy: *that* you can rely on for sure

23:09 i wouldn't be 100% confident about the quoting trick unless i read docs that said it works

23:10 jk_: ,(1)

23:10 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

23:10 amalloy: ,1

23:10 clojurebot: 1

23:10 jk_: aha! it's the comma :)

23:10 amalloy: yes

23:10 ->(inc 10)

23:10 sexpbot: ⟹ 11

23:11 jk_: or arrow :)

23:11 amalloy: if you want to double-check, you can pit the bots against each other :)

23:12 jk_: amalloy: so your second formulation works because you closed over the set that was created without the quote. i really don't see anything different there than what hiredman was saying

23:12 passing it through the reader does actually create the set

23:13 amalloy: that is to say, your demo doesn't really address the quote question at all

23:13 amalloy: no, it doesn't. the quote question seems to work now, but i have no reason to think it's guaranteed

23:13 unless i can find that in some docs

23:14 jk_: amalloy: i should add... according to my interpretation as a clojure newbie! not trying to pass myself off as very knowledgeable :)

23:15 laurus: Why is a floating point number rounded in operations rather than a java.math.BigDecimal number?

23:15 Er, when a java.math.BigDecimal number is not?

23:15 amalloy: jk: i'm just saying that the language definitions guarantee that if you close around a reference, that reference will stay the same; i don't know the language well enough to know if they specify that this works for constructing quoted values also

23:15 ninjudd: chouser: ping

23:16 amalloy: laurus: because floating-point numbers followw the IEEE floating-point spec, which says they only get to use N bits of precision

23:16 BigDecimal is a class for when you want more than that

23:16 laurus: amalloy, what determines that N?

23:16 amalloy: laurus: http://en.wikipedia.org/wiki/IEEE_754-2008

23:18 if floating-point numbers never got rounded, you couldn't divide 1 by 3; defining a standard point at which they round improves portability and consistency

23:18 laurus: amalloy, only if you demand that 1/3 become a decimal, right?

23:19 amalloy: and that's what floating-point numbers demans

23:19 if you want something else, use ratios:

23:19 ,(/ 1 3)

23:19 clojurebot: 1/3

23:19 laurus: So why isn't everything just BigDecimal then?

23:20 hiredman: bds are slower than primitives

23:21 laurus: I'm kind of not sure when to use each one

23:21 jk_: ,(:a '{:a "aaa" :b "bbb"})

23:21 clojurebot: "aaa"

23:21 hiredman: floating point is icky so never

23:21 laurus: hiredman, so instead of 1.25 I should always write 1.25M?

23:21 jk_: that just doesn't seem right. :\

23:21 laurus: For example

23:22 amalloy: laurus: it depends on what you want. why is 1+1=2 instead of 11? either one is an operation that can be useful

23:22 hiredman: laurus: are youwriting a lot of floating point literals?

23:22 amalloy: if you want precision, use BDs or ratios

23:23 laurus: amalloy, right, that makes sense

23:23 hiredman, no, I'm reading _Practical Clojure_ and looking over my question marks :P

23:23 amalloy: laurus: but yeah, as hiredman implies, if you're using a lot of floating-point numbers then you'll probably know already what kind you want. if not, it usually won't matter

23:24 jk_: can someone explain why that works? (:a '{:a "aaa"}) how can that work when the quote should keep there from even being a map to work against?

23:24 amalloy: jk_: the quote just prevents anything inside it from being treated as a function

23:24 laurus: Thanks for the explanation of something so basic to programming :)

23:25 amalloy: (or as a variable)

23:25 ,(let [a 10] ['{:val a} {:val a}])

23:25 clojurebot: [{:val a} {:val 10}]

23:25 laurus: ,(re-matches #"[a-zA-Z]* " "test123")

23:25 clojurebot: nil

23:25 abedra: is there another way to read metadata on a multimethod that I am missin

23:25 missing

23:25 jk_: amalloy: oh, ok. i see. it still gets evaluated

23:25 laurus: I don't understand why that doesn't match the string "test".

23:25 amalloy: laurus: you left a space after the *

23:26 abedra: other than (meta (var foo))

23:26 laurus: amalloy, yeah, I think that's a typo in the book

23:26 amalloy: ,(re-matches #"[a-zA-Z]*" "test123")

23:26 clojurebot: nil

23:26 amalloy: hm. i guess i've never used re-matches

23:27 laurus: amalloy, "Returns the match, if any, of string to pattern, using java.util.regex.Matcher.matches()"

23:27 So that's a standard Java regex matcher apparently

23:28 amalloy: yeah, but it's been like five years since i used java for regexes :P

23:28 laurus: Me too ;)

23:28 Well, in my case, never :P

23:28 I'm so used to the Python regexs, which I think are basically the same as Perl and JavaScript

23:28 amalloy: http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Matcher.html#matches%28%29

23:29 matches() tests whether the whole thing matches

23:29 laurus: Ah, "the entire input sequence"

23:29 I mean, it's kind of obvious from the behavior it just showed, it's just hard to believe for someone steeped in the Perl-style regexes

23:29 amalloy: use find() instead

23:30 ,(re-find #"[a-z]+" "12test123")

23:30 clojurebot: "test"

23:31 amalloy: laurus: java uses PCRE. you won't find any surprises in how the regexes behave, just in the API to get at them

23:32 laurus: amalloy, oh, I see, thank you for that clarification

23:32 amalloy: (and since you're doing it from clojure, the APIs were going to be a surprise anyway!)

23:33 laurus: :)

23:33 amalloy: heh, there is something comically broken about lein repl when i boot into cygwin

23:34 it works fine, and then when i C-d to get out of the repl, the prompt appears but refuses to accept input

23:35 laurus: Heh. I had a similar problem with a shell in Emacs I think

23:36 amalloy: i could boot into ubuntu but i'm already using windows...and for some reason the unix server at work isn't accepting ssh, so i'm stuck with cygwin

23:36 laurus: :|

23:38 ,(re-groups (re-matcher #"[a-zA-Z]*" "test"))

23:38 clojurebot: java.lang.IllegalStateException: No match found

23:38 laurus: What's up with that?

23:40 amalloy: you need to ask the matcher to match something first

23:40 laurus: Ah, thanks.

23:41 I'm probably too tired to be doing this :P

23:41 "returns the groups from the most recent find/match" went right over my head :|

23:41 amalloy: ,(let [m (re-matcher #"a" "a")] (.lookingAt m) (re-groups m))

23:41 clojurebot: "a"

23:41 TeXnomancy: z_

23:41 amalloy: TeXnomancy: is that so

23:42 TeXnomancy: wups; baby on the keyboard

23:45 amalloy: where's the doc for clojurebot? i see people making him do cute tricks, but all i know is the ,expr syntax

23:45 clojurebot: clojurebot?

23:45 clojurebot: clojurebot is not a benchmarking platform

23:46 amalloy: clojurebot: help?

23:46 clojurebot: help is http://clojure.org

23:46 laurus: ,(re-groups (re-matcher #"(a)b" "ab"))

23:46 clojurebot: java.lang.IllegalStateException: No match found

23:46 laurus: ,(re-groups (re-find (re-matcher #"(a)b" "ab")))

23:46 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.regex.Matcher

23:46 laurus: amalloy, what am I doing wrong?

23:47 amalloy: re-find is returning a vector of matches; re-groups expects a matcher

23:47 laurus: Right, but in the second-to-last thing I tried, I passed it a matcher

23:47 TeXnomancy: clojurebot: source?

23:47 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

23:47 amalloy: ,(doto (re-matcher #"(a)b" "ab) (re-find) (re-groups))

23:47 clojurebot: EOF while reading string

23:47 TeXnomancy: if you squint from the right angle, it looks like documentation

23:49 amalloy: laurus: the second-last thing you tried, you passed it a matcher but hadn't asked it to match yet

23:49 the last thing, you asked it to match and then passed it a vector

23:49 laurus: Ugh, okay.

23:50 amalloy: TeXnomancy: these commit messages are so helpful. i could probably learn how to use him without even opening a source file

23:53 laurus: amalloy, it's quite strange, re-matches requires a pattern and a string, but re-find can take those or a matcher.

23:53 Is that an inconsistency?

23:54 amalloy: well, by definition yes. but it's not a bad one

23:54 laurus: Why? :)

23:54 amalloy: re-matches only matches the whole string, so there's no point keeping the matcher around

23:54 re-find will keep getting new matches if you pass it the same matcher, until it runs out

23:54 laurus: Oh, because it'll always return nil for the next one

23:55 Right.

23:55 Thanks. I think I'd better go to sleep.

23:55 Something tells me I would have realized a lot more of this if I'd done it a few hours ago :P

23:55 hiredman: my sarcasm hilight went off for this channel

23:56 laurus: Good night everyone!

23:56 And thanks again amalloy :)

23:57 amalloy: haha

23:57 how do i set one of those up, hiredman

23:59 hiredman: with great fortitude and endurance

Logging service provided by n01se.net