#clojure log - Sep 03 2012

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

0:02 amalloy: tomoj: i think you get them mainly from git add

0:03 dansalmo: is anyone here using light-table?

0:06 Raynes: Sure

0:06 ~anyone

0:06 clojurebot: Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."

0:06 Raynes: Unless it isn't a question and you were just curious.

0:13 tomoj: amalloy: huh, I wish it would do that for me (and for my coworkers..)

0:16 amalloy: tomoj: check out apply.whitespace and core.whitespace at `git help config`, and also the --whitespace option to `git help apply`

0:16 arohner: oh, this is amusing

0:17 ,(read)

0:17 clojurebot: #<ReaderException clojure.lang.LispReader$ReaderException: java.lang.RuntimeException: EOF while reading>

0:17 arohner: huh, that hangs my local repl

0:17 amalloy: arohner: known issue with (older versions of?) lein repl

0:18 arohner: ah, yes I am running an older version

0:18 but I'm doing lein swank

0:20 amalloy: same thing

0:20 or maybe it's just swank? i forget

0:28 dansalmo: I find the insta-repl of lighttable very useful, but I can not figure out how to use the table

0:29 tomoj: amalloy: yeah, no sign of anything about warnings on add

0:29 amalloy: yeah. i thought add replied on apply. but i guess only add -p does that

0:30 tomoj: ah

0:30 so I probably saw those warnings during rebase I bet

0:31 amalloy: tomoj: i bet you can encourage coworkers to use add -p - it's so useful. and as a side effect they'll get warned about whitespace

0:45 rare indeed is a commit from me that didn't involve git add -p at least once

0:52 yankov: when using constraints is it possible to just return a specific value instead of throwing an exception?

0:53 Raynes: dansalmo: What can't you figure out?

0:54 tomoj: amalloy: I think I maybe can get one of them to use magit

1:14 Frozenlock: My next goal in cljs will probably be to (try) make a graphical programming interface. Plug little boxes together... But before I paint myself in a corner, where should I store the block-functions? Directly in the DOM?

1:16 emezeske: Frozenlock: Block-functions?

1:21 Frozenlock: Kinda like this https://code.google.com/p/blockly/

1:24 wmealing_: dejavu, i remember something like squeak that had similar controls

1:24 SegFaultAX: It's always a little strange to get a solution to a 4clojure problem, then see that one of the people that you follow got the same solution verbatim.

1:24 wmealing_: Frozenlock: before you write something please play with some of the current ones so you know what sucks and what doesnt

2:12 SegFaultAX: amalloy: Ping.

2:13 amalloy: heyo

2:13 SegFaultAX: amalloy: Are the 4clojure problems stored in mongo?

2:13 amalloy: yeah

2:13 SegFaultAX: amalloy: Is that db available somewhere?

2:13 amalloy: no, but most of the data is exposed via the API

2:14 SegFaultAX: amalloy: Oh sweet. Where can I read about the API?

2:14 amalloy: the source is pretty much it, i think. or check out lein-foreclojure or similar tools that use it

2:15 SegFaultAX: amalloy: Would you be willing to accept pull requests that extend the API to include fetching solutions for your account?

2:15 amalloy: sure

2:15 although i don't know how you'll do auth -sounds hard

2:15 SegFaultAX: amalloy: Actually, does fetching source need to be authed?

2:16 amalloy: https://github.com/4clojure/4clojure/blob/develop/src/foreclojure/api.clj is the only place we explicitly output json

2:16 SegFaultAX: amalloy: I mean, I can just follow someone to get the source to a problem.

2:16 amalloy: well, there's a checkbox to disable sharing solutions. i guess you could just have that also disable API-fetching of your solutions

2:18 SegFaultAX: The unit tests aren't included in the API?

2:21 amalloy: huh?

2:22 SegFaultAX: amalloy: Nevermind, I'm silly.

2:22 :)

2:23 For some reason, I feel determined to be in the top 100 of 4clojure. I'm at 199 right now.

2:23 Of 8.6k

3:56 kral: namaste

4:28 john2x: can I do (case my-str "s" "S" (do-something))? execute do-something if my-str = "s" or "S"?

4:31 tomoj: that means (if (= my-str "s") "S" (do-something))

4:31 emezeske: john2x: case does not offer fall-through like a C switch statement if that's what you're after

4:31 tomoj: (case my-str ("s" "S") x y)

4:32 clgv: ,(case "S" ("s" "S") true false)

4:32 clojurebot: true

4:32 john2x: cool. thanks!

4:43 spoon16: What do you guys think of this idea? We use Gson a lot and I could not find an existing library that made it easily accessible from clojure. https://github.com/spoon16/gson-clj

4:44 tomoj: huh, I never knew keys worked on seqs ##(keys (concat {:a 1} {:b 2}))

4:44 lazybot: ⇒ (:a :b)

4:45 spoon16: ##(keys (into [] 1 2 3))

4:45 lazybot: clojure.lang.ArityException: Wrong number of args (4) passed to: core$into

4:45 amalloy: tomoj: i think (keys m) is basically (map key m). ##(keys (concat {:a 1} {:a 2}))

4:45 lazybot: ⇒ (:a :a)

4:45 spoon16: ##(keys [1 2 3])

4:45 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry

4:46 tomoj: interesting

4:49 samrat: in Noir how do I check whether a key(obtained from a form) is an integer or not?

4:50 to use the key I do Integer/parseInt, but how do I check if a string has been passed?

4:50 vilonis: well, you could use regex to match an int. #'[0-9]+'

4:50 i doubt that is the best way, but none the less

4:55 clgv: samrat: you can compare the regexp approach with wrapping parseInt in a try-catch block and see what fits you more

4:56 samrat: thanks, I'll try the checking with regex

4:57 https://www.refheap.com/paste/4828 this defpage seems to work only after I refresh the page once, what did i do wrong?

5:00 clgv: is there any way I can use a try-catch like I'd use if?

5:00 I mean can I have it do something if an exception is thrown...like redirect to a page

5:00 I tried that but didn't seem to work

5:01 clgv: samrat: yeah. just put it in the catch part

5:01 ,(try (Integer/parseInt "a456") (catch Exception e nil))

5:01 clojurebot: clgv: Huh?

5:01 clgv: &(try (Integer/parseInt "a456") (catch Exception e nil))

5:01 lazybot: java.lang.SecurityException: You tripped the alarm! catch is bad!

5:02 clgv: hm ok the bot does not like it

5:06 samrat: clgv: tried this https://www.refheap.com/paste/4829, doesn't seem to work

5:07 clgv: samrat: should though. add some println statements to see what gets executed

5:09 samrat: clgv: the catch part does get executed

5:10 clgv: samrat: well, then there is probably no exception and it parses something

5:10 ,(Integer/parseInt "12abc 34")

5:10 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "12abc 34">

5:10 clgv: ,(Integer/parseInt "12 abc 34")

5:10 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "12 abc 34">

5:10 clgv: well that should be the exception you get

5:10 ,(Integer/parseInt "")

5:11 clojurebot: #<NumberFormatException java.lang.NumberFormatException: For input string: "">

5:24 hiredman: clear

6:09 hyPiRion: Hm, just so I'm certain: deftype is the way to go if you want objects with state, right?

6:09 "objects"

6:10 clgv: hyPiRion: yes, if you want protocols + state

6:11 hyPiRion: but most of the time try defrecord since it has a map implementation which makes it much handier

6:11 hyPiRion: Yeah, I know.

6:13 clgv: I used deftype for internal objects. defrecord was very handy for dataanalysis stuff

6:20 stain: sudop I thought defrecord was old-fashoined now

6:20 sudo on irc

6:20 :)

6:24 clgv: stain: nope, you get that wrong. defstruct is deprecated

6:30 how can I require a (not yet loaded) namespace only once coordinated between all running threads?

6:35 samrat: clgv: sorry, I was disconnected earlier. any ideas on the problem i was having(filtering off non-integer values passed to Noir)?

6:35 clgv: samrat: did you try regexp and try-catch, yet?

6:36 samrat: if regexp is not too slow I would stick with it

6:37 samrat: clgv: i couldnt make regexp work

6:37 clgv: samrat: there is a lot of info on that online. just search for java and regexps

6:39 samrat: clgv: this is what I tried https://www.refheap.com/paste/4832

6:39 also tried with #"\d+"

6:40 clgv: samrat: are you sure that should be written at that position of defpage? I only knew slightly older versions of noir, but there that would be wrong

6:41 or maybe I didnt know that feature. you should definitely check the docs on that

6:42 samrat: clgv: http://webnoir.org/tutorials/routes, towards the end of the first section

6:43 clgv: samrat: well your defpage route does not contain :minutes - so it cant work like described

6:44 you should use [:get ["/read/:minutes" :minutes #"\d+"]]

6:47 samrat: clgv: but where do I point my form-to now?

6:48 clgv: samrat: concluding from that page I'd say you have to define a route that matches the complement of the current

6:49 or you use the pre-route functionality

6:50 samrat: clgv: could using POST be of help?

6:51 clgv: samrat: why should it?

6:52 samrat: clgv: don't why I thought that, but didn't work anyway

6:53 clgv: samrat: I would just use these pre-routes if you want to do some parameter checking and redirect on mismatch

8:17 samrat: how do I compare two exceptions for equality, one is https://www.refheap.com/paste/4833 and the other is expected to come from a try-catch block

8:18 I need to find out if the two are same

8:18 Chousuke: use identical? maybe. if you are sure they will be the same object

8:18 but I'm not sure what "equality" means for exceptions

8:19 samrat: Chousuke: I meant if it was the same exception

8:19 nz-: samrat: typically you would compare exception types and some data carried by the exception

8:20 clgv: samrat: uh, what do you really want to do?

8:20 noidi: maybe (= (class e1) (class e2)) ?

8:20 if you want to see if they're both exceptions of the same type

8:20 samrat: clgv: actually the same problem as before, filtering out string from Noir GET requests

8:20 pre-route seems to give some solution, so trying that

8:21 clgv: samrat: why do you want to compare exceptions then? that does not make much sense

8:22 samrat: clgv: I'm getting exceptions for both strings and numbers, but they're slightly different

8:23 clgv: samrat: well, usually you would handle them in the catch block or re-throw them. usually, you dont compare exception objects.

8:24 samrat: clgv: not sure how I would handle them in the catch block

8:25 clgv: samrat: well, explain the big scope. you want to render an error page, or what?

8:25 samrat: no, redirect it to "/"

8:25 clgv: then put the code for it in the catch block^^

8:26 samrat: clgv: yes, but I get java.lang.NumberFormatException for both cases

8:26 clgv: samrat: for which cases?

8:26 samrat: for when i pass a number and a string

8:27 clgv: input, function called, expected output, error?

8:29 samrat: clgv: passing no. of minutes via a GET request, works fine when I pass a number but I get an error when I pass a string(which is obvious), so I need to catch when a string is passed and redirect the user to the index page

8:30 clgv: samrat: whats your current code?

8:33 samrat: clgv: https://www.refheap.com/paste/4834

8:33 thats the pre-route

8:35 clgv: samrat: so why dont you just put the redirect-form in the catch block?

8:36 samrat: clgv: for some reason, I get an exception when a number is passed too

8:36 clgv: samrat: then I would check why that happens, since it shouldnt

9:23 firesofmay: Hi, what is the right way to create a directory from clojure?

9:25 algernon: firesofmay: I'm using fs/mkdirs (where fs == github.com/Raynes/fs)

9:26 firesofmay: algernon, okay checking. thanks.

9:27 algernon: but if you don't want an external dependency, then something like (.mkdirs (clojure.java.io/file path)) should work too.

9:28 (fs does have a few advantages, though)

9:28 firesofmay: algernon, oh okay. and How do I find out what to add in my project.clj? Normally projects lists what to add such that it'll add itself from clojars. ?

9:28 algernon, like for example?

9:29 algernon: as for project.clj: [fs "1.3.2"] - I got that by trial and error. Looked at the latest tag, and tried it like this, worked :P

9:30 firesofmay: algernon, found it : http://clojars.org:8002/fs

9:30 :)

9:30 algernon: fs' advantages include better handling of cwd

9:30 firesofmay: algernon, okay looks good to me :)

9:31 algernon: and fs/mkdirs is shorter than the other :)

9:31 firesofmay: algernon, :)

9:34 algernon, mailed the author of fs to add clojars version to readme page. so that others who see that library don't do "trial and error" like us ;)

9:34 * algernon ponders a pull request

9:35 firesofmay: algernon, for?

9:36 algernon: firesofmay: fs, to update the readme.

9:37 firesofmay: algernon, Already mailed him. But good point. I am new to OSS. so learning :)

9:37 algernon, will do that next time :)

9:45 xeqi: _ato: ^ should :8002 be publically accessible? it bypasses the nginx frontend

10:00 _ato: ohh, right. its accessible so we can test the backup server on updates before fully moving ot the new version

10:24 mindbender1: is there any library I could use to obtain a tree view in clojurescript?

10:26 uvtc: algernon: re. figuring out what goes into your project.clj for a given project, the clojars page always shows that.

10:27 algernon: uvtc: yes, but that requires me to find it on clojars too, as opposed to just looking at the github project. I don't like searching two places when one should be enough.

10:27 uvtc: (I do go to clojars if a quick & dirty trial&error does not have the expected result)

10:27 vijaykiran: mindbender1: I think goog.ui has a tree control

10:28 uvtc: algernon: At the [Dining Car](http://www.unexpected-vortices.com/clojure/dining-car.html), all links to projects point to their canonical Clojars page.

10:28 vijaykiran: mindbender1: http://closure-library.googlecode.com/svn/docs/class_goog_ui_tree_TreeControl.html

10:28 algernon: uvtc: that's good enough too

10:28 mindbender1: vijaykiran: thanks

10:29 algernon: uvtc: I still prefer if the projects' README itself points me to the right direction, be it a clojars link or a copy & pasteable leiningen :dependencies entry

10:30 * algernon is terribly lazy.

10:30 uvtc: algernon: I like using Clojars because it's getting the info right from the horse's mouth: that is, that's where lein gets the artifact from. :)

10:31 (lazy-seq algernon) ;)

10:40 john2x: does (eval) not use the current namespace?

10:49 gfredericks: john2x: looks like it does to me

10:49 well

10:49 "current" can be counterintuitive

10:51 it's based on the value of *ns* at the time eval is called

10:51 which is independent from the value of *ns* at the time that the function that calls eval was compiled

10:52 if you want to force a particular namespace at the point where you're calling eval, you can wrap it in (binding [*ns* <something-or-other>] (eval ...))

11:47 DaoWen: I remember reading (or maybe hearing in a webcast) somewhere that Clojure doesn't have built-in pattern matching (like in Racket) because the conditional aspect of pattern matching is bad, and instead Clojure has non-conditional destructuring. Is there anywhere I can go and read (or listen) more about the rational behind why conditionally matching is considered bad?

11:49 wmealing_: bad, is such a strong word

11:49 it could be slower, if that is what you mean

11:52 DaoWen: no, I'm pretty sure I watched a webcast thing where Rich said he doesn't like pattern matching because he doesn't like the conditional part of the destructuring, but I don't think he really elaborated on it in that particular webcast

11:52 gfredericks: I've heard pattern-matching poopoo'd for being closed

11:52 particularly when discussing things like predicate dispatch

11:53 DaoWen: what do you mean by "being closed"

11:53 ?

11:53 Sgeo: DaoWen, once you make a function that uses pattern matching, you can't add onto the function later

11:53 DaoWen: OK, so the idea is that in simple cases destructuring should suffice, and in more complex cases multimethods are a better, more extensible option?

11:54 Sgeo: I think the idea is that there are better options out there, we just need to work on them. But I might be wrong

11:54 (better than multimethods and pattern matching)

11:55 DaoWen: interesting

11:55 thanks

11:57 is it possible to "extend" a multi-method? e.g. I have a base multi-method that covers some cases, then I want to add a few more cases in some (but not all) contexts. would I need to duplicate all the original code to do this, or is there an easy way to "extend" it while keeping the original intact as well?

11:59 jcromartie: well, this was much easier than I thought it would be

11:59 https://gist.github.com/3610244

12:03 DaoWen: oh sweet, thanks

12:03 wait, was that in response to my question?

12:04 it doesn't look like it was :-p

12:05 oh well, I have to sign off—bye

12:06 jcromartie: hah hah, sorry

12:16 tolsen: Hello. I'm using nrepl with nrepl.el in emacs. I think I may have messed up the state of my repl with memoization. Is there an easy way to kill my nrepl instance? I've been quitting emacs and killing java for now.

12:18 uvtc: What was the old clojure.contrib.def `defvar` for?

12:18 nbeloglazov: $clojuredocs defvar

12:18 lazybot: clojure.contrib.def/defvar: http://clojuredocs.org/v/31; clojure.contrib.def/defvar-: http://clojuredocs.org/v/25

12:18 algernon: tolsen: killing the buffer usually

12:19 *usually fixed things for me.

12:19 nbeloglazov: uvtc: weird macro

12:20 uvtc: nbeloglazov: thanks. From looking at it's mention at http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go , looks like maybe it was mainly for the docstring.

12:20 nbeloglazov: uvtc: seems so

12:21 tolsen: algernon: I kill the buffer and I still see the java process running. If I jack in again, now I have two java processes. oh well, killing the buffer and java is better than killing emacs and java

12:28 xeqi: tolsen: kill *nrepl-server*

12:29 tolsen: xeql: that works. thanks!

13:34 SegFaultAX: Is it possible to eval something in a context? Like if I want to eval '(+ a b) in a context where a and b are bound to something meaningful, how could I do that?

13:34 dnolen: SegFaultAX: eval doesn't work w/ locals if that's what you mean.

13:34 SegFaultAX: dnolen: So what am I looking for?

13:35 dnolen: SegFaultAX: it's just not possible.

13:35 gfredericks: SegFaultAX: you can wrap your form in a let

13:35 Sgeo: SegFaultAX, I think you're looking for the Kernel programming language?

13:35 gfredericks: (eval (list 'let '[a 2 b 3] my-code))

13:36 SegFaultAX: gfredericks: That's easy enough.

13:36 nDuff: SegFaultAX: ...do a and b have to be locals? It's a whole different story if they can be vars.

13:36 SegFaultAX: nDuff: With "binding"?

13:36 gfredericks: SegFaultAX: if you want to use something other than literals you'll have to be slightly more fancy with the vector

13:36 SegFaultAX: gfredericks: Nope, just literals.

13:37 dnolen: SegFaultAX: as nDuff said, if you're not trying to capture locals then you can probably get something that works for you.

13:38 SegFaultAX: Hmm, this doesn't work &(binding [a 1 b 2] (eval '(+ a b)))

13:39 ,(binding [a 1 b 2] (eval '(+ a b)))

13:39 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

13:39 gfredericks: SegFaultAX: they have to be vars to use binding

13:39 SegFaultAX: gfredericks: But is binding what I'm looking for?

13:39 gfredericks: SegFaultAX: you can use my let idea if you don't need vars

13:39 I think locals are cleaner than vars

13:40 SegFaultAX: If I don't have to modify the form I'm going to eval, that would be ideal.

13:41 gfredericks: SegFaultAX: I could whip up an eval-let macro that would make it even cleaner

13:41 SegFaultAX: gfredericks: What would that look like?

13:41 gfredericks: oh you mean "modify" as in wrapping it in a let?

13:41 SegFaultAX: gfredericks: Yea nevermind, I don't wrapping it.

13:42 gfredericks: SegFaultAX: you could say (eval-let [a 3 b (+ a 10)] some-code)

13:42 SegFaultAX: gfredericks: That would be awesome!

13:42 gfredericks: give me 75 seconds

13:43 SegFaultAX: What's the easiest way to turn a map into a vector?

13:43 gfredericks: depends on what you want

13:43 ,(vec {3 4 5 6})

13:43 clojurebot: [[3 4] [5 6]]

13:43 SegFaultAX: ,(apply concat (vec {3 4 5 6}))

13:43 clojurebot: (3 4 5 6)

13:44 gfredericks: SegFaultAX: any destructuring or interdependence between the locals you're creating?

13:45 SegFaultAX: Nope.

13:45 gfredericks: okay that makes less I have to think about :)

13:45 oh man writing a macro that does eval is like writing a macro macro

13:46 SegFaultAX: :)

13:47 gfredericks: Don't worry about it if it's too much trouble.

13:47 gfredericks: no it is fun

13:49 SegFaultAX: https://gist.github.com/3611284

13:50 I think it works fine with destructuring

13:51 but not interdependence

13:55 oh also you don't have to worry about the distinction between literals and non-literals

14:02 SegFaultAX: gfredericks: Sorry, stepped away for a minute. Looking now.

14:03 gfredericks: I can also imagine a different macro that uses the locals currently in place

14:04 SegFaultAX: gfredericks: Wow, this is awesome. Thanks!

14:05 * gfredericks is always up for writing a macro

14:06 hyPiRion: gfredericks: you monster.

14:07 * arrdem only stoops to macros when he realizes he's written more than 15 lines of repetitive boilerplate

14:22 hyPiRion: Hey, what's the preferred way of handling command line arguments? I noted that there was a clojure.contrib-library on it before, but they are surely deprecated.

14:23 okay, nevermind - My google-fu isn't that great today.

14:23 Frozenlo`: https://github.com/clojure/tools.cli

14:23 aw

14:24 arrdem: yeah Frozenlock got the last thing I used..

14:25 hyPiRion: Frozenlock: Yeah, I got to that too.

14:25 Thanks anyway.

14:25 :)

14:31 Frozenlock: Any library for engineering units manipulation?

14:37 technomancy: Frozenlock: there's that frink port

14:40 Frozenlock: I guess this is https://github.com/martintrojer/frinj :)

14:40 Looking now, thanks!

14:40 http://onclojure.com/2010/03/23/computing-with-units-and-dimensions/ is also really promising

14:49 uvtc: I'm trying to use clostache with a templates/foo.html template. Within my code I've got `(render-resource "templates/foo.html" {...})`, but am getting the following exception:

14:49 java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil

14:51 The top of the stack trace (up to where `render-resource` is called) looks like this: https://www.refheap.com/paste/4848

14:52 Anyone have any ideas what might be causing that?

15:01 xeqi: uvtc: does "templates/foo.html" exist?

15:01 usually I see that when the file can't be found

15:01 uvtc: xeqi: Yes. And if I intentionally misspell the filename, I get the same error.

15:02 The clostache `render` function works fine for me.

15:03 xeqi: does (clojure.java.io/resource "templates/foo.html") throw the same exception?

15:05 uvtc: xeqi: No. In my repl, if I run that I get nil back.

15:06 jeremyheiler: That's the problem, then. For it's trying to call make-reader with a nil argument.

15:08 Although passing nil into make-reader gives me a differently worded exception message. (using 1.4)

15:09 uvtc: I'm using 1.4 here.

15:09 xeqi: uvtc: is this a lein project w/ default resource-paths ?

15:10 uvtc: xeqi: It's in a fresh `lein new compojure myproj` project.

15:10 xeqi: whats the path from project root to foo.html ?

15:12 uvtc: my code is in src/myproj/handler.clj

15:12 So, that's myproj/src/myproj/handler.clj

15:12 And the templates are just in a directory I made: myproj/templates/foo.html

15:13 But I've tried `(render-resource "../templates/foo.html" {...})`

15:13 and `(render-resource "../../templates/foo.html" {...})`

15:13 xeqi: move it to resources/templates/foo.html

15:13 pandeiro: i'm trying to debug compojure routes while running jetty via nrepl.el but for some reason (println) doesn't output anything. Any guesses?

15:14 xeqi: pandeiro: anything in the *nrepl-server* buffer?

15:14 uvtc: xeqi: Thanks for the suggestion, but I get the exact same exception and stack trace.

15:15 pandeiro: xeqi: yikes, tons of stuff

15:16 uvtc: xeqi: Wait!

15:16 xeqi: Works. That fixed it.

15:17 xeqi: pandeiro: heh, I think there is a fix in master to make it go to the buffer with the prompt, but you can find it there for now

15:17 uvtc: xeqi: Thanks so much. :) Why does it insist on having things in a resources directory?

15:17 pandeiro: xeqi: yes wasn't expecting that, thanks

15:18 jeremyheiler: uvtc: io/resource expects things to be on the classpath, and resources/ is on the classpath by default i think.

15:19 uvtc: Ah. Thanks, jeremyheiler . So, maybe `lein new compojure myproj` should also create a "resources" dir in the project.

15:19 jeremyheiler: It's configurable with the :resource-paths options in project.clj

15:20 Yeah, maybe.

15:36 Sgeo: I was just looking at #clnoobs and someone was talking about why you shouldn't modify literal objects. I take it that that's a non-issue in Clojure because literal objects aren't modifyable?

15:36 Although, I wonder if there might be some that are, such as literal deftype sort of things

15:37 mvid: any idea why I wouldn't be able to resolve the symbol "catch" in this code? http://dpaste.com/795826/

15:37 nDuff: Sgeo: One still runs into mutable objects when working with Java interop

15:38 chouser: But there's no literal format for those, generally, just ctor syntax.

15:43 jeremyheiler: mvid: What's the actual error?

15:43 mvid: Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: catch in this context, compiling:(credits/foursquare.clj:46)

15:43 when i run lein test

15:44 djanatyn: TIL about the partial function :)

15:44 hooray for currying!

15:44 mvid: jeremyheiler: it fails in compilation

15:45 djanatyn: when is it appropriate to use partial, and when is it not?

15:46 chouser: mvid: That usually shows up when there are parens missing or in the wrong place, but that doesn't appear to be the case there. You're sure that's the snippet that's failing?

15:46 mvid: that is what the output is, but it might be somewhere else. thanks for the tip

15:47 is it better to use :require or :use ?

15:48 uvtc: I like :require, sometimes with :refer.

15:48 emezeske: mvid: Generally speaking, :require is preferable, as it will never cause problems when e.g. two namespaces contain the same symbol

15:49 uvtc: mvid: ^^

15:54 rbxbx: Anyone have thoughts on the `motivate` technique described here (http://bjeanes.com/2012/09/motivate-your-lazy-sequences) ?

15:55 Does seem like their should be a built-in for this pattern, or are there reasons you might not want to do this?

15:56 hiredman: ,(doc seque)

15:56 clojurebot: "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer."

15:58 rbxbx: hiredman that's in response to my query?

15:58 seems to fit the bill.

16:03 gfredericks: oh man that was my fault

16:04 * gfredericks knew about seque heck if

16:10 rbxbx: haha, gfredericks you caused a blagging :(

16:10 thx hiredman :)

16:12 gfredericks at least it was an opportunity to learn. Built-ins are good for production code, but figuring things out yourself is nice too :)

16:19 gfredericks: rbxbx: it true

16:25 l1x: hey

16:25 gfredericks: ~hey

16:25 clojurebot: what's up <from>

16:26 l1x: how could i remove an element of a set? this does not work -> (remove "bog" ("bog" "cog" "dog" "fog" "gog"))

16:26 gfredericks: disj

16:26 but that's a list there

16:26 Raynes: xeqi: ping

16:26 gfredericks: ,(remove #{"bog"} ("bog" "cog" "dog" "fog" "gog"))

16:26 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

16:26 Raynes: xeqi: With my clojail changes, code that used to timeout after 15 seconds runs in 38 milliseconds.

16:26 gfredericks: ,(remove #{"bog"} ["bog" "cog" "dog" "fog" "gog"])

16:26 clojurebot: ("cog" "dog" "fog" "gog")

16:26 Raynes: xeqi: Was it worth the wait? :D

16:27 l1x: i see

16:27 thanks

16:27 gfredericks: Raynes: you deleted the Thread/sleep calls?

16:27 Raynes: gfredericks: Lol, yeah, tots.

16:28 gfredericks: we do that every week at work. we're thinking of researching whether or not we could build a script to do it.

16:28 Raynes: But for real, clojail just accumulated a lot of cruft. I've rewritten the whole tester implementation now.

16:29 gfredericks: ##(/ 15 0.038) speedup is a lot of cruft

16:29 lazybot: ⇒ 394.7368421052632

16:29 xeqi: Raynes: always worth the wait for you

16:30 is lazybot updated?

16:31 firesofmay: Can anyone tell me why is Promise called as "Promise"? What is the context? I understand (a bit) what they do. But I am trying to understand the reason to name it that way.

16:33 weavejester: firesofmay: You're promising to assign it a value at a later date.

16:34 firesofmay: weavejester, ah okay. and future is like this function call will return its value sometime in future. Am I correct?

16:35 gfredericks: a future is like a promise where you give it the computation to produce the result at the same time you create the future itself

16:36 weavejester: firesofmay: Yes… but more precisely, what gfredericks said :)

16:36 gfredericks: promises decouple that; you create a promise without saying anything about who computes its value or how

16:36 weavejester: A future is essentially a promise + a calculation in a background thread that fulfills the promise.

16:36 firesofmay: gfredericks, ah that clears the difference.

16:36 weavejester, now I got it :)

16:37 dansalmo: Is there a function that will remove outer list containers until reaching the innermost list without losing any elements? such as (wtf? '(((xz) yz))) => ((xz) yz) , (wtf? '((xz) yz)) => ((xz) yz)

16:37 gfredericks: go and do great things

16:37 dansalmo: doubt there's a built-in for it

16:37 firesofmay: gfredericks, someday, someday.. :)

16:37 gfredericks: but easy to define yourself

16:38 dansalmo: So I must itterate until count > 1?

16:38 weavejester: Yeah, basically just a reduce

16:38 gfredericks: weavejester: I'll bet you $.49 you can't reduce that

16:38 * gfredericks intends to make himself rich today

16:40 weavejester: I guess it wouldn't be a reduce, now that I think about it, but now you've said that I want to write it using reduce :)

16:40 gfredericks: I think the only reasonable thing is loop

16:40 or iterate

16:40 weavejester: Yeah...

16:41 gfredericks: ,(first (drop-while #(and (sequential? %) (= 1 (count %))) '(((x z) yz))))

16:41 clojurebot: ((x z) yz)

16:41 gfredericks: wait that doesn't have iterate in it

16:41 what did I just do

16:41 * gfredericks scratches his head

16:42 weavejester: You could clojure.walk it and then find the first element that has a rest

16:42 gfredericks: oh my input didn't match his; I was wondering how the heck it came out different

16:43 ,(first (drop-while #(and (sequential? %) (= 1 (count %))) (iterate first '((((((xz) yz))))))))

16:43 clojurebot: ((xz) yz)

16:43 Raynes: xeqi: No.

16:43 weavejester: ,(clojure.walk/prewalk identity '(((xz) yz)))

16:43 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.walk>

16:44 gfredericks: I always feel icky about making iterates that will crash if you walk them too far

16:44 &(clojure.walk/prewalk identity '(((xz) yz)))

16:44 lazybot: ⇒ (((xz) yz))

16:44 gfredericks: weavejester: I doubt there's any natural walk solution either

16:45 weavejester: What about...

16:45 casion: is there any other way to stop clojure from promoting types other than littering my code with (unchecked-int )

16:46 Raynes: xeqi: Could you PM me a bit of code that fails the current sandbox? Preferably one line.

16:46 gfredericks: casion: is this about the byte-wrangling?

16:46 casion: gfredericks: yep

16:46 still having issues with clojure constantly promoting signed ints to longs

16:46 gfredericks: I'm convinced there's got to be something simpler than playing with primitive types

16:46 Guest88912: guile

16:46 gfredericks: signed ints now?

16:47 casion: gfredericks: I get fed signed or unsigned 2,3,4 byte values in big or little endian :|

16:47 and I'm tyring to use ByteBuffer to deal with this in a reasonable way

16:47 gfredericks: casion: through what kind of interface?

16:47 casion: but clojure is constantly promoting negative ints to longs

16:48 gfredericks: does the jvm expose any endiannesses?

16:48 casion: gfredericks: audio files, via javax.sound.sampled

16:48 gfredericks: yes, I get that information and store it in a map with other data and the byte stream

16:49 weavejester: Hm, maybe a loop would be simplest :)

16:49 gfredericks: ~hurray

16:49 clojurebot: \o/

16:51 gfredericks: casion: what's the signature of the method wherein you actually read data? returns a byte?

16:52 casion: gfredericks: I get 'frames' containing an array of bytes, which I have to split by the number of channels then convert to signed int or float

16:52 if I was dealing with just 16, 32 and 64bit values. everything would be peachy

16:53 but I have to support 8, 12 and 14 as well

16:53 gfredericks: oh you're talking about endianness regarding the order of bytes within larger words

16:53 casion: yes

16:53 gfredericks: I got distracted thinking about the order of bits within bytes

16:53 casion: I should have been a bit more clear about that, sorry

16:54 gfredericks: although if you have numbers that cross byte boundaries like 12-bit I guess you might have to worry about that anyhow

16:56 casion: if I could get clojure to just not promote types, ByteBuffer works great

16:57 I still have to handle a few cases manually, but it's better than writing 20 functions for the strange format combinations

16:58 gfredericks: casion: I assume you know about primitive type annotations right?

16:58 * gfredericks doesn't know for sure if they would work

16:58 casion: yeah

16:58 that's what I just started messing with now

17:01 dansalmo: gfredericks: thanks for the code solution to my question.

17:03 gfredericks: dansalmo: ##(loop [x '(((((bf) uh))))] (if (and (sequential? x) (= 1 (count x))) (recur (rest x)) x))

17:03 lazybot: ⇒ ()

17:03 gfredericks: w00ps

17:04 l1x: is there a way to replace the nth character in a string without using the setCharAt from java?

17:05 dnolen: l1x: yes but it's less straighforward that setCharAt.

17:05 l1x: the only thing i can think of is to deconstruct the string and use the replace-first

17:06 and build it up again

17:06 gfredericks: dansalmo: ##(loop [x '(((((bf) uh))))] (if (and (sequential? x) (= 1 (count x))) (recur (first x)) x))

17:06 lazybot: ⇒ ((bf) uh)

17:06 gfredericks: yeah that's it

17:07 dnolen: l1x: Clojure strings are Java strings, what's the problem w/ using setCharAt?

17:07 l1x: does that work when you are running your code on .net clr?

17:08 dnolen: l1x: I doubt it but that's a problem Clojure hasn't committed to solving.

17:09 l1x: i see

17:13 dnolen: l1x: there's been some talk of CL-like conditional compile - upon which platform generic string ops could be built but it's near clear such a lib would even make it into core.

17:13 l1x: yeah

17:13 cool

17:16 emezeske: l1x: I have a conditional-compile lib called prism, but it doesn't support CLR yet

17:17 l1x: It's pretty much a hack, but it works fine for jvm vs js, and I'm sure it would work fine with CLR with some small changes

17:17 l1x: nice

17:18 emezeske: l1x: Basically you'd have to find some way to tell, from a macro, that it's running in the CLR environment

17:18 l1x: that's the hack part :)

17:18 l1x: :)

17:18 emezeske: Sadly, there's no standard clojure.core/*platform*, or it would be dead-easy

17:18 l1x: reminds me of some autconfigure hacks on unix

17:18 emezeske: Yeah, very similar (unfortunately)

17:23 dnolen: l1x: http://dev.clojure.org/display/design/Feature+Expressions

17:25 l1x: i see, thanks

17:25 i just would like to rewrite this -> (let [sb (StringBuilder. word)] (for [altc alphabet] (str (doto sb (.setCharAt 1 altc)))))

17:26 to a clojure only implementation

17:26 i guess it is possible ti recur

17:26 hyPiRion: $javadoc StringBuilder

17:27 lazybot: http://docs.oracle.com/javase/6/docs/api/java/lang/StringBuilder.html

17:27 l1x: https://gist.github.com/3613696

17:27 i got this far

17:28 hyPiRion: Why would you like to do a (.setCharAt 1 ...) multiple times?

17:28 l1x: sorry it is just a debug line, in the function it is using an index

17:29 hyPiRion: okay.

17:29 ToxicFrog: Is there a recommended library for dealing with character encodings in clojure?

17:29 Automatically skipping BOMs, for example?

17:29 l1x: now the tricky part is to decompose the string to first & rest and recur on the function and return the first + rest where the rest has the first character replaced

17:30 dnolen: l1x: are you planning on having it run on the JVM & CLR?

17:30 l1x: well, i would like to write the way that i dont need to worry about that

17:32 dnolen: l1x: if you're not going to actually use both platforms then I wouldn't bother. If you are, probably more productive to weigh in on Feature Expressions.

17:34 l1x: dnolen: i am pretty close, the only problem i dont fully understand recur yet and I am not sure how to build a return []

17:37 dnolen: ,(apply str (assoc (into [] "foo") 2 \r))

17:37 clojurebot: "for"

17:38 dnolen: l1x: ^ but grossly inefficient, as well as whatever it sounds like you are working on. Perhaps that doesn't matter for your application. But I as I've already said, I wouldn't bother, use setCharAt

17:38 l1x: this is just a learn2code in clojure, i dont care about performance at all. in real project i always use the java calls cause we are working on JVM

17:39 dnolen: l1x: ah then go for it ;)

17:39 l1x: https://github.com/l1x/euler/blob/master/src/euler/core.clj#L94

17:39 casion: is there any way to process all-but the last item in a seq with map-indexed withouth using something like butlast?

17:40 I thought about comparing the index to count inside the map, but that also seems inefficent

17:40 dnolen: casion: why do you want to avoid butlast?

17:40 gfredericks: if the collection isn't Counted then I assume anything would be equivalent to butlast

17:41 casion: dnolen: linear time

17:41 dnolen: casion: but you're already using map-indexed

17:41 casion: yes, and I don't want to incur that cost twice

17:41 dnolen: casion: map-indexed and butlast are both lazy

17:41 casion: if I can avoid it

17:42 gfredericks: reducers!

17:42 dnolen: casion: oops

17:43 casion: oops?

17:43 dnolen: casion: I thought butlast was lazy

17:44 gfredericks: casion: pulling something off the end of a seq is always going to be linear, if you want better than that you'll have to back up to wherever the seq came from and get something smarter

17:44 casion: gfredericks: ok

17:45 dnolen: casion: though still for your purposes map-indexed + butlast is still one traversal.

17:45 (butlast (map-indexed ...))

17:46 casion: well, I'm writing this silly byte-array value getter to handle buffer sized 1/2/4/8

17:46 and I came up with (reduce + (map-indexed #(bit-shift-left (bit-and %2 0xFF) (* % 8)) val)

17:47 except the last value shouldn't be & 0xff

17:47 so maybe there's another solution I'm missing

17:48 gfredericks: is %2 supposed to be a byte?

17:48 casion: yes

17:48 % index, %2 byte

17:48 gfredericks: (bit-and %2 0xFF) actually does someothing?

17:49 casion: yes, it unsigns the value

17:49 that above is assuming little-endian btw

17:50 so if fed a byte-array of [0xd9 0xfe 0xFF], it should output -295

17:50 gfredericks: well arrays are counted

17:51 casion: but the last value has the sign, so & 0xff blows that… so you just shift that by itself

17:51 gfredericks: I assume (count some-array) is constant

17:51 (but it might not be; it just could be)

17:52 casion: I have something like (reduce + (map-indexed (fn [idx itm] (bit-shift-left (if-not (= idx count) (bit-and itm 0xff) itm) (* idx 8))) val))

17:52 and that works, but I'm not sure how clojure handles that conditional

17:52 gfredericks: not sure how clojure handles it?

17:52 you compute count outside the thing right?

17:52 casion: correct

17:53 gfredericks: so what's ambiguous about that?

17:53 casion: that above is slower than butlast it seems :|

17:54 gfredericks: if you're worried about speed you might just use loop

17:55 casion: that seems like it'd be the same?

17:55 gfredericks: I think it could be faster for less function calls

17:56 casion: I'd still have to compare every value against the index, or use butlast wouldn't I?

17:56 gfredericks: you could keep an index and increment it up to the second-to-last position

17:56 casion: hmm, I see what you're saying

17:56 and I get that as well now haha

18:34 estebann: if you know that a sequence will always be entirely consumed and will be reasonably sized, is it better to fully realize it at the time of creation (rather than producing a lazy sequence)?

18:37 or perhaps a better way to state my question, are there any significant penalties associated with lazy realization of sequences in this case?

18:40 hyPiRion: estebann: It will be slower than eager realization.

18:41 estebann: hyPiRion: gotcha... thanks

18:41 chouser: but realizing a lazy seq early is not necessarily slower than realizing it later.

18:41 hyPiRion: It shouldn't be noticably different.

18:41 estebann: ok

18:41 chouser: using reducers or something else that avoids building the lazy seq entirely might be faster.

18:41 technomancy: estebann: clojure chunks certain kinds of sequences for you behind the scenes

18:42 unfortunately it's often a bit unpredictable when happens

18:42 estebann: is there any benefit to all-at once realization eg doall vs, one at a time?

18:42 technomancy: only one way to find out

18:42 chouser: estebann: I wouldn't assume so without measuring.

18:42 estebann: technomancy: touche

18:42 casion: gfredericks: It seems that if I make sure I'm using an array, (conj (map f (butlast array) (last array)) is fastest

18:43 damn missing parens in there, I need to switch back to erc

18:43 technomancy: estebann: instead of creating a lazy seq and then forcing the whole thing, it might be marginally more efficient to just mapv straight to a vector instead

18:43 but on no account should you take my word for it without empirical evidence

18:43 estebann: ok.. i'll do a little testing

18:43 thanks

18:43 hyPiRion: But, well, you know, if speed is an issue, consider going into java and use pure arrays instead.

18:44 chouser: or staying in clojure and using pure arrays

18:45 hyPiRion: chouser: That's what I meant - maybe I phrased it bad.

18:45 chouser: ah

19:09 gfredericks: casion: that's quite interesting

19:09 casion: I guess because butlast/last are constant time on arrays?

19:09 gfredericks: not butlast at least

19:09 casion: and that's faster than having any conditionals in a loop

19:10 gfredericks: it builds up a vector

19:10 casion: my guess at least

19:10 does it?

19:10 gfredericks: yep; eagerly

19:10 casion: hmm

19:10 gfredericks: that's why dnolen retracted his lazy assertion

19:10 casion: it's almost 2x faster than the map that checks for the last index

19:11 and about 50% faster than a plain loop

19:11 gfredericks: I wonder if arrays are chunked

19:11 djanatyn: anyone use nrepl with evil-mode?

19:11 amalloy: djanatyn: Raynes probably does

19:12 djanatyn: I'm trying to figure out how to have the *nREPL error* buffer always in emacs mode

19:12 Raynes: Sure.

19:12 No clue.

19:13 djanatyn: I can just do \q but there's probably a better way to do it

19:19 hmm. I'm trying to work with binary trees

19:19 I want to write a function that generates a tree of all possible results from flipping a coin n number of times

19:20 now that I think about it, I guess I don't even need a tree. I can just have a list of lists

19:27 O_O

19:28 ,(conj '(1 2) 3)

19:28 clojurebot: (3 1 2)

19:28 djanatyn: ,(conj [1 2] 3)

19:28 clojurebot: [1 2 3]

19:28 gfredericks: ,(doc conj)

19:28 clojurebot: "([coll x] [coll x & xs]); conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type."

19:28 djanatyn: I'm trying to read the documentation to understand why this happens

19:29 sorry if this comes up a lot, I can imagine a lot of people running into this issue

19:29 gfredericks: lists are fast at the front, vectors are fast at the end

19:29 djanatyn: okay, that makes sense

19:29 why are vectors fast at the end?

19:30 * gfredericks tries to think about the implications of building vectors backwards

19:30 djanatyn: I understand why linked lists are fast at the front

19:30 gfredericks: do you know anything about the impl of vectors?

19:32 djanatyn: I thought that vectors didn't evaluate their elements

19:32 gfredericks: well that's a characteristic of vectors-as-source-code

19:32 but they are also data structures, distinct from lists

19:33 djanatyn: are they like arrays?

19:33 gfredericks: they couldn't easily be arrays because they are persistent/immutable

19:33 djanatyn: okay. is there a good resource to read about clojure data structures?

19:34 gfredericks: vectors have been described a good bit; there's a nice video or two as well

19:36 http://blip.tv/clojure/daniel-spiewak-extreme-cleverness-functional-data-structures-in-scala-5970151

19:36 djanatyn: also, how do I add an item to the front of a list? use conj after reversing, and reverse again?

19:37 gfredericks: conj works for the front of a list; did you meant the front of a vector or the end of a list?

19:37 djanatyn: umm

19:37 gfredericks: ,(conj '(3 5 54) 2844)

19:37 clojurebot: (2844 3 5 54)

19:38 djanatyn: the intended behavior I'm looking for is having (function '(foo bar) 'baz) evaluate to '(foo bar baz)

19:38 gfredericks: ah so we're clashing on our definition of "front"

19:38 the easiest way is ##((fn [coll x] (concat coll [x])) '(foo bar) 'baz)

19:38 lazybot: ⇒ (foo bar baz)

19:39 gfredericks: but keep in mind that's not efficient

19:39 Sgeo: What's this ## stuff?

19:39 gfredericks: that's how you kick lazybot and make him pay attentien

19:39 * gfredericks is off for dinner for a bit

19:39 djanatyn: okay, thank you gfredericks

19:42 Sgeo: Is there a central repository for Clojurescript?

19:44 Frozenlo`: gfredericks: either the presenter moves too much, either the camera is too zoomed in.

19:46 S11001001: djanatyn: if there is a concern about forcing the first argument to conj, cons is better for creating a new list whose head is your arg and tail is your other arg

19:47 Sgeo: If some Java code uses Math.sin, I can't with-redefs that away, can I?

19:47 To replace sin with another function

19:56 gfredericks: nope

20:05 djanatyn: can you use defn with clojurebot?

20:05 gfredericks: not really

20:05 xeqi: ,(defn asdf [x] (+ 1 2))

20:05 clojurebot: #<Exception java.lang.Exception: SANBOX DENIED>

20:05 djanatyn: is that supposed to say SANDBOX?

20:07 anyway, regardless, I did it!

20:07 https://gist.github.com/3615071

20:07 (list-possible-sequences 2)

20:07 => ((heads heads) (heads tails) (tails heads) (tails tails))

20:08 and I can map my other functions over that :)

20:08 (map count-heads-and-tails (list-possible-sequences 2))

20:09 gfredericks: djanatyn: so for this purpose you could have just as well added to the "back" of the list, right?

20:09 djanatyn: => ({:heads 2, :tails 0} {:heads 1, :tails 1} {:heads 1, :tails 1} {:heads 0, :tails 2})

20:09 gfredericks: ...hmm

20:09 yes -_-

20:09 gfredericks: or really you could have been using lists or vectors but not cared which and just used conj

20:09 djanatyn: order doesn't matter here.

20:09 amalloy: &((fn flips [n] (lazy-seq (if (zero? n) [[]], (for [flip '[heads tails], more (flips (dec n))] (cons flip more))))) 2)

20:09 lazybot: ⇒ ((heads heads) (heads tails) (tails heads) (tails tails))

20:10 djanatyn: ugh, for confuses me

20:10 is it even a macro?

20:10 gfredericks: it is

20:10 amalloy: you should also stop calling the right of a linked list the front. everyone in the world calls it the back

20:11 gfredericks: or "end"

20:11 amalloy: sure

20:11 djanatyn: okay, sorry. I have trouble labeling the front and back of any one dimensional thing

20:14 amalloy: anyway, for is worth learning. eagerly building a list of size 2^n seems like a bad idea in general

20:19 gfredericks: &((fn flips [n] (let [N (bit-shift-left 1 n)] (for [x (range N)] (-> x (+ N) (Long/toString 2) (rest) (->> (map {\0 'heads \1 'tails})))))) 3)

20:19 lazybot: ⇒ ((heads heads heads) (heads heads tails) (heads tails heads) (heads tails tails) (tails heads heads) (tails heads tails) (tails tails heads) (tails tails tails))

20:21 amalloy: huh. i would have assigned heads to 1. i wonder if anything interesting lies behind our different choices

20:21 gfredericks: oh man I totally hadn't even thought about it

20:21 I don't even remember choosing

20:21 I just typed

20:22 I would've done like you said if I had thought about it I'm sure

20:33 nvy: hello, what does ->> do?

20:33 gfredericks: ,(doc ->>)

20:33 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."

20:34 nvy: thanks

20:34 gfredericks: so (->> x (foo baz) (bar bajoong)) is (bar bajoong (boo baz x))

20:38 cshell_: does anyone know of a clojure wrapper around processing? (ie processing.org)?

20:38 or something similar for drawing graphics/animations?

20:39 wmealing_: i thinkquill

20:39 cshell_: wmealing_: that's awesome, thanks!

21:07 Sgeo: I have reason to make a mock Math class and force all code to use it. Is this accomplishable?

21:09 brehaut: great evil might be possible with classpath munging, but it might be extremely unpredictable

21:10 gfredericks: probably easier to decompile the code you care about, switch the calls, and recompile :D

21:11 amalloy: brehaut: Math is in java.lang, so i think you'd need to recompile all of the jre and put your version on the bootclasspath when you start clojure

21:14 Sgeo: Hmm, darn

21:15 I just want to replace those static methods with ones that can accept dual numbers

21:15 gfredericks: what are dual numbers?

21:16 stankley: gfredericks: http://en.wikipedia.org/wiki/Dual_number

21:16 … no idea

21:16 Sgeo: http://en.wikipedia.org/wiki/Dual_number#Differentiation the reason I'm interested

21:17 It's an easy way to calculate derivatives

21:18 gfredericks: derivatives of polynomials over reals is difficult?

21:21 Sgeo: Can do more than polynomials

21:22 gfredericks: so what library are you using whose behavior you want to redefine?

21:23 Sgeo: ...well, I sort of wanted to make it work with any function in Java or Clojure that was a mathematical function, and calculate the derivative without changing the function itself

21:24 gfredericks: so differentiate here means differentiating at a point?

21:25 Sgeo: Yes

21:25 gfredericks: that is terribly interesting

21:25 arohner: ,(name :foo/bar)

21:25 clojurebot: "bar"

21:25 arohner: that's irritating

21:26 gfredericks: arohner: that's what the name function is for

21:26 it complements the namespace function

21:26 Sgeo: (Although automatic differentiation doesn't seem to work well when the derivative is undefined. (lambdabot in #haskell has an AD thing loaded)

21:26 gfredericks: Sgeo: so if you wanted to do sin you would need some approximation so that you could compute it for duals?

21:27 arohner: I don't think it's very common to have a namespaced keyword and to want to convert the whole thing to a string without a colon

21:27 Sgeo: gfredericks, I _think_ you'd just write the sin function that accepts duals to do the sine of the real part and ... the cosine of the coefficient of the dual (I'm not certain though, but I think it would be defined in those terms))

21:28 ,(let [fullname (fn [sym] (str (namespace sym) "/" (name sym)))] (fullname :foo/bar))

21:28 clojurebot: "foo/bar"

21:29 Sgeo: Hmm, I should learn to letfn

21:29 I guess letfn is the equiv. of CL's labels?

21:29 ,(doc letfn)

21:29 clojurebot: "([fnspecs & body]); fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+) Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body."

21:29 gfredericks: ,(subs (str :foo/bar) 1)

21:29 clojurebot: "foo/bar"

21:30 Sgeo: ,(doc subs)

21:30 clojurebot: "([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."

21:30 Sgeo: Symbols are strings now?

21:30 Or act as them for ... stringy purposes?

21:30 gfredericks: no I called str on them

21:30 on it*

21:30 Sgeo: Oh

21:31 ,(str :foo)

21:31 clojurebot: ":foo"

21:31 Sgeo: ,(namespace :foo)

21:31 clojurebot: nil

21:36 gfredericks: ,(name '/)

21:36 clojurebot: "/"

21:36 gfredericks: &:/

21:36 lazybot: java.lang.RuntimeException: Invalid token: :/

21:54 * Khaoz having a lot of fun learning clojure

21:54 * qmx is having too

21:54 * gfredericks is having a lot of fun

21:55 qmx: repl-based programming is spoiling me

21:55 specially after getting vimclojure appropriately-setup

21:57 spoon16: how can I get a multiline string to print at the repl?

21:57 ##(pprint "hello\nworld")

21:57 lazybot: java.lang.RuntimeException: Unable to resolve symbol: pprint in this context

21:58 spoon16: (clojure.pprint/pprint "hello\nworld")

21:58 gfredericks: spoon16: use print or println instead of pprint

21:58 spoon16: there you go

21:58 nice

Logging service provided by n01se.net