#clojure log - Jan 06 2011

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

2:04 tomoj: is there any way for a macro that expands to a def to set the :file and :line metadata?

2:04 seems def ignores it and supplies its own

2:05 qbg: You could expand to (do (def name ...) (vary-meta #'name ...))

2:06 tomoj: ouch

2:06 but thanks

2:08 amalloy: tomoj: that's exactly what defmacro itself does

2:08 tomoj: alter-meta! I guess

2:08 amalloy: oh, hmm

2:08 amalloy: it has to set the :macro key of the def'd var

2:09 tomoj: ah, (list '. (list 'var name) '(setMacro)) ?

2:11 amalloy: tomoj: yeah

2:12 oh, i see it's not actually altering the meta directly; it's been a while since i looked at that

2:18 tomoj: but i guess (.setMacro x) is exactly equivalent to (vary-meta! x assoc :macro true)

2:24 tomoj: yep, only expressed in 16 lines instead of one :)

2:25 er, that's not fair I guess

2:32 Licenser: morning!

2:34 qbg: Licenser: I see your morning and raise you a good night

2:52 rooney: hi all, I'm a total noob trying to install labrepl, lein deps complains that it can't get org.clojure:clojure-contrib:jar:1.1.0-master-SNAPSHOT

2:52 what should I do?

3:00 amalloy: rooney: try changing project.clj to ask for clojure-contrib "1.2.0" instead of "1.1.0-master-SNAPSHOT"

3:02 rooney: hi amalloy, it's already "1.2.0", I just cloned it and haven't changed anything

3:02 tomoj: doesn't labrepl's project.clj already ask for 1.2.0?

3:02 rooney: yes, tomoj

3:02 tomoj: some dep is asking for the snapshot, I guess

3:05 rooney: this is what lein says

3:05 Path to dependency:

3:05 1) org.apache.maven:super-pom:jar:2.0

3:05 2) autodoc:autodoc:jar:0.7.0

3:05 3) org.clojure:clojure-contrib:jar:1.1.0-master-SNAPSHOT

3:08 tomoj: huh.

3:08 it's fixed in autodoc's repo, but not in the latest autodoc on clojars

3:09 I imagine you can probably just remove autodoc from the dev-dependencies

3:12 why does labrepl dev-dep on autodoc, I wonder?

3:12 rooney: hey that works, thanks tomoj!

3:13 I have no slightest clue, I'm really noob about clojure

3:13 tomoj: see also https://github.com/trptcolin/labrepl/commit/f323292b5947932dbcb56bac3bfca56d781947d7

3:13 to keep autodoc but avoid the error

3:13 not sure if there's actually any reason to keep autodoc...

5:42 LauJensen: Morning crew

5:42 talios: 'lo

5:42 16minutes till morning tho :)

5:56 Leonidas: (sort-by :upvotes {:foo {:upvotes 3} :bar {:upvotes 5} :baz {:upvotes 2}})

5:57 ,(sort-by :upvotes {:foo {:upvotes 3} :bar {:upvotes 5} :baz {:upvotes 2}})

5:57 clojurebot: ([:foo {:upvotes 3}] [:bar {:upvotes 5}] [:baz {:upvotes 2}])

5:59 Leonidas: hmm, I think :upvotes is not the proper fn

6:03 ,(sort-by (comp :upvotes second) {:foo {:upvotes 3} :bar {:upvotes 5} :baz {:upvotes 2}})

6:03 clojurebot: ([:baz {:upvotes 2}] [:foo {:upvotes 3}] [:bar {:upvotes 5}])

6:04 Leonidas: ,(sort-by (comp - :upvotes second) {:foo {:upvotes 3} :bar {:upvotes 5} :baz {:upvotes 2}})

6:04 clojurebot: ([:bar {:upvotes 5}] [:foo {:upvotes 3}] [:baz {:upvotes 2}])

6:04 Leonidas: what is better to use: - in the key-fn or reverse on the resulting seq?

6:11 any why are there 2 planets, http://planet-clojure.org/ and http://planet.clojure.in/

6:13 arbscht: Leonidas: the latter is implemented in python, the former a rewrite in clojure

6:14 I presume planet.clojure will be deprecated eventually

6:15 Leonidas: arbscht: and which one to use at the moment? the latter has a nicer UI and looks more "recent".

6:16 arbscht: Leonidas: I use planet.clojure.in, out of habit

6:17 Leonidas: arbscht: ah, ok, thanks

6:48 could someone please take a quick look at https://github.com/Leonidas-from-XIV/karmawhore/blob/master/src/karmawhore.clj ?

6:48 I'm rather new to clojure and therefore I suppose I did some stuff overly complicated

6:52 Chousuke: looks pretty good to me

6:52 Leonidas: btw, is it possible that split-with and separate are exactly the same function, just implemented differently? and separate is twice in clojure-contrib?

6:53 Chousuke: thank you :) I suspect I messed up in -main, with unpacking, repacking, unpacking again.

6:56 Chousuke: it seems you don't need summed-karma to be a map

6:56 since it gets sorted immediately afterwards

6:58 also is there a need for votes to be a map either?

6:58 GOSUB: Leonidas: the .org planet came later and was created as a hobby. not sure if it's maintained anymore.

6:59 arbscht: the former is not a rewrite per se, since it was written without any discussion with me.

6:59 Chousuke: Leonidas: oh, I just noticed you have a single-segment namespace. That can break some things.

6:59 Leonidas: ,(val ["foo" "bar])

6:59 clojurebot: EOF while reading string

6:59 Leonidas: ,(val ["foo" "bar"])

6:59 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry

7:00 Chousuke: Leonidas: you should at least have leonidas.karmawhore or something :)

7:00 preferably one more, to avoid collisions

7:00 Leonidas: Chousuke: yeah, but I really dislike the deep nesting that this causes.

7:00 Chousuke: you'll dislike the problems more

7:00 GOSUB: ,(val (first {"foo" "bar"}))

7:00 clojurebot: "bar"

7:01 Leonidas: ,(second ["foo" "bar"])

7:01 clojurebot: "bar"

7:01 Leonidas: hmm, second could be good enough as replacement

7:01 Chousuke: Leonidas: the issue is that since you only have a single segment in your namespace, it ends up in the default package :/

7:02 and that confuses IDEs and tools pretty often

7:02 bartj: I get garbage on my REPL when I do this

7:02 , (println "самарская обл.,")

7:02 clojurebot: самарская обл.,

7:02 Chousuke: bartj: your encoding is wrong

7:02 Leonidas: Chousuke: oh, ok. I'll think about it. thanks for the information

7:03 raek: bartj: are you using a plain repl at the terminal, or a repl in an IDE?

7:03 bartj: raek, a plain REPL

7:03 Chousuke: bartj: there's a switch you can give to java to specify the encoding by I don't remember it :/

7:03 it's usually something stupid by default

7:03 like macroman on OS X

7:03 raek: bartj: lein repl or java -jar clojure.jar clojure.main?

7:03 Chousuke: who uses that, anymore?

7:04 Leonidas: Chousuke: I don't think it needs to be a map, but semantically i think a map "fits".

7:04 raek: if you use lein repl, install rlwrap (a command line tool)

7:04 Leonidas: Chousuke: ---^ votes I mean

7:04 * raek </3 "Operating System Default Encoding"

7:05 * Leonidas likes the clj script from Arch Linux. it uses rlwrap and/or jline if available :)

7:05 Chousuke: Everything should just use UTF-8 by default nowadays :(

7:05 raek: agreed

7:05 Chousuke: if anyone needs anything else, they can change it

7:05 raek: lein repl uses rlwrap if avaiable and jline otherwise, IIRC

7:06 and jline chokes on UTF-8

7:07 bartj: also, you have to set your terminal to use UTF-8 too

7:11 hrm, I thought *in* and *out* were using UTF-8 in clojure, but it seems they are using the dreaded "Operating System Default Encoding"

7:12 at least source code is interpreted as UTF-8

7:12 bartj: raek, still fighting UTF-8

7:13 AWizzArd: cemerick: do you know anything about Azuls Zing plattform as a cloud service?

7:13 cemerick: AWizzArd: not a bit

7:13 raek: bartj: are you using leiningen to start the repl?

7:13 AWizzArd: They show so nice comparisons: http://www.azulsystems.com/sites/www.azulsystems.com/Response%20Time%20WEBeTailer2010%20rev2.jpg

7:13 cemerick: Though Azul + platform sounds interesting! :-)

7:13 bartj: raek, no

7:13 AWizzArd: cemerick: it does.. Amazon should buy a few of such.

7:13 raek: bartj: how do you start it?

7:14 bartj: raek, java -cp "libraries" jline.ConsoleRunner clojure.main $1

7:15 raek, I have that somewhere in an executable

7:15 raek: bartj: jline is broken.

7:15 use rlwrap if you can

7:15 bartj: raek, you mean a particular version?

7:16 raek: last time I checked, it wasn't designed with multi-byte encodings in mind

7:16 bartj: sigh

7:16 raek: but they might have done something about it

7:16 cemerick: raek: FYI, you can set the JVM's default encoding via the file.encoding system property.

7:16 raek: -Dfile.encoding=UTF8

7:17 this one?

7:17 bartj: I am going to sorely miss the "history" feature that jline gives my Clojure REPL

7:17 cemerick: yes

7:17 no good?

7:18 raek: bartj: if you have rlwrap installed, you should be able to use it like "rlwrap java -cp ..."

7:19 bartj: you might want to try adding the -Dfile.encoding=UTF8 option and checking the terminal's settings first

7:19 bartj: raek, thanks a ton;

7:19 raek: if you're lucky, the jline guys might have fixed it

7:20 bartj: np

7:20 bartj: raek, I had rlwrap but didn't know how to use it - "rlwrap command" works

7:20 raek: "lein repl" has all this built in

7:21 but maybe you didn't wanted to use lein

7:24 bartj: raek, can you please point where I can see more features of lein repl?

7:24 raek, I don't know what I am missing

7:26 raek: bartj: well, basically it starts clojure, takes care of the classpath and wraps the repl in jline or rlwrap

7:26 https://github.com/technomancy/leiningen

7:26 http://groups.google.com/group/leiningen/browse_thread/thread/65ccdef10c4ed173

7:28 I don't think there are many more features of lein repl

7:28 well, it starts a socket server too

7:28 bartj: raek, thanks again

7:49 AWizzArd: rhickey mentioned a link to an article about Zing in June or July 2010. Today they seem to have it available: http://www.azulsystems.com/products/zing/whatisit

7:50 fyuryu: anybody ever experimented with protocol buffers for real time communication via UDP?

7:54 cemerick: AWizzArd: do they host it? There's a form to request access to trial downloads.

7:55 I'll bet it'll be serious $$, in either case.

7:55 fyuryu: as rhickey once said: if you have to ask, you can't afford it :-)

7:58 AWizzArd: cemerick: Unfortunately I don't know about the prices of this. They made me believe that it will be much cheaper than alternative solutions when your load is really big. I don't know how big 'big' is though ;)

7:58 cemerick: TB-sized heaps makes me think "big" means "BIG" :-)

7:59 AWizzArd: Though it could be interesting to take one of these Vega 3 machines with 864 cores and 768 GB of RAM and just share it for users that just need 1-20 cores and 1-20 GBs.

8:00 For hosting I found http://goo.gl/ugiOJ

8:02 I get the impression that they are offering hosting.

8:02 But it may be possible that they don't target users with non-massive needs.

8:03 cemerick: "Customers can request a trial copy at…"

8:03 That screams on-premise.

8:03 AWizzArd: http://www.azulsystems.com/sites/www.azulsystems.com/azul/images/ZRC%20Screen%20Shot.jpg

8:03 This screen looks a bit like a management console for instances.

8:05 Cool would be if they simply allowed to sign up and buy some time on their instances. I would try it, even for 10$ per hour. Just out of curiosity to see how good my stuff runs there :)

8:43 rak85: hi, guys

8:43 what do i have to 'use' in order to use the thrush function?

8:47 sorry, the function is comp

8:47 mrBliss: ,((comp #(* % %) inc) 1)

8:48 clojurebot: 4

8:55 AWizzArd: rhickey: Would it make sense to let alter-mate! work on symbols too?

8:55 I have a macro which generates a defn F. The parameter vector of F is automatically type-hinted. I first tried ~(alter-meta! arg-name assoc :tag class) but later on switched to the more complicated ~(with-meta arg-name (assoc (meta arg-name) :tag class))

8:56 rhickey: AWizzArd: no, symbols are values

8:56 AWizzArd: Okay, so with-meta was the right approach then.

8:58 Another thing: 'some' takes only one collection over which it iterates. Could this be extended to take n collections, like map (and CLs some)?

9:01 bortreb: I have a C++ program which I have written which analyzes videos and then outputs data about them to STDOUT

9:02 What's the best way to get clojure to process this as sequence of records or whatever?

9:02 or should I be using JNI or JNA or some other such thing??

9:07 stuartsierra: Clojure can read STDIN like any other program

9:17 bortreb: I'm wanting to write a clojure function that takes in a File object and runs the program on it, returning a lazy sequence of records captured from the output of the program (which may go on for forever if it reads from a camera)

9:18 but I don't know how to invoke the program from the shell or capture the data in a sequence, especially as it might keep going

9:19 does that sound reasonable/ how might I do such a thing?

9:21 raek: http://clojuredocs.org/clojure_core/clojure.java.shell/sh <-- this will probably do the "run the program on the file" part

9:22 you will get the whole output as one (possibly giant) string, though

9:24 bortreb: I've tried that, but the problem is that sh blocks until the process finishes, which may not ever happen

9:24 or at least is inconvienent

9:25 is there some way to make that into a lazy sequence?

9:25 raek: ah, I see. communicating via a stream would perhaps be better

9:26 you should be able to make a function very much like sh, but which gives you a stream of the program's output instead

9:27 bortreb: streams? what are these? are they lazy-seqs or something?

9:27 raek: http://download.oracle.com/javase/6/docs/api/java/lang/Runtime.html#exec(java.lang.String, java.lang.String[])

9:27 java.io.InputStream (for binary data) or java.io.Reader (for text)

9:28 you can call line-seq on a reader to get a lazy sequence of the lines in that stream

9:28 bortreb: so I'll have something like a backing lazy seq that gets realized in a seperate thread that runs the process "till completion" and then take things from that lazy-seq in my main thread?

9:29 and still use STDOUT or is there a more proper / better way to send data from the C++ program

9:29 raek: the exec call will start the program in a spearate process

9:29 bortreb: ?

9:29 raek: you will get a Process object back (http://download.oracle.com/javase/6/docs/api/java/lang/Process.html)

9:29 and you can access its stdin/out/err

9:30 bortreb: does that sound reasonable?

9:30 raek: with this approach, you clojure program would start the C++ program

9:31 well, how do you want to start the C++ program?

9:31 bortreb: I think from the clojure function,

9:31 raek: if you want to pipe its output to the clojure program's stdin, then you can simply call line-seq on *in*

9:32 the exec call will not block

9:32 so there is no need to start a separate thread here

9:33 the reason that sh blocks is that it wants to consume all the input before returning

9:36 my advise would be to start the process using java.lang.Runtime/exec (look at the source for 'sh', since the inerop can be tricky in this case) and return (.getInputStream the-process-returned-by-exec)

9:37 you can then use the methods of the InputStream to read the data

9:38 you could also make a function that returns a lazy sequence of the records by 'repeatedly' calling some 'read-record' function on the input stream

9:38 bortreb: thanks so much --- I'll start trying to piece something together

9:39 raek: if the data is text oriented, use Reader instead of InputStream

9:39 since bytes and characters are not the same thing in clojure

9:39 (sorry for spaming, but I really want to stress that)

9:44 afekz_: is there an FAQ for the # here?

9:53 AWizzArd: bortreb: I used the approach raek mentioned. Started a binary from Clojure and follow its input stream to see what it outputs.

10:18 mtopolnik: query sexpbot

10:31 bortreb: success

10:35 tonyl: bortreb: congrats, on whatever you are doing

10:38 bortreb: I made a modified version of sh as per raek's suggestions -- it's at https://gist.github.com/768026

10:39 tonyl: oh interesting, lazyseq of the stdout

10:39 bortreb: but, I still don't know how to fix it for long running processes that return a lot of data via STDOUT --- the javadoc for the reader says that Bad Things happen if you wait too long to read the buffer

10:40 so I guess I'd run into that if the lazy seq wasn't consumed quickly enough....

10:45 but so far it seems to be doing well

10:50 AWizzArd: bortreb: You don't need a lazy-seq. You could have a thread that reads from the stream whenever you expect it to output something.

10:53 bortreb: :AWizzArd doesn't the lazy-seq help to decouple the reading from the processing, though?

11:05 AWizzArd: bortreb: How would it do this? Lazy seqs are an optimization technique that can save memory.

11:09 raek: bortreb: neat! also, I would recommend passing an additional agrument to the Reader constructor: the encoding

11:09 if you don't know which one you want, pick "UTF-8"

11:09 AWizzArd: bortreb: in your case a lazy seq can even potentially cause memory problems, namely when your binary produces tons of output which you don't consume.

11:09 bortreb: ok --- I shall add that

11:10 it's true that the lazy seq can cause memory problems because of the caching action

11:10 raek: the clojure.java.io/reader function can be used instead of nesting the two constructors

11:11 (it's basically just sugar for making these kind of things shorter)

11:11 AWizzArd: bortreb: I have two futures that constantly read from the output and the error stream

11:11 raek: (io/reader (.getInputStream process) :encoding "UTF-8")

11:12 AWizzArd: I use the situation that .read blocks.

11:13 This way my infinit loop can just read everything the binary outputs, and run the parser on it and then recur to the loop head.

11:13 raek: also: (def println-repl (bound-fn* println))

11:13 AWizzArd: The future will sleep until your binary outputs something. As soon this happens the future wakes up, reads everything, parses it and continues to sleep until the next output arrives.

11:13 raek: or (alter-var-root #'*out* (constantly *out*)) ;; in the slime repl

11:14 (io/reader will also wrap the Reader in a BufferedReader)

11:18 bortreb: :raek I edited the gist to reflect your changes

11:19 :AWizzArd so then your futures dereference into a big string, or a list of lines, or a character stream?

11:20 could I see an example of using futures to read from STDOUT if it's convienent?

11:24 AWizzArd: bortreb: the code I wrote is not mine, I can not post it. But I can tell you that you basically need to decide how you think your binary will output data to the console: 1. it happens after you do something specific in Clojure or 2. it can happen at any time, parallel to your running Clojure program.

11:25 If it is 1. then you can simply trigger the action in Clojure and in that moment read from the input stream of the Process object. And then you have a String and can do with it whatever you want.

11:26 In the case 2. you will need a state object, such as an agent, which can be accessed from other threads. They will deref the agent to see its latest output.

11:27 You would send a reading/parsing function to the agent. The agent can call itself, which is the equivalent to the recur in my future.

11:31 bortreb: basically have a byte array, say, 1 MB in size. Optimally it should be able to catch more than the binary can output at any time. Then you .read into that array, and see how much you read. Then make a string out of this, parse it and you have your data.

11:32 And .read can immediately be called again, if it should be needed, depending on your app. It will block until the next output is available. And you can .interrupt it any time.

11:33 bortreb: wouldn't that have the same problem as the lazy-seq method in that you will not succeed if the program outputs too much?

11:34 oh, but you can set the buffer size with your method while you can't with the lazy-seq ethod?

11:34 and it doesn't necessarily cache anything

11:35 AWizzArd: You can check how much data is .available and create an array on-the-fly of that size.

11:35 bortreb: how can code that you wrote not be yours if you wrote it?

11:35 AWizzArd: But if you expect that your output can be bigger than a (fixed) array size, just .read multiple times from it, until your data can be parsed in a meaningful way.

11:36 bortreb: I wrote it while I was at work. It belongs my company.

14:22 edw: Is there a non-painful way to deal with including a jar that's not fetched from a lein repo? I'm writing to the AdWords API and would like to use the Google-provided jar.

14:22 chouser: I think you can symlink (or copy) the jar in to a specific place in your project dir

14:22 amalloy: edw: it's actually a maven repo, but ways exist

14:22 easiest for me is lein install

14:23 though i think you have to do something special to install a raw jar

14:23 edw: Hmm. Reading TFM...

14:24 amalloy: http://code.google.com/p/google-api-adwords-java/issues/detail?id=28 is an open issue (open for a long time) asking google to put the damn thing in maven

14:26 edw: Sigh...

14:26 amalloy: edw: http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html

14:26 edw: Thanks!

14:28 amalloy: lein and cake both provide a convenient wrapper around this functionality, but i can never remember how to use it :P

14:31 edw: OMG this is insane. In order to add a jar to a classpath I need to create a POM file and add it to the local Maven repo. This is why I hate Java with a passion.

14:32 amalloy: edw: doesn't that mvn:install task create the pom for you?

14:32 well. "for" you, after you specify all the crazy options it needs

14:32 edw: Perhaps. I specified a packaging type of 'jar'. Maven is heating up my laptop right now. Let's see what happened...

14:33 amalloy: jar should be right

14:33 not that i'm a maven expert

14:37 edw: Well lein installed the jar from the local Maven repo, but I can't find the classes. I'll count this as a victory of sorts. (If I didn't, I'd be pulling out the bottle right now...)

14:38 amalloy: *chuckle*

14:39 edw: if it's installed, you should be able to specify it as a dependency in project.clj, and then (import com.google.Blah)

14:47 edw: amalloy: I've specified it as a depenedency, and it appears in *classpath*, but I can't import any of the packages.

14:47 amalloy: huh

14:47 hiredman: have you run lein deps? is the jar actually in libs/?

14:50 edw: Yeah, I'm blowing through some of the Java sample code, looking to replicate something trivially simple in Clojure, but this is Java, so trivially simple is hard to find...

14:50 rata_: hi all

14:52 edw: Hi rata_.

14:52 pjstadig: one

14:52 oops

16:01 SoftwareMaven: Is anybody using clojure for production web servers (beyond toy stuff, anyway)?

16:08 lpetit: SoftwareMaven: TheDeadLine , for one. And Google App Engine !

16:08 https://the-deadline.appspot.com/

16:09 http://www.slideshare.net/smartrevolution/using-clojure-nosql-databases-and-functionalstyle-javascript-to-write-gextgeneration-html5-apps

16:09 and there's also the video related to this talk available somewhere

16:09 I mean, google it and you'll find it :)

16:12 benreesman: anyone know the right way to get the last inserted id with clojure.contrib.sql?

16:16 SoftwareMaven: lpetit: I promise I tried Google first. It's always hard to figure out what keywords to try.

16:17 lpetit: And thanks, too :)

16:18 LauJensen: benreesman: I dont know about contrib, but in clojureql this might work @(project (table db :tablename) ["LAST_INSERT_ID()"])

16:18 benreesman: cool

16:18 LauJensen: Also, this might work, if tht ID is also the highest id

16:18 (-> (project (table db :pages) [:id]) (sort [:id#desc]) (take 1) (pick! :id))

16:19 That will return an integer

16:19 @ benreesman

17:38 riddochc: Hey, I've got a curious thing going on with the tip of master on things in -contrib... When I do (use 'clojure.contrib.monads), I get the following:

17:38 CompilerException java.lang.IllegalStateException: Can't dynamically bind non-dynamic var: clojure.contrib.macro-utils/protected-symbols, compiling:(clojure/contrib/monads.clj:195)

17:39 amalloy: riddochc: probably not all of contrib is updated for clojure 1.3.0

17:39 riddochc: I looked in macro-utils, and protected-symbols is defined like so: (defvar- ^:dynamic protected-symbols #{})

17:40 It *looks* like the metadata indicates it's dynamic.

17:41 amalloy: i notice that (str (promise)) prints "clojure.core$promise$reify__5542@1926603" (or similar), but (print (promise)) hangs until someone delivers to it. is there a reason for this?

17:44 riddochc: that's the wrong syntax for dynamic, unless defvar- is doing some pretty surprising stuff

17:45 should be ^{:dynamic true}, i think. ^:dynamic is a type-hint, claiming the object's type will be :dynamic

17:45 qbg: amalloy: core uses that syntax

17:45 ^<keyword> is equivalent to ^{<keyword> true} in 1.3

17:46 amalloy: qbg: oh, thanks; didn't realize that had changed. that's what i get for checking my work in a 1.2 repl

17:46 qbg: It is a useful change too

17:46 * riddochc hunts, tracing down to defsymbolmacro in contrib/macro-utils...

17:46 qbg: ^:private compared to ^{:private true} for example

17:46 amalloy: qbg: agreed

17:47 riddochc: is the var perhaps getting re-def'ed somewhere else that doesn't include :dynamic?

17:47 riddochc: amalloy: I'm trying to find that out now...

17:50 rata_: amalloy: probably print includes in what it prints the value of the promise

17:51 amalloy: rata_: yeah, presumably. i'm just not sure how to go about finding that and either getting around it or adding an option

17:54 rata_: amalloy: maybe defining a method for print-method... what are you doing?

17:55 amalloy: rata_: sandboxing. if the user says (print (sandbox `(promise))), it hangs forever; the sandbox function contains a timeout, but here the print (and therefore deref) happen outside of the timeout context

17:57 perhaps i could add an :as-string mode to the sandboxer, which uses pr-str before returning the result

17:59 rata_: and does it help to define a method for print-method like (defmethod print-method (class (promise)) [obj] (print (str obj)))?

18:00 sorry (d... [obj w] (.write w (str obj)))

18:00 amalloy: ^

18:00 amalloy: rata_: yes, that sorta fixes the problem - except that if the promise HAS been delivered to, you can't see its value

18:01 rata_: amalloy: well, if there's a predicate for testing if a promise has been delivered, you can handle that in the body of that method

18:04 amalloy: rata_: i looked around but i couldn't find one. i suppose i could deliver "Pending" to the promise and catch the exception if it's been delivered

18:05 rata_: can you deliver more than once to a promise?

18:06 amalloy: rata_: no; that's the idea

18:06 &(let [x (promise)] (deliver x 1) (deliver x 2))

18:06 sexpbot: java.lang.IllegalStateException: Multiple deliver calls to a promise

18:09 amalloy: rata_: thanks for the ideas. i'll meditate on my options

18:09 rata_: welcome

18:11 drewr: how do you get-in in python?

18:12 and I don't mean d["foo"]["bar"]

18:12 I want a function that will take ["foo"]["bar"] and apply that to d

18:15 rata_: is there a way to know the fields of a class from clojure?

18:16 drewr: ,(doc "methods")

18:16 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Symbol

18:16 drewr: ,(doc methods)

18:16 clojurebot: "([multifn]); Given a multimethod, returns a map of dispatch values -> dispatch fns"

18:17 drewr: hm, I thought there was one for java

18:17 you can use show in c.c.repl-utils

18:23 vijaykiran: Hi All .. (noob here) What's the best way to multiply two sequences in clojure ?

18:23 rata_: drewr: def get_in(d, ss): return reduce(lambda d, s: d[s], ss, d)

18:23 vijaykiran: in which way do you want to multiply those seqs?

18:24 (map * s1 s2) is one way

18:24 drewr: rata_: ah, nice

18:25 rata_: ss is an iterable of keys

18:25 vijaykiran: rata_: I want something similar to the effect of - for (int i = 1; i < 10; i++) { for (int j = 1; j < 10 ; j++) { println i*j }}

18:26 rata_: that is (dotimes [i 10] (dotimes [j 10] (println (* i j))))

18:27 mmmm... just realized you want it from 1... then (dotime [i 9] (dotimes [j 9] (println (* (inc i) (inc j)))))

18:27 vijaykiran: rata_: sorry for the wrong description - infact I want the collection of all the i*j

18:27 rata_: is that possible using dotimes ?

18:27 rata_: no... then use for

18:28 vijaykiran: rata_: https://github.com/vijaykiran/project-euler-clojure/blob/master/Problem4.clj

18:28 rata_: (for [i (range 1 10), j (range 1 10)] (* i j))

18:28 vijaykiran: rata_: ok, let me try with for

18:29 rata_: drewr: that's for multifns, not for any object

18:32 amalloy_: according to the source code, I imagine you could use .hasValue as the predicate, but (.hasValue (promise)) doesn't work for me, don't know why

18:32 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L5951

18:33 linusericsson: what's the name of the nifty parenthesis autocompletition of Slime/emacs?

18:34 && how can I enable ctrl (arrowup) in the slime REPL?

18:34 sexpbot: java.lang.Exception: Unable to resolve symbol: & in this context

18:34 amalloy_: linusericsson: paredit

18:34 what do you want C-<UP> to do? command history? that's M-p by default

18:35 linusericsson: @amalloy_ Thx! && Thx!

18:36 you seriously made my day!

18:36 amalloy: enjoy :)

18:40 riddochc: Okay, I've definitely narrowed this down. The definition of m-fmap in contrib/monads triggers the error, "Can't dynamically bind non-dynamic var"

18:41 It's not a problem with its use of m-bind, exactly, because the previous definitions of m-lift and m-join don't trigger the error.

18:43 rata_: amalloy: does (.hasValue (promise)) work for you?

18:44 amalloy: rata_: no, and (show (promise)) doesn't list a hasValue method either; where did you find it?

18:44 rata_: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L5951

18:48 amalloy: ^

18:50 amalloy: rata_: that might be a new 1.3 feature

18:52 rata_: amalloy: well, I think that's what you need =) or put the print inside the sandbox call (is it a macro or a fn?)

18:52 amalloy: rata_: it's a function, but either way i think it's equally simple

18:54 rata_: yes, it just that I don't know if the verb used for macros is to call also :P

19:04 * riddochc posts to list.

19:05 riddochc: I bet someone else can figure this out a lot faster than I can.

19:15 amalloy: rata_: good question actually. call is probably wrong, technically, but who knows/cares

19:31 wooby: macros are functions, they're just called at compile time :)

20:00 Raynes: If a Jira issue is marked as unresolved, but somebody somewhere has already fixed it and the fix is already in contrib, what does one to get that issue closed? Just comment that it's no longer applicable?

20:02 amalloy: Raynes: find the person who filed the issue and tell them to close it, right?

20:02 Raynes: I think commenting will suffice.

20:27 devn: trying out fnparse for the first time (or trying to... (while learning how to write a parser...))

20:27 amalloy: devn: fun. it's been a few years since i wrote any parsers

20:28 * devn has no idea what he's doing

20:28 devn: this is my first time

20:29 i just know that i want to write one to let people use HAML for their templates with clojure

20:29 amalloy: any suggested reading?

20:30 amalloy: devn: ummmm, mine was in college. we had some assigned book or other, but it was really dry

20:30 and i'm not sure how the functional/mutable divide affects things

20:32 but parsers are the most interesting part of compilers, so reading up on compilers will probably help. finite automata and pushdown automata were useful things to understand when writing a mutable parser

20:33 maybe see what kind of information flex/jflex and yacc/cups (c/java respectively) ask for when they build a parser

20:34 devn: yeah im starting to put bits and pieces together

20:34 amalloy: anyway i'm headed home now. good luck devn

20:34 devn: but there looks to be a lot to know

20:34 I can enumerate the tokens, but understanding how to handle indentation rules and such is difficult

20:34 ciao amalloy

20:44 rata_: devn: have you looked at the examples that come with fnparse?

20:45 devn: also, here's an interesting post http://slyrus.github.com/2010/09/17/parsing-smiles-with-fnparse.html

20:53 devn: rata_: cool, thanks

20:53 i've looked at the JSON parser but it is still a bit beyond my skill level I think

20:53 fbru02: when would guys recommend using STOMP instead of json ?

20:53 devn: fbru02: as soon as the girls do it ;)

20:54 fbru02: devn: are they hoy?

20:56 rata_: devn: welcome :) that link explain some bits of a parser step-by-step, hope it helps

20:57 devn: rata_: the info on hound so far is great

20:57 thanks again

20:57 rata_: =)

21:12 gfrlog: ,(eval (repeat 5 'vector))

21:12 clojurebot: DENIED

21:12 gfrlog: ,(vector 'vector 'vector 'vector)

21:12 clojurebot: [vector vector vector]

21:12 gfrlog: I think that would be even more fun if my name were Victor

23:06 riddochc: I'm sure this is an easy question, but it's evading me... I'd like to have a lazy sequence of characters from a reader. There's line-seq, but not char-seq.

23:06 I'm sure I can do this with a sequence function or two, but it's not coming to me.

23:07 Zba2Y7Pr3: $source line-seq

23:07 sexpbot: line-seq is http://is.gd/kgWop

23:08 Zba2Y7Pr3: riddochc: Surely, you can just adapt the line-seq (as defined above) into char-seq with ease.

23:08 amalloy: riddochc: (repeatedly #(.read r))?

23:08 Zba2Y7Pr3: riddochc: Just use (.read rdr) instead of (.readLine rdr).

23:08 (and not require rdr to be BufferedReader, but just Reader.)

23:09 riddochc: Cut and paste for the win, amirite?

23:10 riddochc: Zba2Y7Pr3: Sure, I guess. I suppose I was going for something more like amalloy's solution, but I'll need to deal with EOF...

23:10 amalloy: riddochc: take-while will handle that

23:11 riddochc: amalloy: Cool, thanks.

23:12 hiredman: (doc instance?)

23:12 clojurebot: "([c x]); Evaluates x and tests if it is an instance of the class c. Returns true or false"

23:21 riddochc: amalloy: Hmm. repeatedly seems to give an infinitely repeating sequence of the results of calling the function once, rather than actually giving a sequence of the results of calling the function over and over. :)

23:22 amalloy: &(take 10 (repeatedly rand))

23:22 sexpbot: ⟹ (0.5986945969999783 0.5934446983371355 0.17555572971645572 0.2200530400344024 0.4922304862838399 0.23857009757987335 0.8506081527117483 0.5500754080616745 0.4780380877552357 0.5879140724603221)

23:22 riddochc: Er, no, nevermind.

23:22 * amalloy thinks riddochc is wrong

23:22 riddochc: Here's an interesting one...

23:22 Ahh. (repeatedly #(.read (reader r))) will continually re-open the stream.

23:23 Zba2Y7Pr3: Well, yeah. You don't want to do that. :-P

23:24 riddochc: (not= #(let [rdr (reader r)] (repeatedly #(.read %))) (fn [r] (repeatedly #(.read (reader r)))))

23:33 amalloy: riddochc: well, i guess if any of your files have at least one byte there would be a difference, yeah, but who needs such huge files

23:37 riddochc: amalloy: Heh. And I thought I was referring to the functions, not the output of them.

23:38 amalloy: wellllll, your first example has nested #()s so it's not exactly a function :P

23:39 riddochc: amalloy: Eh, true. So, I'm not quite as up on Java as I am on other languages... it looks like .read returns an Integer, in the range 0-65535. It *looks* like it's reading bytes, but I'm not quite sure.

23:40 amalloy: riddochc: depends whether you're reading a Reader or a Stream

23:41 riddochc: The implication seems to be that .read could really a variable number of bits, 16, or 8, or maybe something else, too, depending on the encoding.

23:42 amalloy: both classes return an int: either some meaningful piece of data, or -1 for EOF

23:42 Stream.read "normal" values are 0-255 because they read bytes

23:42 Reader.read "normal" values are 0-65535 because they read UTF-8 characters

23:43 &1

23:43 sexpbot: ⟹ 1

23:43 amalloy: riddochc: try pasting that arrow into a text file: it's a two-byte character that (.read (reader foo)) will return in one go

23:44 riddochc: amalloy: Oh, fun. So, if I know I want to be working on bytes, because the format I'm working with can include binary data.

23:44 amalloy: then you don't want a reader

23:44 you want an inputstream

23:45 riddochc: Huh. That arrow comes up as 10233.

23:45 amalloy: http://clojure.github.com/clojure/clojure.java.io-api.html#clojure.java.io/input-stream

23:46 &(int ⟹)

23:46 sexpbot: java.lang.Exception: Unable to resolve symbol: ⟹ in this context

23:46 amalloy: &(int \⟹)

23:46 sexpbot: ⟹ 10233

23:46 amalloy: &(char 10233)

23:46 sexpbot: ⟹ \⟹

23:46 riddochc: Yup.

23:50 amalloy: $source promise

23:50 sexpbot: promise is http://is.gd/kh36e

23:53 amalloy: argh seriously, even in 1.3.x there's no class for promises? how can i find out if a given object is a promise?

Logging service provided by n01se.net