#clojure log - Dec 21 2008

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

0:06 jawolfe: I've gotta run, never mind ... I'll post in the newsgroup instead. thanks!

0:10 hiredman: (doc concat)

0:10 damn it

0:11 jawolfe: Hrm, i suppose apply is evaluating the arguments (duh).

0:12 hiredman: there is clojure.core/concat and clojure.core/lazy-cat both are lazy

0:12 jawolfe: hiredman: thanks

0:12 hiredman: i have looked at both

0:12 dhaya: jawolfe: Looks like concat is lazy except for the first 3 colls, try (take 1 (apply concat (map (fn [x] (prn x) (list x)) (range 1 20))))

0:13 jawolfe: dhaya: that's what it looks like to me too

0:13 for my application, I need something that is lazy for all (but the first, perhaps)

0:14 i.e. a fn that takes a lazy seq of seqs

0:15 and only forces each inner seq when its first element is needed

0:18 lisppaste8: jawolfe annotated #72461 with "solution?" at http://paste.lisp.org/display/72461#1

0:19 jawolfe: Thanks, gotta run

3:32 poiuyt: how can I conj or cons just a parenthesis?

3:33 hiredman: example?

3:33 poiuyt: iwant (conj [+ 2 3] ( )

3:33 -> [+ 2 3 (]

3:34 hiredman: you want the paren character

3:34 poiuyt: ys

3:34 hiredman: character literals in clojure are characters proceeded by \

3:34 \(

3:34 \)

3:38 poiuyt: ok

3:38 but i cant eval (clojure._PLUS___221@e5ace9 2 3 \( clojure.___247@5ed853 12 3 \))

3:39 hiredman: uh

3:39 heh

3:40 no

3:40 karmazilla: he want's to conj a list of things

3:40 hiredman: (eval `(+ 1 3))

3:40 karmazilla: want he wants is different then what he wants to do

3:41 poiuyt: eval takes a list of things, a data structure

3:41 (eval (seq [+ 1 3]))

3:51 so weird that clojurebot is still here

3:51 the server it runs on has been down for hours

3:52 poiuyt: lol

3:52 he has come alive

3:52 kurzweils predictions has been preceeded by reality

3:52 clojurebot

4:05 if i have a vector of arbitrarily nested vectors, what is the best way to visit them all?

4:05 loop recur and call the function again for each subvector?

4:05 is there such a function already?

4:07 hiredman: maybe in contrib?

4:08 poiuyt: what is the best html-parsing lib available in clojure?

4:17 hoeck: poiuyt: http://sourceforge.net/projects/nekohtml worked for me

4:34 poiuyt: how can i ask (operator? x)

4:34 or the common name for +-/*

4:38 can I doc multimethods?

4:42 Lau_of_DK: poiuyt: I dont know of any built in method for testing for operators, but this works

4:42 (= '* (or '* '/ '+ '-))

4:49 meredydd: heya

4:49 How do you get a backtrace off a REPL exception these days, without wrapping the whole line in (try (catch...))

4:49 ?

4:51 leafw: *e

4:51 or (.printStackTrace *e)

4:51 or (.printStackTrace (.getCause *e))

4:51 meredydd: Joy. Okay, I'll make a macro.

4:52 leafw: meredydd: all 3 are different levels of detail on the Exception, notice.

4:52 meredydd: I'm aware.

5:01 trasko: is it possible to define my own exceptions and then print the line number hwere it happened?

5:03 leafw: trasko: yes, you can define your own exceptions. And they will automatically show where they were thrown.

5:04 see (doc throw)

10:03 klinkers: how do i call a method like

10:03 Connection con = DriverManager.getConnection

10:03 ("jdbc:derby:eltesto1;create=true", "flonk", "plonk");

10:03 let [conn (new DriverManager.getConnection...?

10:05 leafw: klinkers: use namespace syntax, since it's static

10:06 (def con (DriverManager/getConnection "jdbc:derby:eltesto1;create=true" "flonk" "plonk"))

10:06 klinkers: ah

10:42 how dio im import java.sql.*; ?

10:42 (import '(java.sql *)) doesnt work

10:42 kotarak: klinkers: you can't import everything.

10:44 klinkers: how do i append 2 strings?

10:44 (+ "hello" " there")?

10:45 kotarak: (str "Hello" " " "there")

10:53 klinkers: how do I break a line?

11:10 kotarak: klinkers: ?? In the output? (newline)

11:52 Lau_of_DK: rhickey: Regarding the new initiatives like the wiki and such, would you consider tracking clojure on http://www.pivotaltracker.com/ ?

14:36 rhickey_: I didnt check my log before I shut down emacs, but did you get a chance to look at pivot tracker?

15:02 Boys, can I provide doc strings for multimethods in some clever way ?

15:02 kotarak: Only we (defmulti #^{:doc "bla"} foo ...)

15:05 Lau_of_DK: Thanks Mr. Brandmeyer

15:07 Hmm, that doesnt connec with (doc foo)

15:17 lisppaste8: drewr pasted "agent queue" at http://paste.lisp.org/display/72487

15:18 drewr: I've created a queueing mechanism for incoming and outbound messages over a socket.

15:19 The first time a couple of these gets created, everything works fine. Agents are dispatched, actions are called, stuff is logged.

15:19 The next time around, perhaps when a SocketException is caught, make-queue will get called again.

15:19 The agent is created and returned.

15:19 However, the action does not seem to be called (i.e., nothing is logged at least).

15:21 Is there anything obvious that I'm missing?

15:23 mehrheit: maybe it's blocking indefinitely?

15:24 drewr: What would cause it to block so as not to run f?

15:25 Specifically, the log on line 14 *is* printed, but the one on line 4 is not.

15:26 mehrheit: right, I missed that one

15:26 drewr: I even tried a throw in there to make sure there wasn't an I/O issue with stdout on subsequent calls.

15:27 mehrheit: does sending other functions to the returned agent work?

15:30 drewr: mehrheit: I'm not sure I understand.

15:30 To the agent after it's created?

15:31 The only way I interact with the agent is (.put (:q @a) "msg...").

15:51 chrisn: hello?

15:52 replaca: chrisn: good afternoon

15:52 kotarak: salut?

15:56 mehrheit: drewr: yes, after creation

15:57 drewr: mehrheit: I found out that the action runs later after I close the connection, so there is definitely something blocking the agent from running dispatchAction().

16:00 I wonder if LockingTransaction.getRunning() is blocking since this agent gets spawned from another agent.

16:03 rhickey: drewr: how do you know it's not blocked in take?

16:04 drewr: I don't see how transactions come into it, but getRunning() doesn't block in any case

16:05 drewr: rhickey: I suppose it could be, but why wouldn't it print the log message? I'm flushing *out* in my log fn.

16:06 rhickey: drewr: you saw "queue stopped" from prior action?

16:06 drewr: Yes.

16:07 rhickey: drewr: no agent errors?

16:07 drewr: conn is essentially a map like {:sock ... :inq (make-queue ...) :outq (make-queue ...) listener: (listen ...returns an agent too...}

16:08 The listen agent catches the SocketException and eventually calls (connect) which creates another conn, with new :inq and :outq.

16:08 It's these new queues that get blocking behavior I don't see the first time.

16:12 Actually, the log I'm looking at is to a file, but each line is written with (with-open) so it should be flushing on each close.

16:13 rhickey: drewr: "should be" famous last words :)

16:13 drewr: Heh, true.

16:14 rhickey: agents don't use locks/blocking, so I'd look carefully at the use of blocking queues

16:16 drewr: And you don't see any inherent danger in agents calling other agents ad infinitum?

16:16 chrisn: Am am building a rendering system. I know Rich *hates* mock objects, but I need to make a mock jogl opengl interface. This requires managing some minimal state (textures allocated as well as FBOs allocated for now). I could do this using atoms behind the scene to handle the state. Is this a valid way to go?

16:17 rhickey: drewr: no, the whole point is that, because they can't wait on each other, they can't deadlock

16:17 kbarros: besides performance, is there a semantic difference between "3" and "(int 3)"?

16:17 drewr: rhickey: OK, that's what I figured.

16:19 kbarros: it looks like operations on int's promote them to more general numeric values

16:19 rhickey: kbarros: yes, if you say (let [x (int 3)] ...) then arithmetic involving x and other ints will be 32-bit primitive math

16:19 Chousuke: rhickey: I sent a CA to you on friday. Hopefully it'll arrive safely.

16:20 rhickey: user=> (* 1000000 1000000)

16:20 1000000000000

16:20 user=> (* (int 1000000) (int 1000000))

16:20 java.lang.ArithmeticException: integer overflow (NO_SOURCE_FILE:0)

16:20 drewr: rhickey: If I look at the LinkedBlockingQueue, it's filled with stuff from the socket's input stream. It seems to indeed be that the agent's action isn't running to start .take-ing.

16:23 kbarros: user=> (def a (int 1000000))

16:23 user> (* a a)

16:23 does not overflow

16:25 rhickey: kbarros: the types have to be accessible to the compiler - there's no type on a, so generic arithmetic

16:25 primitives are limited to let locals and args

16:26 drewr: you need to make sure the queue you are looking at is the one the agent is

16:27 kbarros: ok, thanks. when using literal numbers could the compiler, as an optimization, generate primitive operations? i.e., could it fall back to generic arithmetic when necessary?

16:30 drewr: rhickey: I'm (fairly) sure of it. All the messages flush out after I "stop" the queues.

16:30 rhickey: kbarros: that's kind of what the generic math is, also there is an interaction with boxing, which dominates over the dispatch. A local with a primitive type is unboxed, a literal is boxed

16:31 drewr: I just don't understand why the ones for the first connection act "normally" and then subsequent ones block.

16:31 They're different agents, actions, and states.

16:31 Each call to make-queue creates a different BlockingQueue.

16:34 rhickey: drewr: you sure you're not being fooled by the logging not flushing?

16:37 drewr: Yes, because the logging acts like I expect with a fresh connection -- (read-line) returns line, .puts it into queue, agent .takes it, dispatches on it, logs it, etc.

16:38 Besides, I put a (throw) in the action just to make sure it wasn't a buffering issue, and the agent didn't report any errors.

16:42 rhickey: drewr: can you make an isolated reproducing test case?

16:42 drewr: I'm thinking of how I can do that. :-)

16:42 chrisn: why are there specific setters for arrays of different types, but not different getters?

16:55 klinkers: hmm lets say you have a bunch of functions that operate on some structure. lets say they all take 4 params. now for all these functions the 1st param will always be the same. can i somehow write a macro that changes function-definitions? hmm does this make any sense?

16:55 kbarros: I get a "class cast exception" for the following expression: (double 1e500) . Is this the appropriate compiler error? It confused my emacs mode.

17:03 RSchulz: kbarros: I think it might be a bug. Witness:

17:03 (double 1e500)

17:03 java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number

17:03 user=> 1e500

17:03 Infinity

17:04 user=> (class 1e500)

17:04 clojure.lang.Symbol

17:04 I think that's the problem. You get a symbol when you give a floating (or double) numeric literal that is out-of-range for a double.

17:09 Perhaps it's deliberate to ensure that no computation takes place using an unrepresentable number.

17:09 It could be argued that it should be converted to one of the arbitrary-precision formats.

17:14 gnuvince_: RSchulz: by the way, did you start a blog? I saw you asked about blogging services on the mailing list.

17:15 kbarros: rschulz: thanks

17:15 RSchulz: gnuvince_: Not yet. I think it might have been a passing fancy.

17:16 kbarros: i was expecting (double 1e500) to be the double representation of infinity

17:16 gnuvince_: That's too bad, you seem to have very good knowledge, it would've been a nice boost to the community.

17:23 Lau_of_DK: In a try/catch, how do I print the exception trapped?

17:25 Nevermind, I got it

17:28 RSchulz: gnuvince_: I haven't definitely decided not to. I'm just worried about being able to sustain a blog long enough for it to be meaningful.

17:29 drewr: rhickey: FYI, I switched that .take to a .poll (which shouldn't block), and get the same behavior.

17:29 klinkers: if i make a new namespace, cant i def taken names there?

17:29 RSchulz: Part of my problem (psychologically...) is that as soon as I've accomplished something, it no longer seems special to me and hence no longer worth writing about.

17:30 gnuvince_: RSchulz: you're not alone ;)

17:30 drewr: Is there any reason why an agent won't fire an action ASAP after instantiation?

17:37 rhickey: drewr: agent sends don't dispatch until agent action returns

17:38 see #5 here: http://clojure.org/agents

17:39 drewr: From what I'm seeing, #1 is what is postponed.

18:16 replaca: how do I add stuff from a jar in the classpath to the repl? I've been trying stuff like (load "/clojure/contrib/lazy-xml") but this doesn't seem to get it.

18:16 (Up til now, I'd just been going straight from Slime)

18:17 dreish: add-classpath

18:17 rhickey: replaca: the stuff is a lib?

18:17 (load 'clojure.contrib.lazy-xml)

18:18 replaca: yeah, in a jar. The jar is already on my classpath

18:18 rhickey: load takes the name of the lib as above

18:18 Chouser: load takes a string, doesn't it?

18:19 rhickey: but you really want require don't you?

18:19 Chouser: (require 'clojure.contrib.lazy-xml) or (use 'clojure.contrib.lazy-xml) should work.

18:19 replaca: there we go!

18:20 rhickey: thanks for the noob answer

18:20 my lisp skills and my java skills haven't quite jelled into the clojure mindset :-)

18:21 require is exactly the button I was looking for

18:21 rhickey: Chouser: you're right, so would need slashes and -/_ translation

18:22 Chouser: but not the .clj extension. ...far too low-level to bother explaining. :-)

18:30 replaca: Another Q: is there a standard way now of doing AOT compiles from the command line (or ant tasks)? I saw the group thread, but it still seems unresolved.

18:30 Or should I just write a clj helper for ant?

18:35 Nafai: replaca: That would be useful, if there isn't one already

18:38 replaca: Nafai: yeah, it seems necessary eventually for packaging things. But it might not be today's most important problem for anybody. :-)

18:38 Nafai: replaca: I was considering doing that myself

18:39 Because I was going to try to write Android apps with Clojure

18:39 But I ran into some snags :)

18:39 replaca: Yeah, to be really useful it needs to be in the core

18:40 I think we need command line tools that let you "ignore" the jvm

18:40 This has been discussed at some length in the group and I don't really have a lot to add to that discussion

18:41 nafai: what kind of snags did you run into?

18:41 Nafai: replaca: A couple: 1) the compiler for dalvik, the Android vm, won't compile the existing Clojure jar

18:42 2) Clojure still uses a runtime dynamic classloader and that won't work with dalvik either

18:42 So my snags weren't related to making the ant task :)

18:42 replaca: oh, you wrote about that in the group, right?

18:42 Nafai: I've just discussed that here

18:43 replaca: I'd love to see android work too. It seems like it would be awesome to write clojure apps targeted at mobile devices

18:43 Nafai: I guess I read it while lurking one day :-)

18:44 Nafai: Yeah, me too

18:45 klinkers: can someone give me an example of how i should name my namespace

18:45 i stil dont get how to refer tot hem from others

18:46 i want like python: import numpy as N; N.f

18:47 replaca: klinkers: mostly you don't use import to pull in other clojure stuff, you use (require) or :use if you're in an ns statement

18:48 Like this:

18:48 (ns foo (:use com.infolace.format))

18:49 or

18:49 (require 'com.infolace.format)

18:49 the java babble of the inverted domain name is completely optional (just convention)

18:50 hiredman: I just put everything under hiredman

18:50 hiredman.clojurebot

18:51 klinkers: but where does :require look?

18:52 im a in a dir datstructures now

18:52 im a in a dir datastructures now

18:52 i have one file (ns datstructures.stack)

18:52 replaca: In the classpath

18:52 klinkers: ah i see

18:53 replaca: so the "." is typically a directory boundary

18:53 so that would look for datastructures/stack.clj

18:54 (again the inheritacnce of java/jvm)

20:04 Answering my own earlier question (in case anyone cares): You can compile from the command line with java -cp ... clojure.lang.Compile foo bar

20:04 where foo and bar are the names of namespaces to compile

20:05 There is an ant task in the latest clojure build.xml

20:36 Chouser: rhickey: {} constructs an ArrayMap -- is that documentable, or incidental?

20:37 rhickey: Chouser: when does it matter?

20:42 RSchulz: user=> (class {})

20:42 clojure.lang.PersistentHashMap

20:43 user=> (ancestors (class {}))

20:43 #{clojure.lang.IObj java.lang.Iterable java.util.concurrent.Callable clojure.lang.IPersistentCollection java.lang.Object clojure.lang.APersistentMap clojure.lang.Obj java.lang.Runnable clojure.lang.AFn java.io.Serializable java.util.Map clojure.lang.IFn clojure.lang.Associative clojure.lang.IPersistentMap}

20:45 Chouser: rhickey: It doesn't much, but the ArrayMap docs could mention that {} is one way to construct one.

20:45 RSchulz: try (class {:a 1 :b 2 :c 3})

20:46 rhickey: Chouser: apparently it isn't, currently

20:46 Chouser: depends if it has any entries. I guess I'll skip it.

20:47 rhickey: Chouser: and number of entries

20:47 user=> (class {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8})

20:47 clojure.lang.PersistentArrayMap

20:47 user=> (class {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9})

20:47 clojure.lang.PersistentHashMap

20:48 Chouser: ok

21:42 Dmisener: How do I programmatically what the current version of clojure that is running?

21:43 As you can imagine Google "Clojure version" isn't much help {grin}

21:46 Chouser: Dmisener: did you download a release, or use svn?

21:50 Dmisener: Downloaded the release... I know what version it is ... but was wonder if I was to make version sensitive code.. how would I determine the current running version.

21:50 Chouser: no such capability yet.

21:53 Dmisener: Thanks...

23:50 replaca: Q: what sorts of things can *out* be bound to and have print/pr work?

23:50 hiredman: writers

23:50 filewriter, printwriter

23:51 replaca: thanks, hiredman

Logging service provided by n01se.net