#clojure log - Jan 16 2011

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

0:00 Gigaroby: guys is there any map that take care of order of keys ?

0:00 timmc: A sorted map, you mean?

0:00 Gigaroby: no

0:00 one that mantains the order of keys

0:00 amalloy: Gigaroby: insertion order? then no

0:00 Gigaroby: amalloy, ah ok

0:00 amalloy: that's not a map anymore, it's a vector

0:01 Gigaroby: amalloy, thanks I will use metadata then

0:38 amalloy: Gigaroby: i don't understand how metadata can solve your problem. the point of hashmaps is they have constant(ish)-time lookup of known keys

0:39 Gigaroby: amalloy, all right but I also need to keep track of the order of the keys I insert

0:39 amalloy: if you want to look up a key based on something like its metadata, you'll have to scan through all the keys in the map

0:40 Gigaroby: metadata isn't a terrible solution if you won't ever be looking things up based on the metadata

0:40 but my style would be to have a map more like {:key [:data :time], :key2 [:data2 :time2]}

0:41 Gigaroby: amalloy,

0:41 I need

0:41 to have vectors as keys and vectors of vectors as values

0:42 amalloy: okay....

0:42 Scriptor: er...

0:43 Gigaroby: {[0 1] [[1 2] [3 4]] [1 3] []}

0:44 and I want to add keys at the end of this

0:44 and also remove at the end of this

0:45 amalloy: i don't see what this has to do with my suggestion to use [time, data] pairs as the values in your map

0:45 Scriptor: Gigaroby: could you explain what you need this for? We might be able to give a better suggestion

0:47 Gigaroby: well I want to solve the knight tour problem and I have to use the current position as key and the list of possible next moves as values

0:47 Scriptor: ah, so you're using vectors as coordinates

0:47 Gigaroby: yes

2:13 amalloy: guys, it's so quiet in here. are all the disreputable clojurians out partying?

2:41 Dranik: hi all!

2:41 I need to generate all tuples [0-10; 0-10]. What is the most idiomatic way?

2:45 pdk`: can you draw up an example by hand of what the output would look like

2:46 [0-10; 0-10] i'm not quite following on what the expansion would be there

2:46 mids: maybe (for [x (range 11) y (range 11)] [x y])

2:47 Dranik: [0;0] [0;1] [0;2] ... [5;0] [5;1] [5;2] .... [9;0] [9;1] ....

2:47 mids, I'll give it a try, thanks

2:49 btw, what is the most idiomatic way to read a text file and get a sequence of lines?

2:52 mids: clojure.contrib.duck-streams/read-lines

2:52 Dranik: mids, thanks!

2:53 mids: dont be scared to use google though ;)

2:55 pdk`: ,(for [x (range 4) y (range 4)] [x y])

2:55 clojurebot: ([0 0] [0 1] [0 2] [0 3] [1 0] [1 1] [1 2] [1 3] [2 0] [2 1] ...)

2:55 pdk`: yep

3:01 Dranik: what is the key difference between (fn[] ...) and #(...)? I can use fn in reduce but clojure doesn't want to use #() in reduce...

3:02 pdk`: #() is a shorthand for anonymous functions

3:02 copy the line you're trying to write, keep in mind you use %x syntax instead of named arguments in #() functions

3:02 ossareh: Dranik: they're the same for all intents and purposes - the (fn) form is probably easier for your reduce since you can be very clear with your variables

3:03 pdk`: so i don't state up front what arguments the #() function takes

3:03 instead i refer to them as %1 %2 etc in the order they're passed

3:03 Dranik: oh well, I've just tested it, and it works. Tanks!

3:07 pdk`: you can test lines straight in the chat with ,

3:09 mids: ,(println "ORLY?")

3:09 clojurebot: ORLY?

3:09 mids: :)

3:11 amalloy: Dranik, mids: surely line-seq is more sensible than read-lines?

3:11 Dranik: amalloy, thank, I'll check it out

3:12 amalloy: ossareh, Dranik: the difference between (fn[]) an #() is that the former can be nested; if you tried to nest #(map #(+ %1 %2)) forms, the compiler couldn't know which parens belonged where

3:13 er, which %s

3:57 LauJensen: Morning all

3:59 amalloy: hey LauJensen

4:12 LauJensen: amalloy: Do you know of a reliable cross platform way of enumerating USB devices and getting their product IDs?

4:12 amalloy: fraid not. way out of my jurisdiction

4:19 robonobo: hi, i have a namespace defined like this: (ns foo.foo (:use foo.help])), and i'm trying to call it from the repl with (use 'foo.foo), but that gives the error "java.lang.IllegalArgumentException: Parameter declaration reduce should be a vector". What am I doing wrong?

4:20 (use 'foo.help) does work

4:27 amalloy: robonobo: do you really mean (:use foo.help]? those parens don't match

4:28 robonobo: yeah, i meant (:use [foo.help])

4:28 amalloy: robonobo: ah. well, that's not right. you want either foo.help or [foo help]

4:29 actually i think there's a difference between [] and () in :use declarations, but honestly it's poorly documented. at any rate foo.help and (foo help) should both work

4:30 robonobo: so (ns foo.foo (:use foo.help)) ?

4:30 amalloy: righto

4:31 robonobo: i still get the same error with that

4:32 amalloy: robonobo: maybe gist/paste your code?

4:32 robonobo: k

4:34 amalloy: robonobo: https://github.com/amalloy/clojopts/blob/master/src/clojopts/ui.clj is a snippet from one of my projects that works

4:37 robonobo: now of course if I try to make a simple examle it does work

4:39 amalloy: *chuckle*

4:44 robonobo: amalloy: i've found my problem, it wasn't with the namespace

4:44 i was confused by the repl telling we it was on line 1

4:44 but that's the repl's line 1

4:45 i just put (defn func (...)) somwhere

4:45 without the []

5:49 zmyrgel: hi, would multimethods a good solution for repl modeling

5:50 I would need to have 'common' commands and then two 'sub-repl' which deal in their speciality commands + the 'common' commands

5:50 also is there some parser already done for this I could use?

5:52 now I have cond structure which first processes the common commands and if it can't find matching case it checks active repl type and continues to process that repl types commands

5:54 raek: a multimethod can be seen as an open case expression...

5:55 zmyrgel: ok, what about parsing

5:55 raek: (defmulti eval-top-level-command (fn [words] (first words))) ;; something like this?

5:56 zmyrgel: so that would choose the eval-top-level-command based on the commands first word?

5:56 raek: multimethods are just a bunch of functions with the same name. and then you give clojure some way of choosing the right function for a specific set of arguments

5:56 yes

5:58 zmyrgel: but wouldn't it give duplicate code.

5:58 raek: here I assumed that you passed the command line as a sequence of strings (or keywords or symbols). I have no idea how your code is organized

5:58 zmyrgel: I'm making chess engine with UCI and XBoard protocols with addition to my own 'protocol'

5:59 uci and xboard 'repl' should also have access to my own protocol's command processing

5:59 raek: would you consider (case (first words) "start" (...handle start command...) "stop" (...handle stop command...)) to contain duplicate code?

6:00 (you can have a default case too)

6:01 zmyrgel: I mean to 'extend' the default repl at runtime as I would extend Java base class

6:01 raek: the clojure repl?

6:01 zmyrgel: my own

6:01 chess engine repl

6:03 and I want to keep the engine repl types separate as if the uci repl is active the xboard repl commands are then invalid and vice versa

6:04 raek: maybe you could refactor the common code into its own function

6:04 and make it return nil or something if it does not recognize the command

6:04 zmyrgel: yeah

6:04 raek: and then your specialized repls could be functions with the same signature

6:05 zmyrgel: I would assume some inheritence system would be a good option

6:05 raek: that delegates everything to the common function first

6:05 zmyrgel: for example the 'help' command should print my default repl help and then the uci / xboard repls help

6:06 raek: you could perhaps represent a set of command as a map

6:06 then just (merge base-handlers {:foo foo-handler, :bar bar-handler})

6:07 which would add/override the :foo and :bar commands

6:07 protocols uses ordinary maps of functions as the way to do implementation sharing

6:08 zmyrgel: ok, gotta see how to proceed with that

6:08 any suggestions how to proceed with command parsing?

6:08 now I have very fragile system in place

6:09 raek: since functions are values in clojure, class inheritance is not the *only* way of sharing behaviour

6:09 zmyrgel: something like (case (first command) "move" (make-move (second command)))

6:09 raek: is there a common syntax, or does each protocol need to parse its commands in its own way?

6:10 or what do you mean by parsing here?

6:10 zmyrgel: I get single string as input and need to parse the engine commands from there

6:10 xboard repl is quite simple still

6:11 but now my repl crashes everytime if my command is incomplete

6:11 raek: do the protocols need to share parts of the parser?

6:11 zmyrgel: for the 'common' part

6:13 uci is bit more painful to parse

6:13 http://wbec-ridderkerk.nl/html/UCIProtocol.html

6:13 raek: the approach where you use a base handler and a more specific handler that delegates to the base handler first, and does its own handling if that failed could perhaps be applied to the parser problem too

6:13 zmyrgel: for example the go command is quite nasty

6:15 raek: i.e. define a common parser that returns nil on ivalid data. then let a specialized parser begin with (if-let [data (parse-common ...)] data (...do own parsing...))

6:15 hrm, that could be written as (or (parse-common ...) (...do own parsing...))

6:16 you could reverse the order if you want the specialized parser to be able to verride

6:17 zmyrgel: ok, I'll get back to work. Have meeting tommorrow regarding this so need to get something done first :)

6:19 raek: I hope this was somewhat useful. the point is: clojure does not have a single inheritence system. since functions are first-class values, you are expected to roll your own (which is not too complicated).

6:21 zmyrgel: yep, gave me some ideas

6:21 Slow and somewhat ugly process as this is my first real funtional programming project

6:39 can I somehow interrupt function to return it's value so far?

6:39 the goal is to interrupt the alpha-beta search to return the best move so far

6:40 the algorith processes the moves in loop within so to just return the current loops best-move value when I need it

6:40 mids: have it return a lazy sequence maybe?

6:41 mrBliss: zmyrgel: maybe an agent

6:42 zmyrgel: mids: how would that help?

6:42 I mean it takes like 30 secs to seek a move and xboard protocol defines command 'move now' which would make ai's move immidiately

6:42 so when I get the

6:43 so when I get the 'move now' command I would need to get the alphabetas best move

6:43 raek: zmyrgel: if you have a Future object (e.g. from a 'future' call), you can can call future-cancel on it to interrupt that thread

6:44 if the thread is in a blocking operation (other than reading from a socket), that blokcing operation will throw an InterruptedException

6:44 otherwise (if it's doing calculation) the interrupted status of the thread is set

6:45 you can design that code to regularly check that status, and abort if it finds it set

6:47 you can also use an atom to hold a "is interrupted?" value that you check regularly

6:50 zmyrgel: can't I just wrap it in try and then catch InterruptException and return current best move in there/

6:50 ?

6:51 raek: only blocking operations throw such an exception

6:52 e.g. taking an element from a currently empty LinkedBlockingQueue

6:52 or waiting for a lock

6:52 zmyrgel: ok

6:53 raek: so for a task that is only CPU bound, you have to design interruptability into it

6:54 zmyrgel: well the loop in the function holds the best-move which I need

6:54 sluggo: is the loop in its own thread?

6:54 zmyrgel: so at each loop iteration I check somehow if we have been interrupted and then return the best-move

6:54 sluggo: not at the moment

6:55 raek: zmyrgel: yes.

6:56 pauldoo: 'ello

6:56 zmyrgel: raek: and the obvious followup, how to check if the function is interrupted?

6:56 raek: (let [f (future ...call best moving finding function...)] (try (.get f 30 TimeUnit/SECONDS) (catch TimeoutException _ (future-cancel f) @f)))

6:57 zmyrgel: http://download.oracle.com/javase/6/docs/api/java/lang/Thread.html#interrupted()

6:57 pauldoo: how would I create a sequence which is the result of calling a zero argument function (rand say) N times..

6:57 (map (fn [_] (rand)) (repeat 10 nil)) is the best I can come up with

6:58 but it seems a bit pants..

6:58 zmyrgel: raek: ok, thanks

6:58 raek: hrm. this will not work as I though...

6:58 cancelling the future makes the deref throw a CancellationException

6:58 rather than return a result...

6:59 I got the semantics for futures and threads a bit mixed up

6:59 zmyrgel: it might be simpler to communicate when to stop with an atom instead.

7:00 mrBliss: pauldoo: ##(take 10 (repeatedly rand))

7:00 sexpbot: ⟹ (0.2759028873310243 0.6624371144084372 0.340050893492865 0.3204405251057306 0.7898043499624735 0.5132701706685107 0.21342042332892108 0.13312135339576658 0.026571457408496424 0.12350743903241035)

7:00 pauldoo: aha! :)

7:00 zmyrgel: ok

7:00 raek: (let [a (atom true), f (future ...call best moving finding function with a...)] (try (.get f 30 TimeUnit/SECONDS) (catch TimeoutException _ (reset! a false) @f)))

7:01 pauldoo: mrBliss: thanks - repeatedly is the awesome :)

7:01 raek: in the loop: (loop [best-move ...] (if @running ... best-move))

7:01 where running is the atom called 'a' before

7:01 zmyrgel: yep

7:40 fbru02: hey guys, i'm having a weird problem, i'm doing a map inside a macro and i don't know why after the macro resolves it tries to call the resulting list ? anyone ever had this problem ??

7:55 pauldoo: how do I remove a value from a map? (ie unassoc?)

7:57 arbscht_: ,(doc dissoc)

7:57 clojurebot: "([map] [map key] [map key & ks]); dissoc[iate]. Returns a new map of the same (hashed/sorted) type, that does not contain a mapping for key(s)."

7:58 pauldoo: aha.. :)

7:58 I can see me adding lots of "see also" to clojuredocs.org

7:59 arbscht_: isn't that already there?

8:23 pauldoo: it wasn't linked from assoc

8:45 rrc7cz: can somebody explain to me exactly how a method is invoked by (. o foo)? I've traced the source down to an ObjExpr fexpr, line 5421 of Compiler.java. The next line is simple a cast to IFn, then a call to invoke. Somehow it's taking the method in fexpr and calling invoke on that, but that's the part I'm missing

8:50 sgronblo: Hey can you get a better clojure repl that has auto-completion and maybe even some fancy syntax highlighting?

8:50 mrBliss: sgronblo: Emacs + SLIME

8:50 sgronblo: that goes against my religious beliefs :)

9:00 robonobo: how do i get a default on cond? just (cond (condition) (thing) (condition) (thing) (true) (default))?

9:00 or is there a more idiomatic way to do that?

9:01 true should be without brackets ofcourse

9:01 mrBliss: robonobo: :else is the convention

9:01 robonobo: ok

9:02 Raynes: &(cond (= 1 0) 10 true 20)

9:02 sexpbot: ⟹ 20

9:02 Raynes: &(cond (= 1 0) 10 :else 20)

9:02 sexpbot: ⟹ 20

9:05 mrBliss: Raynes: some more silly names for a book on Clojure: "Structure and Interpretation of Clojure Programs" (SICP), "On Clojure" (like PG's On Lisp), "The Art of Clojure Programming" (Knuth), "Clojure: The Good Parts (Everything)" (Crockford).

9:05 I really think you should stick with "Sexpbook" though :)

9:05 mids: The Holy Clojure

9:06 Raynes: Surprisingly, a lot of people think I should stick with "Meet Clojure".

9:07 I could compromise. I could name it "Meet Clojure: The Sexpbook" ;)

10:17 arkh: "Clojure: The Good Parts (Everything minus some Java warts)"

10:18 robonobo: java warts sounds like an awful condition

10:19 they're huge and they won't go away

10:19 arkh: could be worse: VB warts

10:19 robonobo: you monster!

10:19 arkh: ; )

10:23 Is there a macro written like the following? (filter coll_of_funcs coll)

10:24 opqdonut: what would it do?

10:24 arkh: act like filter but apply an arbitrary number of functions to each item in coll, returning the first non-nil value (and skipping any remaining funcs for that item in coll)

10:25 I have a bunch of re's I'd like to try to match on text and there's enough of them that I don't want to use regex ORs

10:26 opqdonut: just use some?

10:26 ,(doc some)

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

10:27 opqdonut: so something like (some #(re-match % the-string) collection-of-res)

10:27 arkh: oh, nice. That works

10:33 it's not pretty but maybe this will work: (for [s strings] (some (#re-find % s) collection-of-res))

10:33 kjeldahl: Anybody knows why congomongo returns my mongdb integers as doubles? Normal behaviour?

10:51 robonobo: is there an opposite of (nil? x)? not-nil?

10:56 kjeldahl: robonobo: Think not, only (not (nil? x))

10:56 robonobo: kjeldahl: bumme

10:56 r

10:56 opqdonut: ,(doc negate)

10:56 clojurebot: Titim gan éirí ort.

10:56 robonobo: what now?

10:56 opqdonut: hmmh, I was pretty sure negate would've been #(comp not %)

10:57 mrBliss: opqdonut: ##(doc complement)

10:57 sexpbot: ⟹ "([f]); Takes a fn f and returns a fn that takes the same arguments as f, has the same effects, if any, and returns the opposite truth value."

10:57 kjeldahl: robonobo: (defn not-nil? [x] (not (nil? x))) ??

10:57 opqdonut: ah, complement

10:58 mrBliss: robonobo: in which context do you need it? Usually you can just do (if x .. ..)

10:58 robonobo: for every? or some

10:58 mrBliss: then use identity

10:59 robonobo: i know i can do it with (not) but that's not pretty

10:59 mrBliss: ##(every? identity [nil 1])

10:59 sexpbot: ⟹ false

10:59 robonobo: ooh

10:59 opqdonut: ##(filter identity [false nil])

10:59 sexpbot: ⟹ ()

11:00 opqdonut: ##(filter #(not (nil? %)) [false nil])

11:00 sexpbot: ⟹ (false)

11:00 mrBliss: pay attention to ^^ though :)

11:23 Chousuke: remember also (remove nil? ...) :P

11:31 dedeibel: Hi there - I am new to clojure and have a little problem you might help me with. I have an agent of a vector of ints and want to get the doubled value of each of them. Now I would use "map" to calculate over all entries, but using "send" this is more difficult since the collection is set as second parameter and uses the agent value as the first parameter. Is there common way to solve the problem? A different function? I was having the problem

11:34 mrBliss: ,(let [a (agent [1 2 3])] (send a (fn [coll] (map #(* % 2) coll))) (await a) @a)

11:34 clojurebot: (2 4 6)

11:35 mrBliss: dedeibel: ^^ not the most elegant solution, but I can't think of anything better.

11:35 companion_cube: would (partial map #(* % 2)) replace (fn [coll] (map #(* % 2) coll)) ?

11:36 mrBliss: companion_cube: yes, that's better :)

11:38 dedeibel: ah

11:38 thanks, that look kind of nice

11:38 looks

11:39 so many handy functions/macros to learn at the beginning :-)

11:40 companion_cube: (doc) is imho very useful at the beginning

11:40 mrBliss: or (find-doc a-regex)

11:42 dedeibel: I also recommend http://clojuredocs.org/

11:44 dedeibel: Thank you. Looks well categorized. Mostly I am using the API reference on clojure.org and the wiki. But it sometimes lacks some examples which would speed up things.

11:44 Nice, I see, there are some one clojuredocs

12:03 pdk: i feel ya there

12:03 i had no idea what -> and ->> really did until i saw a code sample

13:18 gfrlog: does anybody know about using the input and output streams with nailgun?

13:43 phenom_: anyone here using emacs on a mac ?

14:04 wolverian: can I make a macro that generates a function whose name is a concatenation of a macro parameter and the question mark? I'm failing to use syntax (un)quoting correctly as this is my first macro.

14:04 opqdonut: ,(symbol (str 'wolverian "?"))

14:04 clojurebot: wolverian?

14:05 opqdonut: ;)

14:06 amalloy: &(let [name 'test] `(defn ~(symbol (str name "?")) [] (...)))

14:06 sexpbot: ⟹ (clojure.core/defn test? [] (...))

14:07 amalloy: wolverian: ^

14:10 wolverian: thanks!

14:17 huh. `(defn ~(symbol (str name "?")) ...) gives me the function #'user/(quote paramvalue)?

14:18 (where paramvalue is the symbol passed in name)

14:19 Raynes: Are you passing 'paramvalue or paramvalue? The quotes are significant.

14:20 wolverian: right, that was the problem. just realized it myself. thanks.

14:28 timmc: Yay! I just discovered Pico Editor. It is basically the perfect Clojure editor for my tastes.

14:28 tomoj: any lamina users in? consider (blocking (fn [_] @geo/filtered-pidls)) vs (blocking (constantly @geo/filtered-pidls))

14:28 timmc: (I.e., it has bugs and misfeatures that don't bother me.)

14:28 tomoj: will the second still block?

14:29 wolverian: and here I am, learning Emacs for the tenth time just to feel awesome using SLIME... :)

14:29 timmc: wolverian: I never did get the hang of emacs. I feel so inadequate. :-P

14:29 tomoj: yes, it will it seems :(

14:30 wolverian: timmc: it's probably even harder for me, since I've been using Vim since forever.

14:30 I'd just like to meet the person who gets vimclojure's repl support working. he must have superpowers.

14:31 timmc: I grew up with Windows -- the standard WIMP keybindings (C-s = save, etc.) are burned into my finger muscles.

14:32 gfrlog: timmc: I grew up with querty and switched to dvorak in a couple months. I'm sure switching to emacs can be done.

14:32 Raynes: C-x-C-s isn't that much of a leap.

14:33 TimMc: The hardest thing to change is block navigation. C-arrow and such.

14:34 tomoj: confirmed, the second blocks

14:34 TimMc: gfrlog: I was limping along with emacs about 6 months ago -- it can definitely be done -- but I've lost all my progress by now.

14:34 amalloy: TimMc: paredit uses C-arrow for some really handy list-manipulation commands

14:34 Raynes: I'm ashamed to say that I rarely use special movement key coords in Emacs.

14:34 I just use the mouse and arrow keys.

14:34 tendant: Hello, Can i ask how to use multi-bytes characters in slime-repl?

14:34 TimMc: amalloy: Much to my surprise. :-P

14:35 tendant: What OS?

14:35 tendant: ubuntu 10.10

14:36 TimMc: tendant: If you're using emacs in a terminal in Gnome, C-S-u gets you unicode input.

14:36 C-S-u 2 1 2 0 <space> prints the ℠ mark, for instance.

14:36 or... it should. Maybe emacs captures that?

14:37 Raynes: TimMc: Also something to think about: you could switch C-s with C-x-C-s and have your typical saving command and have C-x-C-s for searching.

14:37 TimMc: Raynes: Then I have two problems.

14:37 tendant: TimMc: I can type in those characters in emacs buffer. The problem is I cannot run clojure function containing multi-bytes chars.

14:37 Raynes: TimMc: Emacs isn't regex.

14:38 TimMc: Yes. But I would then have to learn *two* things to get back to using it: Emacs keybindings *and* configuration.

14:39 Raynes: That's a sure sign that Emacs isn't for you. You had it right the first time. ;p

14:40 TimMc: When was I right?

14:40 Oh! I get it.

14:40 (If you're not configuring emacs, you're not really using emacs.)

14:45 tendant: I have configured slime-net-coding-system like this: http://stackoverflow.com/questions/3101279/how-do-i-use-unicode-utf-8-characters-in-clojure-regular-expressions/3318137#3318137

14:47 but it still doesn't work

14:52 Luyt: I was always used to run clojure under diablo-jdk (freebsd), but I just verified it runs under OpenJDK-6 too.

15:01 markskilbeck: How would you go about changing the number 12345 into the collection [1 2 3 4 5]?

15:02 amalloy: &(map #(Integer/parseInt %) (str 12345))

15:02 sexpbot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.String

15:02 amalloy: &(map #(Integer/parseInt (str %)) (str 12345))

15:02 sexpbot: ⟹ (1 2 3 4 5)

15:03 amalloy: markskilbeck: if efficiency matters there are better ways, but this works

15:04 see also https://github.com/amalloy/bit-packer if you do care about speed, or want to use bases other than ten

15:04 markskilbeck: amalloy: it doesn't matter - just playing around, although I'll bookmark that repo.

15:04 And thanks.

15:05 robonobo: markskilbeck: is that for euler?

15:05 markskilbeck: robonobo: good guess.

15:05 robonobo: haha

15:05 markskilbeck: ;)

15:20 robonobo: what's the funciton to get the second element of a seq again?

15:20 s/funciton/function

15:20 sexpbot: <robonobo> what's the function to get the second element of a seq again?

15:21 amalloy: &(doc second)

15:21 sexpbot: ⟹ "([x]); Same as (first (next x))"

15:21 robonobo: why thank you

15:22 amalloy: hey robonobo, sexpbot has a cool feature to help you find the function you're looking for, btw

15:22 $findfn [8 10 22 1] 10

15:22 sexpbot: [clojure.core/second clojure.core/fnext clojure.core/rand-nth]

15:22 robonobo: wow

15:22 awesome

15:22 $findfn [8 10 22 1] 22

15:22 sexpbot: []

15:23 robonobo: broke it

15:23 amalloy: heh, no. there's just no function that does that

15:23 robonobo: yeah, i know

15:23 amalloy: $findfn [8 10 22 1] 2 22

15:23 sexpbot: [clojure.core/deliver clojure.core/nth clojure.core/get clojure.core/trampoline]

15:23 robonobo: is there a way i could do this in the repl?

15:23 i only know of (find-doc)

15:24 amalloy: robonobo: uhmmmm, the function was written in sexpbot for sexpbot. you could copy and paste it into your repl

15:24 or just /msg sexpbot if you don't want to clutter the channel

15:24 robonobo: oh, i see your the author

15:24 s/your/you're

15:24 sexpbot: <robonobo> oh, i see you're the author

15:25 amalloy: robonobo: kindasorta. __joshua wrote it; i helped and improved

15:26 robonobo: what would happen if you would give it something that would result in an infinite loop?

15:26 amalloy: robonobo: it's sandboxed with a timeout

15:26 $findfn (range)

15:26 sexpbot: []

15:27 amalloy: it tries all the functions it knows, giving each one up to (iirc) 50ms to see if it gives the desired results, and terminating it otherwise

15:28 robonobo: very cool

15:28 uhm

15:28 amalloy: um indeed

15:28 that has worked in the past

15:28 robonobo: did we break it?

15:29 _na_ka_na_: is there a way to include \n in . in regexes, doing (.|\n)+ looks ugly

15:30 on a related note why doesn't [.\n]+ work ?

15:31 amalloy: _na_ka_na_: metacharacters lose their special meaning inside []

15:32 _na_ka_na_: hmm found this

15:32 http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#DOTALL

15:32 how do i use the ?s flag

15:33 amalloy: #"(?s)....."

15:34 _na_ka_na_: i get this PatternSyntaxException Dangling meta character '?' near index 0

15:35 amalloy: &#"(?s)....."

15:35 sexpbot: ⟹ #"(?s)....."

15:35 phenom_: argh, why does my Aquamacs show ^X rather than C-x ?

15:35 amalloy: works for me

15:39 _na_ka_na_: oh my bad I skipped the () around ?s ..

15:39 works thanks!

15:41 TimMc: What is the idiomatic way to non-lazily execute a function n times?

15:41 amalloy: &(doc dotimes)

15:41 sexpbot: ⟹ "Macro ([bindings & body]); bindings => name n Repeatedly executes body (presumably for side-effects) with name bound to integers from 0 through n-1."

15:42 TimMc: Ah, fantastic!

15:42 _na_ka_na_: TimMc, also look at repeatedly if you care for return values

15:43 but that's lazy, so you'll need a doall

15:44 TimMc: _na_ka_na_: I was playing with `repeatedly`, but didn't know about `doall`. Thanks! (I'll stick with `dotimes` though.)

15:46 _na_ka_na_: TimMc, just make a note that with dotimes you wont capture the return values

15:46 TimMc: One of these days I will skim through the entire clojure.core API so I know about all of these things.

15:47 _na_ka_na_: suppose I'm reading a file, after reading a few times I decide ok now I need to read the entire file in memory (from here on), how do I slurp the reader (from its current position) ?

15:49 s/after reading a few times/after reading a few lines/

15:49 sexpbot: <_na_ka_na_> suppose I'm reading a file, after reading a few lines I decide ok now I need to read the entire file in memory (from here on), how do I slurp the reader (from its current position) ?

15:50 cobol_expert: are defrecord's visible outside the package in which they're defined? I'm having a heckuva time trying to :use one

15:51 amalloy: cobol_expert: they're java classes: import, not use

15:51 cobol_expert: ah! thanks!

15:51 _na_ka_na_: aah looking at slurp's source, it does exactly what I want, if only it took a reader as input!

15:57 amalloy: _na_ka_na_: (clojure.string/join \newline (line-seq reader))?

15:58 _na_ka_na_: amalloy, yeah but something like slurp-reader will be so cool

15:58 plus no worries about the kind of \newline

15:59 &(= \newline \n)

15:59 sexpbot: ⟹ false

15:59 _na_ka_na_: why is that false?

16:00 &(int \newline)

16:00 sexpbot: ⟹ 10

16:00 _na_ka_na_: &(int \n)

16:00 sexpbot: ⟹ 110

16:00 _na_ka_na_: &(int \r)

16:00 sexpbot: ⟹ 114

16:01 amalloy: _na_ka_na_: \n is the character 'n'

16:03 _na_ka_na_: amalloy, aah yes i realized as soon as i saw the ascii table

16:04 &(= (str \newline) "\n")

16:04 sexpbot: ⟹ true

16:10 wolverian: is there a standard version of def that can define multiple bindings? e.g. (deffoo x 2 y 3)?

16:13 amalloy: wolverian: none that i know of

16:14 wolverian: okay. macroing it was easy enough.

16:14 amalloy: are you sure that's really what you want anyway? perhaps (def config-settings {:x 2 :y 3}) would suit your purposes better

16:15 wolverian: yeah, it probably would, in the long run (i.e. when I'm out of hack hack hack mode)

16:19 amalloy: wolverian: careful, it's easy to stay in that mode and end up with an annoying pile of trash

16:25 wolverian: yeah. fixing my macros now.. :)

16:27 is there a form (condfoo value & clauses) where a clause is a pair pred body, and the first (pred value) true is chosen?

16:28 i.e. like cond except the same value is given to each predicate automatically

16:30 kjeldahl: Anybody know why congomongo/mongodb returns my ints as doubles? I.e. an integer value 1 in the document is returned as 1.0 when used with Clojure (not in the mongo shell).

16:30 raek: it could perhaps be done with condp

16:31 wolverian: condp is the reverse of what I want, sort of.

16:31 raek: ,(condp #(%1 %2) "foo" number? :number string? :string)

16:31 clojurebot: :string

16:32 wolverian: yeah, that works. thanks :)

16:32 robonobo: kjeldahl: maybe you could try the congomongo mailing list (http://groups.google.com/group/congomongo-dev)

16:34 kjeldahl: robonobo: Yeah, I'll try. It has a total of 18 messages or so since inception this summer, so I'm not crossing my fingers.. :-)

16:35 robonobo: kjeldahl: or you could try the mongodb irc

16:35 amalloy: yeah, i got decent help in their irc channel

16:35 the one time i wandered in

16:37 robonobo: kjeldahl: why don't you just use (int)?

16:39 kjeldahl: robonobo: Yeah, I can hardcode those, like I did to stringify the _id (to make it easier to jsonify the docs), but differently from the _id, those ints typically appear more places.. And it doesn't seem to make sense. Thanks anyway.

17:13 phenom_: hey folks, people using aquamacs here ?

17:18 ounce9: hi yes

17:18 phenom_: ounce9: in the minibuffer, does C-x show up at ^X for me?

17:18 _na_ka_na_: can anyone tell me where can I download the complete clojure-contrib-1.3.0-alpha4.jar ?

17:19 building clojure-clojure-contrib-3daaafd produces an empty jar for me

17:19 phenom_: did you do mvn install ?

17:19 and dd it build all the modules ?

17:19 _na_ka_na_: no I'm checking in modules/complete/target

17:19 I did mvn assembly:assembly

17:20 do I need to mvn compile before that?

17:20 phenom_: you need to run "mvn instal"

17:20 _na_ka_na_: but I just want to build

17:20 phenom_: * mvn install

17:20 _na_ka_na_: not install

17:20 phenom_: i know, it'll build

17:21 _na_ka_na_: ok if you say, running install

17:22 ounce9: I get C-x-

17:22 not sure what you mean

17:23 phenom_: it's weird ... i get "^X"

17:24 ounce9: may be a version thing

17:25 _na_ka_na_: phenom_, its still empty

17:26 the complete-1.3.0-alpha4.jar

17:26 phenom_: in /modules/complete/target ?

17:26 _na_ka_na_: mvn install says build successful

17:26 yup

17:26 phenom_: hmmm

17:26 you may have downoaded the wrong zip file ?

17:27 _na_ka_na_: I have clojure-clojure-contrib-1.3.0-alpha4-0-g3daaafd.zip

17:27 do you have link to the correct one?

17:28 phenom_: https://github.com/clojure/clojure-contrib/zipball/1.3.0-alpha4

17:30 _na_ka_na_: that's the one i have

17:31 phenom_: then something is definately up with your build

17:31 i used that just earlier today to do a build (which took quite a long time)

17:32 what is your terminal output telling you ?

17:33 _na_ka_na_: trying again

17:38 same problem

17:38 here's the build output

17:38 [INFO] Unnamed - org.clojure.contrib:standalone:jar:1.3.0-alpha4 SUCCESS [5.106s]

17:38 [INFO] Clojure Contrib ....................................... SUCCESS [0.075s]

17:38 [INFO] ------------------------------------------------------------------------

17:38 [INFO] ------------------------------------------------------------------------


17:38 [INFO] ------------------------------------------------------------------------

17:38 [INFO] Total time: 2 minutes 54 seconds

17:39 phenom_, can you share the jar

17:39 Raynes: _na_ka_na_: http://gist.github.com

17:40 raek: http://build.clojure.org/releases/org/clojure/clojure/1.3.0-alpha4/

17:40 Mimisbrunnr: wow

17:40 raek: http://build.clojure.org/releases/org/clojure/clojure/1.3.0-alpha4/clojure-1.3.0-alpha4.jar

17:41 _na_ka_na_: Raynes, sorry my bad

17:42 raek, I need contrib alpha4

17:42 raek: http://build.clojure.org/releases/org/clojure/contrib/complete/1.3.0-alpha4/ ?

17:43 or check the contrib/ dir for the module you want

17:43 _na_ka_na_: thanks I was looking in the clojure-contrib directory

17:45 raek, even this is empty size 1.8K ?

17:46 raek: strange

17:47 hrm, or was complete the module that depended on all the others?

17:47 http://build.clojure.org/releases/org/clojure/contrib/standalone/1.3.0-alpha4/standalone-1.3.0-alpha4.jar

17:48 seems so. this might be the whole thing ^

17:54 _na_ka_na_: raek, thanks that does seem to be the one

17:54 but when I use it I get this error: https://gist.github.com/782233

18:48 TimMc: Is there any way to type a float literal in Clojure?

18:48 dsop: (float x)?

18:48 TimMc: :-/

18:49 That's a type coercion.

18:49 dsop: then i dont know

18:50 amalloy: &0.1f maybe?

18:50 sexpbot: java.lang.NumberFormatException: Invalid number: 0.1f

18:52 amalloy: TimMc: (float 0.1) should resolve at compile time, making it effectively a literal

18:53 TimMc: amalloy: I was hoping for something more succinct to write. :-(

18:53 amalloy: TimMc: why do you need a float?

18:55 TimMc: amalloy: http://download.oracle.com/javase/6/docs/api/java/awt/geom/Path2D.Float.html#curveTo%28float,%20float,%20float,%20float,%20float,%20float%29

18:57 I need 6 of them.

19:03 dnolen: ,0.1

19:03 clojurebot: 0.1

19:03 dnolen: ,1.1e6

19:03 clojurebot: 1100000.0

19:04 dnolen: in 1.3.0 that's a float literal.

19:04 double literal I mean

19:04 timmc: ^

19:04 amalloy: dnolen: he's looking for actual floats

19:06 Raynes: I, myself, don't care for doubles. I don't use any numbers that can't keep me at the top of the water.

19:07 amalloy: TimMc: you could try (clojure.lang.Reflector/invokeMatchingMethod foo (map float [.1 .1 . 1 .1 .1 .1]))

19:09 or...something like that. i don't use it so i dunno the syntax but clojure.lang.Reflector might be interesting to you

19:17 TimMc: blerg

19:17 I'm not *that* interested in having literals.

20:00 phenom_: are there any online resources that are a good intro to clojure ?

20:00 something like a learnyousomeclojure

20:05 TimMc: Isn't one of the Clojure books free for download?

21:46 bdesham: hi all

21:47 I'm running Clojure with Java 1.6.0 on OS X. importing java.awt.geom.Line2D works fine, but java.awt.geom.Line2D.Float gives a ClassNotFoundException. any idea what I should look at?

21:48 Raynes: bdesham: Is Float an inner class?

21:48 bdesham: heh

21:48 Raynes: yes, over on ##java they told me that it is

21:49 but I don't have enough java experience to understand quite what that means

21:49 Raynes: I believe, but don't quote me on this, that the syntax for accessing inner classes is $. So, java.awt.geom.Line2D$Float

21:49 bdesham: if it helps, I also tried importing java.awt.geom.Line2D and then using (Line2D.Float. 1.0 1.0 1.0 1.0), but got the same error

21:49 Raynes: I'll try that

21:50 amalloy: ugh, the xxx.Float/Double classes in java.awt are a gross example of devs using a new feature (inner classes) just because it's new

21:50 (import java.awt.geom.Line2D$Float)...(Line2D$Float. args) is how you do it, i think, bdesham

21:52 bdesham: hmm

21:52 well now I'm getting "Unable to resolve classname" instead of a ClassNotFoundException

21:53 Raynes: amalloy: I don't think he has to import the inner class, but the outer class. Right?

21:53 amalloy: Raynes: not sure

21:53 &java.awt.geom.Line2D$Double

21:53 sexpbot: ⟹ java.awt.geom.Line2D$Double

21:54 amalloy: &(import java.awt.geom.Line2D)

21:54 sexpbot: ⟹ java.awt.geom.Line2D

21:54 amalloy: &Line2D$Double

21:54 sexpbot: java.lang.Exception: Unable to resolve symbol: Line2D$Double in this context

21:54 amalloy: &(import java.awt.geom.Line2D$Double)

21:54 sexpbot: ⟹ java.awt.geom.Line2D$Double

21:54 amalloy: &Line2D$Double

21:54 sexpbot: ⟹ java.awt.geom.Line2D$Double

21:54 bdesham: aha

21:54 amalloy: Raynes: BLAM! i win

21:54 bdesham: what seems to work is (import 'java.awt.geom.Line2D$Float) ... (Line2D$Float. 1 1 1 1)

21:55 amalloy: isn't...isn't that exactly what i said, bdesham?

21:55 (PS you don't need to quote imports)

21:55 bdesham: hehe

21:56 I think what I tried after your suggestion was (import 'java.awt.geom.Line2D) only, and then using Line2D$Float

21:56 but you need to include the inner class name in the import too

21:56 so yes, you were right ;-)

21:56 thanks all

21:56 amalloy: yeah, it's a bit silly. but the explanation is, at the bytecode level inner classes (more or less) don't exist

21:57 they're just regular classes with a $ in the name

21:58 bdesham: I see

22:27 what's the difference between importing a class via (:ns whatever (:import (java.something class))) and later via (import java.something.class) ?

22:34 _na_ka_na_: bdesham, the only difference is that you can refer to the shorthand 'class' in 'whatever' ns only after the import

22:34 amalloy: bdesham: one of them is in the ns form, the other isn't :P

22:34 tonyl: AFAIK, (ns (:import ...)) uses import inside

22:34 amalloy: ie, there isn't one

22:34 bdesham: oh, ok

22:34 well that clears that up then ;-)

22:35 amalloy: bdesham: fwiw, the (foo.bar baz) vs foo.bar.baz distinction is unrelated to ns vs non-ns

22:38 bdesham: that's a nice thing to keep in mind

22:40 is is possible to define a multimethod of two arguments where only one is dispatched on?

22:40 for example, (f x y) gets routed to (f1 x y) or (f2 x y) depending on the value of (g x)

22:41 _na_ka_na_: bdesham, yes, just define dispatch-fn as (fn [x _] (g x))

22:42 bdesham: excellent, thanks

22:42 I knew there was something I was missing

22:42 that's an example of destructuring, right?

22:43 _na_ka_na_: no, that's just regular fn parameters, _ is a symbol like x, y

22:44 (let [[x y] [1 2]] ..) is an example of destructuring

22:44 where you de-structure [1 2]

22:45 if x were [x1 x2], we could have written (fn [[x1 x2] y] ..) essentially de-structuring x

22:45 Scriptor: if instead of [1 2] you had [z 2] or something like that, would it still try to destructure or say that y is undefined in the current scope?

22:46 _na_ka_na_: &(let [[x y] [1 2]] [x y])

22:46 sexpbot: ⟹ [1 2]

22:46 _na_ka_na_: &(let [[x y] [1 2 3 4]] [x y])

22:46 sexpbot: ⟹ [1 2]

22:47 _na_ka_na_: &(let [[x y] [1 [2 3 4]]] [x y])

22:47 sexpbot: ⟹ [1 [2 3 4]]

22:47 _na_ka_na_: &(let [[x y] [1] [x y])

22:47 sexpbot: java.lang.Exception: Unmatched delimiter: )

22:47 _na_ka_na_: &(let [[x y] [1]] [x y])

22:47 sexpbot: ⟹ [1 nil]

22:47 Scriptor: er, what does the ? mean?

22:47 oh

22:48 _na_ka_na_: &(let [[x y] [[1 2] [3 4]]] [x y])

22:48 sexpbot: ⟹ [[1 2] [3 4]]

22:49 Scriptor: so having the nested vector literals inside it causes it to try to destructure?

22:51 amalloy: Scriptor: every let form "tries" to destructure

22:51 _na_ka_na_: &(let [[x y] (list (list 1 2) (list 3 4))] [x y])

22:51 sexpbot: ⟹ [(1 2) (3 4)]

22:52 _na_ka_na_: &(let [[x y] '((1 2) (3 4))] [x y])

22:52 sexpbot: ⟹ [(1 2) (3 4)]

22:52 amalloy: it does so by taking each *complete form* on the left (first in the pair, anyway), and assigning the matching other form

22:53 for simple symbols that's a simple assignment; for vectors and maps it involves recusive destructuring

23:17 TimMc: I can't find good documentation on all the forms I can use in an (import ...) statement.

23:18 I could swear there's a way to "rename" the Java classes I import, but I can't find complete docs.

23:18 amalloy: TimMc: i don't think that exists

23:18 tonyl: As far as i know there isn't

23:19 I don't know if alias might do it

23:19 TimMc: So you can only rename namespaces?

23:20 amalloy: $source import

23:20 sexpbot: import is http://is.gd/TYmLaD

23:21 amalloy: TimMc: when in doubt, read the source. there's no allowance for anything complicated in import

23:21 TimMc: I don't know enough Clojure to read that yet.

23:21 But I'll take your word for it.

23:22 amalloy: TimMc: import is just turning (import (foo bar baz)) into (import* foo.bar) (mport* foo.baz)

23:22 TimMc: Ah.

23:23 tonyl: and since java class names are not symbols we can't alias them

23:26 TimMc: So I'm stuck with java.awt's RenderingHints?

23:28 tonyl: What does that mean, "not symbols"?

23:29 tonyl: symbols are use to bind a name (symbol) with a value

23:29 alias let's you create an alias for a symbol

23:30 like (alias 'cstr 'clojure.string) would create a cstr as a shortcut for clojure.string

23:30 amalloy: tonyl: check out Namespace.java - it looks like there's code for binding any symbol to any class name

23:30 tonyl: great, thanks amalloy

23:30 amalloy: i'm not sure if it's possible to get at that code though :P

23:30 TimMc: amalloy: Where's this now?

23:31 tonyl: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Namespace.java

23:31 amalloy: line 123 or so

23:50 tonyl: I can't seem to find a straight answer to what thunk means

23:51 in the context of Symbol.java , does anyone have an idea?

23:51 thunk: <joke here>

23:51 tonyl: hehe

23:51 Scriptor: tonyl: can you link us to the line in the source, if there is one?

23:52 tonyl: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Symbol.java#L40

23:56 it might be an old comment that has nothing to do with the current code, I don

23:56 I don't know, but it got me thinking

23:57 Scriptor: nope, not an old comment, here's the original commit : https://github.com/clojure/clojure/commit/01e67b1f2070b1e862e2e4e55680513943be58fb

23:57 amalloy: tonyl: a function taking no arguments

23:58 Scriptor: that's all? And here I was trying to figure out how unevaluated pieces of code had anything to do with it :P

23:58 amalloy: Scriptor: they're synonymous if you look at it right

23:58 tonyl: but the function does take arguments

Logging service provided by n01se.net