#clojure log - Aug 07 2011

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

0:21 seancorfield: on the subject of reflection... i was trying (and failing) to call setter on a Field the other day

0:22 i was working with the MongoOptions object - which is a class with all public fields with int and boolean types

0:23 and i wanted to be able to set them dynamically, mapping :auto-connect-retry true to the autoConnectRetry boolean field

0:23 i got the Field (easy) but couldn't use .set because that only works for non-primitive fields

0:24 so I got the (primitive) type of the field and got the setter name (setInt, setBoolean) and tried to dynamically invoke that using .invoke method field object-array

0:25 but i couldn't get it to work... kept failing to convert the now object value down to the primitive for the typed setter

0:26 in the end i copped out and wrote wrappers for .setInt and .setBoolean and just called those on the Field instead

0:26 for the amount of effort, i might as well have just written wrappers for all of the MongoOptions fields!

0:44 zvrba: the joy of clojure book says that javadoc function is automatically available in core

0:44 as of version 1.2. yet, it is not. {:major 1, :minor 2, :incremental 1, :qualifier ""}

0:44 the interpreter says "unable to resolve symbol"

0:46 seancorfield: ,(doc javadoc)

0:46 clojurebot: Titim gan éirí ort.

0:47 seancorfield: &(doc javadoc)

0:47 lazybot: java.lang.Exception: Unable to resolve var: javadoc in this context

0:47 seancorfield: &(doc clojure.java.javadoc/javadoc)

0:47 lazybot: java.lang.Exception: Unable to resolve var: clojure.java.javadoc/javadoc in this context

0:48 seancorfield: when i did (doc javadoc) in the REPL, that's where it said it was

0:48 zvrba: hmm?

0:48 seancorfield: and typing (javadoc java.lang.Thread) in the REPL takes me to the Java 6 page for Thread

0:49 zvrba: how are you you running "the interpreter"?

0:49 zvrba: i'm running REPL within emacs. started with clojure-jack-in

0:50 i created a dummy project with leiningen just for that

0:50 (as the docs say clojure-jack-in must be run from within a project)

0:50 seancorfield: i just fired up a bare REPL like this: java -cp clojure-1.2.1.jar clojure.main

0:50 it found javadoc just fine

0:50 and it finds it when i do lein repl as well

0:50 but i'm not familiar with emacs

0:51 zvrba: it works from lein repl too

0:52 (it returns just an URL string)

0:52 seancorfield: it should open a browser to that URL

0:52 at least, that's what it does for me :)

0:53 zvrba: oh, it did that too

0:53 opened a new tab in an opera window

1:03 seancorfield: i just tried a REPL in Eclipse with CCW and it works just fine there (it even managed to open a browser window which surprised me)

1:03 so it's something about emacs and clojure-jack-in i suspect

1:22 jimblomo: should I prefer binding to with-bindings unless I already have a map of Vars?

1:37 amalloy: yes, i think the only reason to use with-bindings is if you have var objects instead of their names

1:39 (having just used with-bindings a bunch recently and not really liked it :P)

1:47 srid: the joy of clojure <- this is how programming books should be written.

1:47 * srid is on page 63

2:24 jimblomo: is there a way to programatically create namespaces such that they can be (use) or (required)?

2:25 amalloy: &(doc create-ns)

2:25 lazybot: ⇒ "([sym]); Create a new namespace named by the symbol if one doesn't already exist, returns it or the already-existing namespace of the same name."

2:25 jimblomo: so in the repl, I created a namespace

2:25 but I still couldn't (use) or (require) it.. hmm maybe i'll try refer

2:26 amalloy: refer is the only one that's definitely wrong

2:26 you should probably clarify what you actually did, because you've described something that in theory should work

2:26 jimblomo: user=> (create-ns 'my.new.namespace)

2:26 #<Namespace my.new.namespace>

2:26 user=> (use 'my.new.namespace)

2:26 user=> java.io.FileNotFoundException: Could not locate my/new/namespace__init.class or my/new/namespace.clj on classpath: (NO_SOURCE_FILE:0)

2:27 amalloy: ah. well, you've created it, so it's already loaded

2:27 you don't have to require it

2:28 jimblomo: oh i see, so i can refer to it straight out

2:32 then i can use intern to set new Vars

2:33 amalloy: sure

2:33 though if you're doing it programmatically and want to use intern, you don't need to refer

2:33 refer is only a convenience for the programmer

2:33 jimblomo: ^

2:34 jimblomo: yea, i was thinking of how a user of my library would refer to the namespace

2:34 otherwise it would just be magically available.

5:40 thorwil: is there a variant of assoc that works on vectors and takes an update fn instead of a value?

5:43 triyo: When reiterating over a binding in Clojure like so: file-lst* (map manip-fn file-lst) ... the asterisk seems to be the common practice. As I continue doing this, do I keep appending asterisks?

5:44 Like in Haskell, its common practice just to keep appending single quotes like so file-lst' ... file-lst'', file-lst'''

5:45 Its in the cases where giving it a unique name is meaningless.

5:50 thorwil: triyo: i thought the asterisk thing in clojure is rather to add an asterisk to functions that are "raw", to then write wrappers of the same name, without *

5:51 triyo: I think you are right. I've gotten back in to working with clojure few days ago and had a gap for over a year

5:52 so can't remember, or don't know some common practice.

5:53 So as far as you know, what is the common way to do this? You have a sequence that you need to make a few passes, what name do you bind the returned result to?

5:53 thorwil: triyo: you had a need to split a vector based on predicate yesterday, right? have a look at http://paste.pocoo.org/show/454088/

5:54 triyo: thorwil: thanks for the link. On my second iteration of the implementation though, I managed to do without the split at all with a single pass.

5:55 thorwil: triyo: no shame in adding -1, -2 ... or calling them a b c, though i would try to not handle any inbetween step explicitly

5:55 triyo: if your passes are fns of the same arity, how about using comp?

5:57 or simply (-> x fn1 fn2 fn3)

5:58 triyo: Thinking about your last comment, however its not functions, its bindings on (let [...

5:59 I could make them functions but there is abs no reuse required so an imperative, seqential, flow will do

6:00 *so a sequential flow will do

6:00 (let [parts (map ...) parts' (filter f parts)] ...)

6:04 thorwil: btw, that implementation of filter-split is much better than the commons lib one ;)

6:04 single pass on vector as expected

6:05 thorwil: heh, i do not know another implementation

6:06 shtutgart: I've just installed MongoDB and congomongo, enter this http://paste.org.ru/?gqz90o in the repl... and got NPE! Frustration!

6:07 What the hell is wrong with that code? It's from congomongo github page!

6:07 triyo: hehe would have been a bit more useful than npe

6:07 do you have the stack trace?

6:08 shtutgart: yes, sir: http://paste.org.ru/?4n99za

6:09 triyo: you running a particular version or latest source ver form github?

6:09 shtutgart: 0.1.7-SNAPSHOT, which is latest version on clojars.

6:09 triyo: cool

6:09 let me have a look quick

6:12 shtutgart: Clojure is 1.2, if it makes sense.

6:15 triyo: shtutgart: this is an NPE at driver level as far as I can tell.

6:15 Do yo have any MongoDB log by any chance?

6:16 shtutgart: nothing in the console output...

6:17 triyo: ok, so mongo db instance is running though? :)

6:18 shtutgart: yeah, it running and /bin/mongo works well, i mean - nothing suspicious

6:18 triyo: Have you tried `fetch` ?

6:18 just wan't to narrow the problem down

6:19 shtutgart: It looks like all commands (but mogno!) throwing npe

6:20 triyo: ok, thought it might. One sec.

6:22 Ok I know its IOException related

6:22 on the driver side.

6:23 Do you know what version of mongo java driver you running?

6:23 check /lib dir if you running leiningen

6:24 2.6.3

6:24 I checked the project.clj of congomongo prject

6:26 hehe

6:26 I can see the problem

6:26 shtutgart: hm, if io, maybe it's something stupid, like, i've db running on different port? although i'd expect congomongo has the same defaults as mongo itself, but nobody can guarantee that, right? let me check it...

6:26 triyo: YUP

6:26 but

6:26 wait, there is more ;)

6:27 that driver that is used by congomongo, 2.6.3, has a bug in _error method :)

6:28 https://github.com/mongodb/mongo-java-driver/blob/r2.6.3/src/main/com/mongodb/DBTCPConnector.java#L287

6:28 that first line doesn't check for null, which it can be, on _rsStatus

6:29 Now, the master, 2.7.0-pre -> https://github.com/mongodb/mongo-java-driver/blob/master/src/main/com/mongodb/DBTCPConnector.java#L295

6:29 Fixed

6:29 That gives you a clue I think

6:30 shtutgart: wow, cool!

6:30 triyo: Server is not listening

6:30 or as you said on wrong port

6:30 I'll file a quick ticket on congomongo peoject

6:30 to switch to 2.7.0 when its viable

6:31 shtutgart: yeah, it's a good idea

6:33 so, thank you so much for finding out the problem!

6:34 but, hm, port is 27017 on both sides...

6:38 triyo: This is the problem, I think you could get a nice stack-trace depicting the actual exception if it wasn't for the NPE

6:38 I filed the bug: https://github.com/aboekhoff/congomongo/issues/30

6:39 For now, need to get a bit creative.

6:39 :)

6:39 Ok is your mongo db on same server?

6:39 same host

6:40 whats the hostname in your config?

6:40 localhost,

6:44 whats the hostname in your config?

6:44 shtutgart: triyo: I've just restarted db and now all works perfectly. Thank you again :)

6:44 triyo: np

9:01 sirn: If I have a vector like: [[(1 "a" "b") (2 "a" "b")] [(3 "a" "b") (4 "a" "b")] [(5 "a" "b") (6 "a" "b")]], what's the best way to convert it into [(1 "a" "b") (2 "a" "b") (3 "a" "b") (4 "a" b") (5 "a" "b") (6 "a" "b")] ?

9:03 leonid: ,(apply concat [[(1 "a" "b") (2 "a" "b")] [(3 "a" "b") (4 "a" "b")] [(5 "a" "b") (6 "a" "b")]])

9:03 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

9:03 leonid: hah

9:04 ,(apply concat [['(1 "a" "b") '(2 "a" "b")] ['(3 "a" "b") '(4 "a" "b")] ['(5 "a" "b") '(6 "a" "b")]])

9:04 clojurebot: ((1 "a" "b") (2 "a" "b") (3 "a" "b") (4 "a" "b") (5 "a" "b") ...)

9:05 sirn: leonid: Awesome. Thanks!

9:05 shtutgart: sirn: flatten

9:05 ah, no, leonid is right. :)

9:05 sirn: shtutgart: flatten will make it [1 "a" "b" 2 "a" "b" ...] isn't it?

9:05 lucian: shtutgart: flatten is recursive

9:05 shtutgart: yeah

9:06 * lucian has found that the hard way

9:08 sirn: ,(time (apply concat [(range 10) (range 10)]))

9:08 clojurebot: "Elapsed time: 0.131 msecs"

9:08 (0 1 2 3 4 ...)

9:08 sirn: ,(time (flatten [(range 10) (range 10)]))

9:08 clojurebot: "Elapsed time: 0.223 msecs"

9:08 (0 1 2 3 4 ...)

9:08 lucian: sirn: huh?

9:09 sirn: lucian: just getting curious

9:09 lucian: is apply just slow?

9:10 Bronsa: is there a way to load a file into a string in clojurescript?

9:10 lucian: Bronsa: likely slurp

9:16 leonid: ,(time (apply concat [(range 10) (range 10)]))

9:16 clojurebot: "Elapsed time: 0.132 msecs"

9:17 (0 1 2 3 4 ...)

9:17 leonid: ,(time (mapcat identity [(range 10) (range 10)]))

9:17 clojurebot: "Elapsed time: 0.181 msecs"

9:17 (0 1 2 3 4 ...)

9:17 shtutgart: have someone tried to write desktop gui apps in clojurescript?

9:18 *has

11:40 crazyFox: is there a way to read past conversations? are they logged somehow?

11:41 Scriptor: crazyFox: this one, I think http://clojure-log.n01se.net/

11:45 crazyFox: Scriptor: thx!

12:03 ericbmerritt: I am wondering if someone might be able to help me out with a couple of clojurescript questions this morning.

12:13 gtrak: how do you open a file from the classpath with java.io.file? it doesn't seem to find it. (.exists (file "static/js/hello.js")) always returns false, and the file exists at lein project root/resources/static/js/hello.js

12:15 it finds it at "resources/static/js/hello.js", but that'd be hard-coding

12:16 I think it would break if I had to deploy in a WAR

12:20 thorwil: gtrak: isn't that what the resource function is good for?

12:21 gtrak: ah, hmm, I'll try it

12:24 works great, except it fails when there's a leading slash, is there a quick shortcut to fix that so I don't have to build two paths?

12:44 raek: gtrak: the path you give to 'resource' should not have a leading slash

12:45 trying to find where this is documented

12:46 also, clojure.java.io/resource returns nil when the resource file does not exist

12:47 resource paths always use / as the separator, regardless of the separator of the OS

12:48 ah, here: http://download.oracle.com/javase/7/docs/technotes/guides/lang/resources.html

12:58 gtrak: raek, ah, thanks, I'm translating some code over from using spring's ClassPathResource, I think they adjust for that

13:00 but I have to say, I thought I was going to miss spring and DI, but clojure is so much more powerful without the magic

13:31 crazyFox: given a large map with numeric (and distinct) values. what would be a good way to find the one *map entry* with the greatest value?

13:33 (large map meaning: 1 million entries)

13:34 jimblomo: max-key unless your map is sorted

13:38 crazyFox: ,(apply max-key #(val %) (seq {:c 1 :b 2 :a 3}))

13:38 clojurebot: [:a 3]

13:38 crazyFox: it does the job. nice. thx

13:42 jimblomo: np. maps will auto matically be seq'd, and val is already a function, so you can probably do

13:43 ,(apply max-key val {:c 1 :b 2 :a 3})

13:43 clojurebot: [:a 3]

13:47 theignorati: is there an opposite of select-keys?

13:49 jweiss: is there a simple or recommended way of having multiple agents work off of a single queue? I looked at java's Executors, but doesn't give any way I can find of specifying a per-thread setup/teardown

13:49 crazyFox: jimblomo: yeah, thats better

14:03 jimblomo: theignorati: dissoc, if you really need the seq, (apply dissoc ...)

14:05 jweiss: PriorityBlockingQueue may help

14:07 jweiss: jimblomo: how do the agents pull items off the queue? (or some other thread figure out which agents are free and send work to them)?

14:07 i don't see any way to check if an agent is busy

14:14 pschorf: I am having an odd macro issue...if an argument is a class name, it does not seem to be unquoted

14:14 for instance, (mac "string") works, but (mac String) will fail because it treats the argument like a clojure.lang.Symbol

14:19 gtrak: what's the right way to do namespace configuration in clojure? I kind of miss spring's placeholder @Value annotations

14:21 you can't really configure them from outside without making it stateful, right?

14:24 for instance say I want a cache that lives in a var to be off for development, the ns has to lookup the constant somewhere else, or I can pass it as a parameter to a function, or I make it become stateful via a init() method

14:25 pschorf: i have a better version of the question, how do i do something like ~@(repeat ~n nil)?

14:37 thorwil: pschorf: i guess you could give a name to the (repeat ~n nil) in a let and then ~@name

14:39 pschorf: thorwil: i thought of that, but I had an "unambe to resolve symbol foo# in this context"

14:43 ugh

14:43 so, this works

14:44 ~@(repeat (eval `(~n)) nil)

14:44 clojurebot: eval is DENIED

14:44 pschorf: but it feels so dirty

14:47 thorwil: pschorf: (defmacro nils [n] (let [x# (repeat n nil)] `(print ~@x#))) ?

14:48 pschorf: the issue is, it fails if i do something like

14:48 (def foo 4)

14:48 (nils foo)

14:51 thorwil: oh, it's completely beyond me why

14:52 pschorf: the reason it came up was the macro needs to operate on classes, but for some reason java.util.List is a Symbol instead of a class in the macro

14:55 thorwil: fixed: (defmacro nils [n] (let [x# (repeat (eval n) nil)] `(print ~@x#)))

14:56 pschorf: is that acceptable? i wasn't sure eval was super evil in clojure

14:57 thorwil: pschorf: eval is fine as long as you control what is being fed to it

14:57 pschorf: kk

14:57 thanks

14:58 thorwil: np. clearly i have to work on my mental model of evaluation :)

14:58 pschorf: i know...this is my second macro ever, and I feel like taking a nap after writing it

15:01 thorwil: if you pastebin it, someone might have a look at it and suggest improvement

15:05 pschorf: any ideas to clean this up? http://pastebin.com/b2Hca9eU

16:36 Raynes: amalloy: Must have been some downtime today.

16:37 amalloy: 4clojure is dead too.

20:53 Jarred: I don't understand why there are so many parentheses

20:53 (in Clojure)

20:53 but I also don't understand Lisp-style coding

20:54 scottj: Jarred: what have you done to understand?

20:55 Jarred: scottj Not enough

20:56 amalloy: style points for (in clojure)

21:02 leonid: rofl

21:02 amalloy: Jarred: a reasonable summary is that you have to have *some* punctuation (even pyhton's meaningful whitespace)

21:02 lisp chooses parenthesis and prefix notation because it's very easy to manipulate code in macros

21:04 icey_: Jarred: I think if you were to compare code with a C-like language (Java, C++, C#, etc) that the amount of parenthesis and brackets are pretty similar

21:05 Jarred: i.e. function test() {body} vs (defn test [] body)

21:08 Jarred: Yeah, but those are separated via whitespace

21:08 amalloy Ah I see

21:09 scottj: icey: I think that argument fails once arithmetic, assignment, and member access are considered

21:09 amalloy: scottj: i mostly agree, but arithmetic is a wash

21:09 (+ 1 2) is longer than 1 + 2, but (+ 1 2 3 4 5 6) is a lot nicer than 1 + 2 + 3 + 4 + 5 + 6

21:09 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.NumberFormatException: For input string: "+">

21:10 leonid: what triggered clojurebot?

21:11 (+ 1 2)

21:11 clojurebot: 3

21:11 amalloy: he's a lunatic. don't worry about him

21:11 leonid: ah i didn't know I could omit the ,

21:11 amalloy: Jarred: i wrote an article at http://hubpages.com/hub/What-is-Clojure some time ago. the main focus is really on lispiness, not clojure specifically, so you might find it useful

21:12 wastrel: hi

21:12 scottj: a += 2/b.c++ vs (def a (+ (/ 2 (inc (:c b)))) for example

21:12 wastrel: (:c b)

21:12 looks like an emoticon

21:13 amalloy: scottj: except those two expressions differ in other ways

21:14 you're mutating a (intentionally), and (unintentionally, i'm just guessing) b.c

21:15 and you left out the second occurrence of a in the clojure version

21:15 ibdknox: For any Noir users out there, I created a middleware to compile your cljs code on refresh: https://github.com/ibdknox/noir-cljs

21:15 scottj: amalloy: yeah, I was just trying to show the things I was talking about (assignment, arithmetic, member access) in quick way

21:15 amalloy: i guess. i think your code is a great example of how parentheses clarify things

21:15 because there are at least three weird gotchas in the infix version

21:16 icey: scottj: I get your point when talking about a specific operation, but lisp makes up ground by not needing parens for method calls (for example)... my point is just that it doesn't seem like there are significantly more parens / brackets in c-like code than lisp

21:16 scottj: I don't dispute that, just that the 1 to 1 stu and others like to point out really only applies to function calls and maybe class defs

21:17 icey: i always thought infix notation would be a bigger sticking point than # of parens; it's weird that people are still talking about parens when most editors make them a non-issue

21:17 amalloy: yeah, i guess thinkig about any nontrivial code i've written, it has a lot more grouping operators in clojure than it would in java

21:17 icey: i think people *believe* they care about number of parens, but what really bugs them is depth of parens

21:18 icey: amalloy: I think you're right; but don't you think it's odd that you don't see many complaints about "end end end end end end" in ruby or "});}});});});}" in javascript?

21:20 amalloy: not being a ruby user myself, i doubt you see "end" seven times in a row anywhere near as often as you see ))}))))}])) in clojure

21:20 icey: amalloy: yeah, that's fair

21:20 scottj: the js case is not that much of an exaggeration though

21:21 amalloy: scottj: yeah, i carefully picked on the ruby example :)

21:21 scottj: I think other languages name intermediate steps more often

21:22 amalloy: i remember seeing a clojure user object to java's anonymous classes with something like "seeing );}}()); is a sure sign of a diseased language"

21:22 seemed a bit hypocritical

21:22 scottj: actually since naming doesn't require parens and in coffeescript you don't need parens for function calls or objects, you could probably write it paren free

21:23 icey: ibdknox: noir-cljs looks like it will be a pretty nice time-saver

21:23 ibdknox: icey: I hope so :)

21:24 also if you're doing cljs

21:24 icey: ibdknox: i'm hoping to dip my toes into some ClojureScript later this week, I'll probably use this to do it (so I don't forget to recompile)

21:24 ibdknox: it's worth checking out pinot https://github.com/ibdknox/pinot

21:24 amalloy: hah, pinot

21:24 ibdknox: :D

21:24 icey: ibdknox: dude. that looks awesome

21:25 ibdknox: you can do some really cool stuff with hiccup generating actual dom objects

21:25 amalloy: is there really any other name I could've used?

21:25 amalloy: hehe

21:25 icey: ibdknox: i spent some time earlier today reading up on google closure's templates; i'm happy to not need to use them haha

21:26 ibdknox: yeah.. the entire goog library hurts me a bit :(

21:26 with wonderful functions like goog.dom.getElementsByTagNameAndClass

21:26 icey: ibdknox: is there a way to get access to the request headers from inside defpage?

21:27 amalloy: ibdknox: well, noir makes me think of film noir, not of wine

21:27 ibdknox: icey: intentionally no

21:27 amalloy: yeah, the running joke was that it should've been blanc

21:27 icey: ibdknox: interesting - why intentionally no??

21:28 ibdknox: amalloy: I'm not sure what I could've done related to film noir that would make a good name

21:28 amalloy: i don't know either

21:28 ibdknox: icey: chances are if you need it, you should be writing middleware :)

21:28 icey: what's your usecase?

21:28 icey: ibdknox: haha, fair enough; i was just curious

21:29 ibdknox: getting the user-agent string server-side. it's not a big deal, for this i'm just using compojure since it's a single-serve app

21:30 ibdknox: i.e. I don't have a need for it in noir... I was just curious if there was a way to do it that i missed :)

21:30 ibdknox: icey: gotcha :) You have access to the full request in pre-routes and middleware

21:31 xiaolongxia: ibdknox: actually i have a pretty elementary question about javascript interop using goog libraries ...

21:31 ibdknox: xiaolongxia: shoot

21:31 xiaolongxia: https://gist.github.com/1131051

21:31 ibdknox: that is an epic list

21:31 xiaolongxia: i'm trying to make this more idiomatic in clojure, that works though

21:32 that's a direct port from the URL in the description

21:33 so obviously (let [buttons (vector (. goog.editor.Command BOLD))] (...))

21:33 would work

21:33 but I'm not familiary enough with interop in clojure

21:34 to understand how to go from ["BOLD" "ITALIC" .. ] to an interop compatible name(?)

21:34 ibdknox: ah

21:34 so this is particularly tricky in CLJS right now

21:34 xiaolongxia: ah

21:34 ibdknox: the best way to do it

21:34 is with aget

21:34 (aget goog.editor.Command "BOLD")

21:34 xiaolongxia: huh

21:35 ibdknox: I do it in pinot for event lookup

21:35 https://github.com/ibdknox/pinot/blob/master/src/pinot/events.cljs#L18

21:36 took me a while to get to that though :/

21:36 lol

21:37 xiaolongxia: let is throwing a stacktrace, i'll have to keep playing with it

21:37 but i see what your code is doing

21:37 thanks

21:37 ibdknox: np

21:37 xiaolongxia: i had never messed with the goog libraries before

21:38 but in general, the UI library is pretty nice

21:38 ibdknox: yeah, I'm sure their "controls" are probably ok to work with

21:39 scottj: is there a simple way to not have everything look like google? without recssing everything manually

21:39 ibdknox: hah

21:39 why wouldn't you want to look like google? They're so successful! ;)

21:40 xiaolongxia: scottj: what is it you don't want to look "googly" ?

21:40 ibdknox: Sadly, I don't think so, if you look around you can find some CSS people have already written to make some things look prettier

21:40 xiaolongxia: i'll i'm really interested in is the editor, and that looks like most other well done editors

21:40 ibdknox: but even that seems to be sparse

21:54 emacsen: with cljscript, how does one interface with an existing js library?

21:56 xiaolongxia: ala https://gist.github.com/1096382

21:56 ibdknox: eh

21:56 you shouldn't use js*

21:56 anything in the global js namespace can be accessed through js/

21:56 js/alert

21:56 xiaolongxia: ah!

21:56 emacsen: xiaolongxia, thx. ibdknox okay, then I need to rewrite whatever I want to use?

21:56 xiaolongxia: thanks

21:57 ibdknox: emacsen: huh?

21:57 emacsen: ibdknox, so let's say I want to make a complex app. And I want to leverage something like paper.js

21:58 are you saying don't do it?

21:58 ibdknox: no? I said don't use the js* function :-p

21:58 :)

21:58 emacsen: ah. So what's the right way?

21:58 ibdknox: the example that was given in that gist

21:58 uses (js* "$")

21:59 emacsen: ibdknox, okay.

21:59 ibdknox: you use the js namespace: (js/JQuery "blah")

21:59 though that likely won't do what you expect once you turn on advanced optimization :(

22:00 xiaolongxia: ibdknox: ok, what am I doing wrong here? this results in an array of anon functions, but not anon function calls: http://pastebin.com/ZfrNQj8g

22:01 ibdknox: are you sure the commands aren't functions themselves?

22:02 if they're "classes" they would be

22:03 amalloy: xiaolongxia: you probably meant vec, not vector? though probably you don't need either

22:04 xiaolongxia: http://pastebin.com/yK2jR8qn

22:04 amalloy: well...yes? that's what those say to do

22:05 i wasn't trying to trick you when i said to use vec, not vector

22:05 xiaolongxia: amalloy: i wrot that paste before you said that ...

22:05 i'm trying to understand why the map doesn't work

22:06 amalloy: it works fine

22:06 xiaolongxia: no ... it doesn't

22:06 amalloy: though a (for) would be clearer

22:06 the problem is that you're creating a one-element vector, which contains a list of buttons

22:07 xiaolongxia: ok, so it was vec vs vector

22:07 ibdknox: yeah

22:12 fbru02: hey ! is there any function that is the same as doing first a map and then a reduce

22:12 ?

22:16 zmaril: Pardon me, I am working through Joy of Clojure and have gotten fairly stuck. I am trying to get the a* search example to work but every time I try to run the function it says that there is an error in the compare library.

22:16 Here is the gist: https://gist.github.com/1131095

22:20 amalloy: fbru02: you could write that function yourself in fewer characters than it takes to ask about it, so probably nobody's bothered

22:21 fbru02: amalloy: makes sense :)

22:26 xiaolongxia: amalloy, ibdknox: thanks for your help. won't get any further than this for now, but it runs: https://gist.github.com/1131051

22:27 ibdknox: xiaolongxia: any time :)

23:01 jsnikeris: Suppose I have a sorted sequence, and I want to know what is the next item in that sequence after a given item. So (f [1 3 5 9] 5) -> 5. Is there a better way to do this than to find the index of n, and then traverse the list again to find the next item after n? In Java, I'd use an iterator, but not sure what to do in clojure. Any ideas?

23:02 My example should return 9...

23:09 fullets: (fn [vs n] (first (filter #(> % n) vs)))

23:09 Not sure how idiomatic that is

23:10 jsnikeris: fullets: works for numbers. I just came up with:

23:10 ,(second (drop-while #(not= 5 %) [0 3 5 8]))

23:10 clojurebot: 8

23:11 jsnikeris: still kinda ugly though

23:11 leonid: is your sequence nondecreasing, or increasing?

23:11 jsnikeris: increasing

23:11 well, decreasing

23:13 What do you mean by nondecreasing?

23:13 leonid: by that i mean the sequence has duplicate elements

23:13 fullets: [1 2 3 4] increasing, [1 2 2 3 3 4] nondecreasing

23:13 jsnikeris: Oh, gotcha. No duplicates

23:14 Its actually a sequence of blog entries, sorted by publication date.

23:14 But that's neither here nor there

23:15 leonid: fullet's solution looks good enough

23:16 fullets: If you want if for comparables in general, you could use the compare fn rather than >

23:17 jsnikeris: OK, thanks for the help guys

23:18 leonid: i'm surprised there's no built-in function that does find-first

23:18 bortreb: how about (find-first (partial < 5) [1 2 3 4 5 6])

23:18 using clojure.contrib.seq/find-first

23:19 fullets: bortreb: well spotted :)

23:19 jsnikeris: even named the same!

23:19 leonid: oh didn't know we could use contrib functions

23:20 Scriptor: is this for 4clojure?

23:20 jsnikeris: Yes

23:28 amalloy: jsnikeris: if you have an actual sorted-set/map instead of a vector, you can use ##(doc subseq)

23:28 lazybot: ⇒ "([sc test key] [sc start-test start-key end-test end-key]); sc must be a sorted collection, test(s) one of <, <=, > or >=. Returns a seq of those entries with keys ek for which (test (.. sc comparator (compare ek key)) 0) is true"

23:30 amalloy: and of course if you want to *keep* it sorted, you should be using a sorted-map/set

23:40 jsnikeris: so right now, I've got a function called get-entries that grabs a bunch of blog entries off the disk, and returns a sequence of entries (maps). My idea was to sort this sequence before returning it, so I could use it when calling (next-entry entry) and (prev-entry entry). Also, once I got everything working I would have get-entries cache the entries. What do you think about this approach?

23:41 amalloy: a sorted set (or map) still makes more sense to me

23:41 jsnikeris: sorted-set wouldn't know how to sort these maps though

23:42 amalloy: &(doc sorted-set-by)

23:42 lazybot: ⇒ "([comparator & keys]); Returns a new sorted set with supplied keys, using the supplied comparator."

23:42 jsnikeris: aha

23:42 amalloy: SHAZAM

23:42 jsnikeris: LOL

23:42 literally

23:42 nice

23:44 amalloy: speaking of which, am i the only one who thinks ##(doc comparator) is a lot less useful than something that turns a key-function (as in max-key) into a comparator?

23:44 lazybot: ⇒ "([pred]); Returns an implementation of java.util.Comparator based upon pred."

23:49 jsnikeris: Could you give me an example of max-key in use?

23:51 amalloy: &(max-key :x {:x 1 :y 2}, {:x 10 :y 5})

23:51 lazybot: ⇒ {:x 10, :y 5}

23:55 jsnikeris: Ah, ok.

23:58 Sometimes the docs are so terse I struggle to understand how a fn is used. And then, once I figure it out, I'm like oh, yah, that's a perfect explanation of how it works.

23:58 what it does, rather

Logging service provided by n01se.net