#clojure log - Jul 24 2009

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

0:58 mebaran151: what's the best way to convert an integer to a byte array in bigendian notation?

1:42 replaca_: anyone here no something about ring and jetty?

1:43 I'm trying to understand how to parse posted form data

1:43 without writing my own parser for it!

1:44 arbscht: I think they are held in :form-params in the request map. is that what you mean?

1:45 replaca_: I think that's what I mean, but they don't seem to be there

1:45 (map doesn't have that key)

1:46 the post is x-www-form-urlencoded fwiw

1:49 hmm, that key doesn't exist anywhere in ring. Is it a compojure thing?

1:52 yes, I see that it is now

2:00 hiredman: I think ring doesn't parse form stuff for you, it operates below that "level"

2:01 PatrickC: Hello.

2:08 Hello

2:42 Lau_of_DK: Top of the morning gents

3:10 Fossi: hi

4:00 AWizzArd: ~seen kotarak

4:00 clojurebot: kotarak was last seen quiting IRC, 587 minutes ago

4:19 Lau_of_DK: ~get kotarak

4:19 clojurebot: I don't understand.

4:25 AWizzArd: Maybe you can write a patch Lau, so that the bot can run that function?

4:40 Lau_of_DK: Np - It does require some cooperation on the part of the one who is being fetched though - I'm thinking phone app or something similar

4:52 Fossi: "emacs" question: is there an easy way to find out what file a method is in?

4:53 Lau_of_DK: Well... :) M-! grep -nr "foo" *, would do it

4:54 Are you on Linux?

4:54 @ Fossi

4:54 Fossi: well, that isn't really so helpful in jars

4:54 Lau_of_DK: Oh, you mean by way of reflection ?

4:54 Fossi: it would show up, but i'd like the namespace or such

4:55 (source foo) is great, but unfortunately doesn't give the file either

4:56 Lau_of_DK: I'm blank, never had that question before

4:56 Why would you want the filename?

4:57 Fossi: well, more the namespace, but it's kinda the same

4:57 say, i (use 'compojure), but really only call start, so i would like to find out, where that is defined

4:58 and a hundred other small use-cases like that

5:00 it's also a bit annoying there's no automatic import cleanup :)

5:01 Chousuke: ,(:file ^#'vec); It should be in the metadata

5:01 clojurebot: "clojure/core.clj"

5:01 Fossi: ah, nifty

5:01 Lau_of_DK: very

5:01 Chousuke: :line, too :P

5:01 ,^#'vec

5:01 clojurebot: {:ns #<Namespace clojure.core>, :name vec, :file "clojure/core.clj", :line 241, :arglists ([coll]), :doc "Creates a new vector containing the contents of coll."}

5:02 Lau_of_DK: Awesome tip

5:02 Chousuke, I hereby grant you the title of Tipster !

5:03 Fossi: that make a nice addition to repl-utils imho

5:03 Chousuke: :P

5:03 Fossi: 'd

5:03 Chousuke: what would? that's just metadata :P

5:12 cschreiner: ...

5:13 Lau_of_DK: ;;;

6:41 rottcodd: how do I checkout the par branch?

6:42 Chousuke: git checkout -b par origin/par

6:42 that sets up a local par branch to track the par branch on origin

6:42 ie. rhickey's github repo.

6:43 rottcodd: thanks

6:44 Chousuke: if you don't need a tracking branch, git checkout origin/par works too, but you won't be able to commit in it :)

8:35 djpowell`: which jsr166y.jar do I need for the par branch?

8:35 rhickey: the one in the downloads section on github

8:36 djpowell`: ah, ok

8:36 rhickey: http://cloud.github.com/downloads/richhickey/clojure/jsr166y.jar

8:39 djpowell`: what are the current experimental branches? par, chunks, and ensure?

8:40 rhickey: yes, and par has everything chunks does

8:40 djpowell: nice. do they both have mutable collections?

8:41 rhickey: yes, exactly

8:41 mutable vectors, and that is all the chunks branch has over master at this point, the actual chunks work is in master now

8:42 djpowell: is the main effect of the chunks work to speed up things like map over vectors?

8:43 rhickey: djpowell: yes, and any other collections that can support block access, like arrays

8:44 not yet implemented for maps/sets, but possibly useful there too

8:45 right now only a few ops (map/reduce/filter) have chunk support, but I'm hoping for some contributions (for, doseq etc)

8:46 while not every seq op can be parallelized, most can be chunked

9:01 Chouser: Well, I'm still doing battle with JNI, but now finally to an issue that's Clojure-related. That is, loading me .so and calling a java method works from .java code, but not from .clj code.

9:02 I'm wondering if it's a classloader issue of some sort

9:03 rhickey: Chouser: almost certainly

9:03 Chouser: like perhaps the classloader used to call System/loadLibrary has to have a particular relationship with the classloader used to call the method

9:03 rhickey: shouldn't it?

9:04 Chouser: I tried (do (System/loadLibrary "my_lib") (my.lib/method))

9:04 at the repl, that should be done all in one classloader, right?

9:05 anyway, that fails: java.lang.UnsatisfiedLinkError: my.libJNI.method()I

9:06 Should my goal be to get the root classloader to do the loadLibrary()? Is that possible?

9:07 rhickey: Chouser: I'm trying to understand the semantics of loadLibrary

9:09 Have you tried this advice:

9:09 clojurebot: this is not a bug

9:09 rhickey: If native methods are to be used in the implementation of a class, a standard strategy is to put the native code in a library file (call it LibFile) and then to put a static initializer:

9:09 static { System.loadLibrary("LibFile"); }


9:09 within the class declaration. When the class is loaded and initialized, the necessary native code implementation for the native methods will then be loaded as well.

9:09 from: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runtime.html#loadLibrary(java.lang.String)

9:09 Chouser: I was just about to paste that.

9:09 so do that in a .java and then try the calls from .clj. I'm on it...

9:09 rhickey: manual consumer calls to loadLibrary seem fraught

9:10 the native library should be an implementation detail of some class, and loading the classes should work as always

9:11 er, work as well as always, which is not ... always

9:11 Chouser: heh

9:12 rhickey: have you set java.library.path?

9:12 Chouser: woo!

9:12 static { } did it

9:13 sgtarr_: Clojure is awesome, I just need to play around with it for months before I would dare to use it in a commercial / enterprise setting (which is my job).

9:13 cemerick: ut oh, do we need a static init form in clojure now? :-/

9:14 Chouser: cemerick: I don't think so.

9:14 sgtarr_: rhickey: And you are turning into the new rockstar in Computer Science, no doubt. :-)

9:14 Chouser: I've already got a pile of .java generated by swig for this JNI stuff. I just need to figure out how to inject a static init into the code it's producing.

9:15 adding it manually to the .java is what just worked. The .java file is already there and already requires compilation, so not much value in moving it to .clj

9:15 rhickey: sgtarr_: not really, I'm just a toolmaker

9:16 sgtarr_: That's what James Gosling says too.

9:47 Chouser: I assume there's no place to put .java code that will run when any class in a package is used, right?

9:48 swig is missing a feature I need. Not really java's fault for failing to make up for it...

9:52 cemerick: Chouser: ServiceProviders will do that, although it's JDK6+ IIRC

9:55 Chouser: I'm finding javax.imageio stuff, but I assume that's not what you're talking about?

9:57 cemerick: that was the original impl of the pattern in JDK5, I think

9:58 hrm, I think the "run when a class in a package is accessed" functionality was tied to the imageio stuff, though.

9:58 what I was thinking about that is generally-useful is: http://java.sun.com/javase/6/docs/api/java/util/ServiceLoader.html

9:58 No package-level automatic stuff, tho, as far as I can tell.

10:15 rzoom: as a watcher on assembla, is there any way to not get emailed so often?

10:16 I don't see an "Alerts" tab on the top of the space

10:16 djpowell: rhickey: how many cores did you have on the machine you did the 'pvmap rocks'?

10:19 Chouser: rzoom: Stream tab, upper-right corner, "change alert settings"

10:31 rzoom: Chouser: thanks! the assembla FAQ says there is an "Alerts" tab.

10:44 rhickey: djpowell: 4 cores

11:05 stuartsierra: I can't reproduce this out-of-memory error: http://groups.google.com/group/clojure/browse_thread/thread/c0e889d2a6c200ba

11:07 hiredman: maybe he has a small heap

11:07 stuartsierra: I tried it with -Xmx64m and a 1.5 GB file. No problem.

11:08 hiredman: well

11:08 1.5gb is hardly "really big"

11:10 and who knows what his line processing function does

11:11 stuartsierra: he said it failed on just (write-lines "out" (line-seq (reader "bigfile")))

11:12 cemerick: rhickey: I forget: have you previously warned me off the idea of having an .isForced() method on Delay?

11:13 * hiredman tries out a 36gig file

11:14 hiredman: failed because I don't have 36 gigs free to copy to

11:14 * stuartsierra tries 4.5gb

11:14 hiredman: wait, yes I do

11:14 java.lang.RuntimeException: java.io.IOException: Input/output error (NO_SOURCE_FILE:0)

11:14 hmm

11:18 java.lang.OutOfMemoryError: Java heap space (NO_SOURCE_FILE:0)

11:18 there we go

11:19 after writting 1g of the 36g file

11:20 stuartsierra: Now why don't I get that?

11:20 * stuartsierra is using (write-lines "/tmp/out" (line-seq (reader "/tmp/bigfile")))

11:24 stuartsierra: This also works: (let [lines (line-seq (reader "/tmp/bigfile"))] (write-lines "/tmp/out" lines))

11:24 rzoom: very long lines?

11:24 stuartsierra: hmm, possible. That would have to be a single line larger than the Java head, though.

11:26 s/head/heap/

11:31 duck-streams/write-lines isn't truly lazy; maybe that's the problem

11:32 mebaran151: is there anyway to hook in test-is with a junit runner so my ide could run them: I'm using the Netbeans plugins and I just want an easy way to run my tests

11:33 stuartsierra: mebaran151: Not yet, want to write one? :)

11:33 mebaran151: eh I could take a shot at it

11:33 stuartsierra: There's a patch for JUnit-style XML output, I need to get that applied.

11:34 mebaran151: don't need the xml output: I'd just like to integrate it with my ant task

11:35 stuartsierra: Working with JUnit from Clojure is difficult because it relies so heavily on Java annotations.

11:35 That's why I didn't try.

11:35 clojurebot: http://clojure.org/rationale

11:35 mebaran151: I always thought annotations were cludgy

11:35 it seems like a poor man's solution to make things slightly more dynamic

11:36 I know Scala Specs does it though, and I don't think Scala support annotations yet

11:36 cemerick: mebaran151: you don't really need junit integration to make test-is tests work nicely with ant

11:36 stuartsierra: cemerick: That's true.

11:37 mebaran151: ah, how would I set this up

11:37 cemerick: lisppaste8: url?

11:37 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

11:37 cemerick pasted "test-is ant harness" at http://paste.lisp.org/display/84139

11:37 cemerick: ^^ that's what we use. Crude, but it works.

11:38 stuartsierra: Here's how I do it: http://github.com/stuartsierra/altlaw-backend/blob/5b9edd606df944e5c58e5ad32191b27436201950/build.xml#L95

11:38 cemerick: throws an exception on test-is failure, so ant's failonerror="true" will halt the build, etc.

11:38 mebaran151: also how would I organize my tests in /test?

11:39 cemerick: mebaran151: however you want :-)

11:39 mebaran151: no specific sort of dir format mandated from on high?

11:39 cemerick: I set it up so that all clj files in src/test are munged into namespaces, and passed as args to the class/main method I pasted above

11:40 mebaran151: I see

11:40 cemerick: if a particular test ns doesn't define any tests, then the test-ns call is a no-op, so there's no harm in casting a wide net

11:40 stuartsierra: so do you have to manually maintain a list namespaces to load in org.altlaw.load-all?

11:41 Chouser: ok! swig indeed has the features I needed.

11:41 now every java class it generates has "static { module.init() }"

11:42 mebaran151: I see

11:42 Chouser: and the java class named "module" has "static { System.loadLibrary("my_lib"); }"

11:42 rhickey: Chouser: makes sense

11:43 cemerick: mebaran151: irc being what it is, I can only surmise that you're uneasy ;-)

11:43 Chouser: so an attempt by java/clojure to use any of the generated java classes causes the moudule's init method to be called which itself does nothing but causes the loadLibrary to happen once.

11:43 this seems blogworthy. swig makes this much more pleasant than it otherwise would be.

11:43 mebaran151: a little uneasy

11:44 right now I've just been manually running my tests from the repl

11:44 but before I deploy, I love having a test suite I can run just to make sure everything made to the server okay

11:44 cemerick: yeah, definitely

11:45 FWIW, the mechanism we use is roughly what ant does with junit tests now -- it crawls around your test classpath, looking for TestCases and Suites to run *shrug*

11:45 There's definitely smarter ways to do it, but hardly any easier ones :-)

11:46 stuartsierra: cemerick: not with the addition of clojure.contrib.find-namespaces

11:46 cemerick: that was in response to the load-all question

11:46 cemerick: oh, that's interesting. Never knew it was there. We've got an ant contraption that converts clj filenames -> namespaces

11:47 we don't do any loading tricks, so we have a 1:1 correspondence

11:47 stuartsierra: that's basically what find-namespaces does, but it also parses the (ns...) declaration

11:47 cemerick: well, clj code is way better than an ant contraption :-P

11:47 stuartsierra: I originally had org.altlaw.load-all when I was doing a lot of gen-class stuff, I can probably eliminate in now.

11:48 cemerick: the only advantage using ant has is that there's an easy mechanism to prevent recompilation of files that haven't changed since the last build.

11:50 stuartsierra: Yes, that's harder. I just recompile all the .clj files when any of them have changed.

11:51 cemerick: once our incremental build process crossed the 1-minute mark (because of clj recompilation), I implemented that. Now it's 12s :-)

11:52 stuartsierra: nice

11:57 mebaran151: I really wish the json.read wasn't so strict: uneval in mozilla actually creates non-spec json

12:00 hiredman: mebaran151: you might checkout clojure-json

12:01 mebaran151: how to spec is it? I was reading the source code and it looked equally inflexible (I think it demanded quotes around string keys too)

12:02 hiredman: it could be even less flexible, dunno

12:05 ~def write-lines

12:07 mebaran151: also is there a quick clojure way to turn an Integer into its big endian byte encoding and back?

12:10 hiredman: ,(Integer/toBinaryString 3)

12:10 clojurebot: "11"

12:10 angerman: does anyone have experineces with clojure on terracotta?

12:10 * angerman is wondering if he could abuse the campus's computer lab to do some heavy numerical processing. And MATLAB is definitly not up to the task ...

12:11 drewr: someone was making progress with that but I haven't seen any updates

12:11 angerman: I found a blog that supposidly said it had it running

12:11 and someone on the ML said he deployed something like that in a mecial hospital

12:12 replaca_: angerman: I would go to the clojure google group and do a search. I remember there was some discussion of terracotta support a few months back

12:12 angerman: replaca_: yep, as I said :) ... I guess i sould switch vom MailingList to Group :)

12:13 replaca_: Wow! github has been super-slow the last couple of days

12:13 angerman: someone was working on generalized support and rich was helping him IIRC

12:14 angerman: but I haven't heard anything about it for a while

12:14 angerman: if you're looking for distributed execution you might look at swarmiji too

12:14 stuartsierra: Ok, I put the JUnit XML output in a patch on Assembla. I think I did it right.

12:15 angerman: replaca_: I'm basically looking for a solution to kinda split all the parralliyable stuff across the systems we have here

12:15 cemerick: angerman, replaca_: pjstadig (Paul Stadig) did the initial work, with Rich's help: http://paul.stadig.name/2009/03/clojure-terracotta-update.html

12:16 angerman: I think there are like 12 nearly idle opertron systems + a few Mainframes for the sun ray system that's employed on the campus

12:16 rhickey: angerman: also see: http://github.com/amitrathore/swarmiji/tree/master

12:16 hiredman: there is always hadoop

12:16 angerman: cemerick: ok, i found that blog too. so that's the defacto piece to use :)

12:17 stuartsierra: hadoop isn't aimed at compute-intensive apps, although it may still work

12:18 cemerick: ooh, swarmiji looks interesting

12:18 angerman: hmm swarmiji looks nice

12:18 cemerick: hadoop is so friggin' complicated...

12:18 * angerman has to think about how to use the machines.

12:19 angerman: cemerick: well I won't bother with the datastore part. I got all the data in a postgresql db already, which did a lot of the prefiltering of the data using pl/R

12:19 matting: Hi! I came accross a problem I can't solve: I need to use some java gui and therefore i need to reimplement the paint() method. So my guess is to use 'proxy'. But i need more information (here: what stuff to draw) in paint() that is supplied by the arguments.

12:19 angerman: matting: ?

12:20 replaca_: the advantage of swarmiji is that it seems pretty simple, but I haven't had a chance to actually use it yet

12:20 matting: i'd like to have a function that draws a path

12:20 stuartsierra: matting: proxies can be closures

12:20 rhickey: matting: (let [other stuff] (proxy ... other))

12:20 hiredman: matting: the "methods" in proxys are fns so they can close over stuff

12:21 stuartsierra: Ha! 3 different forms of the same answer.

12:21 matting: :)

12:21 * angerman did some processing-clj stuff with clojure on the repl the other day

12:22 matting: but i still don't get it. suppose i have two paths path1 and path2. i'd like to do sth like (draw-path path1) or (draw-path path2)

12:22 angerman: though before i tired that I did use a jpanel in a jframe

12:22 replaca_: hiredman: I have a new json file for clojurebot to chew on that has the pointers to clojure.contrib on github

12:22 matting: does this mean i need to create a new proxy for each call?

12:22 replaca_: hiredman: it's at http://github.com/richhickey/clojure-contrib/raw/gh-pages/api-index.json

12:23 hiredman: I think it should be identical to the old old, format-wise

12:23 *old old => old one

12:23 hiredman: ok

12:27 replaca_: hiredman: let me know if you have any issues

12:27 djpowell: paint is a callback that is called by java - you put the instructions on how to paint the screen in it, and java will call it when it needs to repaint the screen - which you can also trigger by telling it to repaint. so you'd have a single proxy for your window or panel or whatever that overrides paint.

12:27 hiredman: replaca_: it works

12:28 (I have no issues)

12:29 djpowell: as to what to put in paint - you might structure your application so that another thread updates a ref with the current state of the world, in a loop, that also calls repaint on the component, and sleeps for a bit, and then your paint method renders that state. maybe.

12:30 cemerick: rhickey: any idea to what degree (if any) cinc will impact the usability of clojure data structures/APIs from the Java side? e.g. will PHM, etc., still have stable names?

12:30 stuartsierra: mebaran151: Re "uneval in mozilla actually creates non-spec json": c.c.json.read is a *JSON* parser, not a *Javascript* parser. It won't parse Javascript objects. That's a design choice; parsing real Javascript is quite a bit harder. You might as well use a real Javascript interpreter like Rhino.

12:31 mebaran151: heh, I actually am using rhino, but sometimes I want to get the values it generates back into clojure!

12:32 replaca_: hiredman: cool!

12:32 that was easy

12:32 Chouser: cemerick: interesting question. The intefaces and abscract classes would have stable names of course.

12:32 mebaran151: I kind of wish Mozilla had included to_json function in their standard distribution

12:32 matting: but how can i make my reimplementation of paint() dependent on the state?

12:32 stuartsierra: mebaran151: ah, should be fairly straightforward to transform Rhino's objects into Clojure types, then.

12:32 I do that with JRuby.

12:32 matting: i think that's what i don't understand yet

12:33 Chouser: cemerick: but if the concrete classes are defined using newnew (which I would assume) than their actual classnames would be generated I would think.

12:33 cemerick: Chouser: I'm thinking of the impact on RMI, which uses big-S Serialization, which depends on stable names

12:33 mebaran151: the included scripting JDK isn't very easy to work with

12:33 stuartsierra: ah

12:33 hiredman: replaca_: how difficult would it be to add clojure.core to that?

12:33 clojurebot: clojure is the brand

12:33 mebaran151: I did end up swapping it out for Rhino proper

12:33 hiredman: ~botsnack

12:33 clojurebot: thanks; that was delicious. (nom nom nom)

12:34 mebaran151: but I wouldn't have had to if Mozilla hadn't thought in their infinite wisdom to produce adhoc JSON instead of real JSON

12:34 stuartsierra: yeah

12:34 Chouser: cemerick: hm... that brings up print-dup as well. I guess we'll either need stable constructor names (still seems unlikely to me) or print-dup will have to use the factory functions (hash-map, sorted-set-by, etc.)

12:35 cemerick: the latter seems most reasonable

12:35 replaca_: Q: does anyone know where there's a regexp pattern or something for finding links in raw text? I'm trying to take docstrings and convert the embbeded things like http://json.org to <a> tags when I render them in HTML. This seems like a *very* solved problem, but I can't come up with a google search for it :-)

12:35 cemerick: There's always writeObject and readObject overrides to get proper Java Serialization (presumably using print-dup)

12:36 matting: you see, if i would reimplement paint() in java paint() would also depend on the internal state of the object. i don't know how you can get the same thing done with clojure.

12:36 replaca_: hiredman: shouldn't be hard at all. Would it be OK if it were in a separate file?

12:36 cemerick: But that puts serialized clojure objects out of the reach of the various tools that expect "normal" serializations.

12:36 hiredman: replaca_: that would be fine

12:36 stuartsierra: matting: your proxy function needs to close over a variable representing the state. If it's mutable, then it should be one of Clojure's mutable types, probably a Ref.

12:36 replaca_: cool, i'll put it on the todo list

12:37 rottcodd: with 2 packages p1 and p2, is it possible to have p2 export p1/foo as p2/foo?

12:37 hiredman: replaca_: clojurebot uses #"[A-Za-z]+://[^ ^/]+\.[^ ^/]+[^ ]+" to snag urls out of irc

12:37 djpowell: or, you could just make the variable a global ref I guess

12:38 replaca_: hiredman: works pretty well?

12:39 hiredman: seems to

12:39 replaca_: hiredman: I worry about links at the end of a sentence

12:39 hiredman: what do you mean?

12:39 matting: stuartsierra: can you point me to some clojure source where i can see how this is done?

12:40 replaca_: "For more information, see http://json.org/overview.html."

12:40 want to get the middle period, but not trailing

12:40 hiredman: ,(re-find #"[A-Za-z]+://[^ ^/]+\.[^ ^/]+[^ ]+" "For more information, see http://json.org/overview.html.")

12:40 clojurebot: "http://json.org/overview.html."

12:40 hiredman: hmmm

12:41 replaca_: that tends to be pretty common in docs

12:41 djpowell: matting: in http://clojure.googlegroups.com/web/ants.clj the state is just held in global vars that hold refs (eg world), they are manipulated by lots of threads, and the paint method calls the render function, which shows how to call methods on the Graphics object in order to draw stuff

12:41 opqdonut: ,(re-find #"[A-Za-z]+://[^ ^/]+\.[^ ^/]+[^ ]+" "For more information, see http://json.org/overview.html.")

12:41 clojurebot: "http://json.org/overview.html."

12:41 opqdonut: gah, sorry

12:41 ,(re-find #"[A-Za-z]+://[^ ^/]+\.[^ ^/]+[^. ]+" "For more information, see http://json.org/overview.html.")

12:41 clojurebot: "http://json.org/overview"

12:42 Chouser: irc-log-to-html.clj uses #"(?:https?://|www\.)(?:<[^>]*>|[^<>\s])*(?=(?:&gt;|&lt;|[.()\[\]])*(?:\s|$))"

12:42 clojurebot: see logs

12:42 stuartsierra: matting: not a great example, but here's one: http://tinyurl.com/lwqbhq

12:42 matting: thanks

12:42 hiredman: ,(re-find #"(?:https?://|www\.)(?:<[^>]*>|[^<>\s])*(?=(?:&gt;|&lt;|[.()\[\]])*(?:\s|$))" "For more information, see http://json.org/overview.html.")

12:42 clojurebot: "http://json.org/overview.html."

12:43 hiredman: :/

12:43 replaca_: Chouser: now there's a regex!

12:43 hiredman: ,(re-find #"[A-Za-z]+://[^ ^/]+\.[^ ^/]+[^ ]+" (.replaceAll "For more information, see http://json.org/overview.html." "\.$" ""))

12:43 clojurebot: Unsupported escape character: \.

12:43 djpowell: stuartsierra: re your jmx server - do you think it is worth using OpenMBeans instead of straight DynamicBeans?

12:43 hiredman: ,(re-find #"[A-Za-z]+://[^ ^/]+\.[^ ^/]+[^ ]+" (.replaceAll "For more information, see http://json.org/overview.html." "\\.$" ""))

12:43 clojurebot: "http://json.org/overview.html"

12:44 stuartsierra: djpowell: not mine

12:44 djpowell: oh - oops

12:44 cemerick: replaca_: java regexes also support forward non-capturing assertions, which are generally cleaner than the alternatives, IMO

12:44 stuartsierra: djpowell: Stuart Halloway, I think

12:44 djpowell: ah

12:44 replaca_: cemerick: yeah, that might be part of the sol'n

12:44 Chouser: oh, you know what -- my regex is meant to operate on html. that's why it's so crazy

12:45 replaca_: hiredman: $ loses because this doesn't necessarily happen at the end of the source text

12:45 Chouser: that is, it's skipping over tags and entities embedded in the url.

12:45 replaca_: Chouser: yeah, makes sense

12:46 when I was doing the autodoc on the google code wiki, it did this for me (its one nice feature), but in the new autodoc, I've got to do it myself

12:46 hiredman: ,(re-find #"[A-Za-z]+://[^ ^/]+\.[^ ^/]+[^ ]+" (.replaceAll "For more information, see http://json.org/overview.html. foo bar" "(\\.$|\\.\\s)" " "))

12:46 clojurebot: "http://json.org/overview.html"

12:47 replaca_: hiredman: which finds it at some cost to my source text

12:47 :)

12:48 the idea is to be able to transform "For more information, see http://json.org/overview.html. foo bar"

12:48 Chouser: ,(map second (re-seq #"(\w+://.*?)[.>]*(?: |$)" "For more information, see http://json.org/overview.html. foo bar"))

12:48 clojurebot: ("http://json.org/overview.html")

12:49 replaca_: into "For more information, see <a href="http://json.org/overview.html">http://json.org/overview.html</a>. foo bar"

12:50 Chouser: nice!

12:50 thanks guys, I think I have a good starting point now.

12:53 Chouser: (str2/replace "For more information, see http://json.org/overview.html. foo bar" #"(\w+://.*?)([.>]*(?: |$))" (fn [[_ url etc]] (str "<a href='" url "'>" url "</a>" etc)))

12:53 ,(require '[clojure.contrib.str-utils2 :as str2])

12:53 clojurebot: java.io.FileNotFoundException: Could not locate clojure/contrib/str_utils2__init.class or clojure/contrib/str_utils2.clj on classpath:

12:55 replaca_: Chouser: beautiful!

12:55 why think when you have #clojure?! :-)

12:58 beutdeuce: how does cons work?

13:01 hiredman: (fn [a b] (fn [c] (c a b)))

13:02 stuartsierra: beutdeuce: (cons x s) adds the object x to the *front* of the sequence s

13:02 beutdeuce: ah, like the Haskell : operator?

13:03 stuartsierra: more or less, yes

13:03 ,(cons 1 (cons 2 (cons 3 nil)))

13:03 clojurebot: (1 2 3)

13:03 beutdeuce: thnx

13:04 hiredman: ,(let [_cons (fn [a b] (fn [c] (c a b))) car (fn [a b] a) cdr (fn [a b] b)] (car (_cons 1 nil)))

13:04 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--3535$car

13:05 hiredman: bar

13:05 ,(let [_cons (fn [a b] (fn [c] (c a b))) car (fn [c] (c (fn [a b] a)) cdr (fn [c] (c (fn [a b] b))] (car (_cons 1 nil)))

13:05 clojurebot: Unmatched delimiter: ]

13:05 hiredman: bah

13:05 forget it

13:06 beutdeuce: :P

13:06 stuartsierra: hiredman: what are you trying?

13:06 hiredman: ,(let [_cons (fn [a b] (fn [c] (c a b))) car (fn [c] (c (fn [a b] a))) cdr (fn [c] (c (fn [a b] b)))] (car (_cons 1 nil)))

13:06 clojurebot: 1

13:06 hiredman: ,(let [_cons (fn [a b] (fn [c] (c a b))) car (fn [c] (c (fn [a b] a))) cdr (fn [c] (c (fn [a b] b)))] (cdr (_cons 1 nil)))

13:06 clojurebot: nil

13:06 Raynes: O_o

13:07 hiredman: cons cells as lambdas

13:07 or lambdas as cons cells

13:08 stuartsierra: ah

13:13 hiredman: ,(let [_cons (λ [a b] (λ [c] (c a b))) car (λ [c] (c (λ [a b] a))) cdr (λ [c] (c (λ [a b] b)))] (car (_cons 1 nil)))

13:13 clojurebot: 1

13:15 beutdeuce: ,(filter (fn [x] mod x 2 == 0) (range 1 100 1))

13:15 clojurebot: (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99)

13:16 beutdeuce: hm

13:16 stuartsierra: You're not writing in lisp!

13:16 replaca_: ,(filter (fn [x] mod x 2 == 0) (range 1 100 1))

13:16 clojurebot: (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99)

13:17 stuartsierra: ,(filter (fn [x] (= 0 (mod x 2)) (range 1 100 1))

13:17 replaca_: ,(filter (fn [x] (= (mod x 2) 0) (range 1 100 1))

13:17 clojurebot: EOF while reading

13:17 EOF while reading

13:17 stuartsierra: ,(filter (fn [x] (= (mod x 2) 0) (range 1 100 1)))

13:17 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$filter

13:17 replaca_: ,(filter (fn [x] (= (mod x 2) 0)) (range 1 100 1))

13:17 clojurebot: (2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98)

13:17 hiredman:

13:17 stuartsierra: that's it

13:17 beutdeuce: right, i'm forgetting about the prefix evaluation

13:17 mebaran151: ,(doc import)

13:17 clojurebot: "([& import-symbols-or-lists]); import-list => (package-symbol class-name-symbols*) For each name in class-name-symbols, adds a mapping from name to the class named by package.name to the current namespace. Use :import in the ns macro in preference to calling this directly."

13:18 mebaran151: cool so that's how the clojurebot works

13:18 I'd never actually thought about it before

13:18 durka42: ,(filter even? (range 1 100))

13:18 clojurebot: (2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98)

13:18 hiredman: can't you just tell range to step by 2?

13:18 (doc range)

13:19 clojurebot: "([end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0 and step to 1."

13:19 durka42: that would work too

13:19 hiredman: I guess not

13:19 durka42: ,(range 1 10 2)

13:19 clojurebot: (1 3 5 7 9)

13:19 hiredman: ,(take 10 (iterate (partial + 2)))

13:19 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$iterate

13:19 hiredman: ,(take 10 (iterate (partial + 2) 0))

13:19 clojurebot: (0 2 4 6 8 10 12 14 16 18)

13:19 durka42: TIMTOWTDI

13:20 beutdeuce: Can clojure do lazy evaluation of infinite lists in list comprehensions?

13:21 mebaran151: it should be able to

13:21 hiredman: infinte sequences

13:21 beutdeuce: right, they are referred to as sequences

13:21 hiredman: sequences are lazy and can be infinite

13:21 mebaran151: ,(take 10 (repeatedly 5))

13:21 clojurebot: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

13:21 hiredman: beutdeuce: lists and sequences are not the same thing

13:22 sequences are a list like interface over most collection types

13:22 mebaran151: ,(take 10 (repeat 5))

13:22 clojurebot: (5 5 5 5 5 5 5 5 5 5)

13:22 hiredman: ,(class (repeate 5))

13:22 clojurebot: java.lang.Exception: Unable to resolve symbol: repeate in this context

13:22 hiredman: ,(class (repeat 5))

13:22 clojurebot: clojure.lang.LazySeq

13:23 hiredman: ,(count (repeat 5))

13:24 clojurebot: Execution Timed Out

13:27 mebaran151: is there anyway to sandbox Clojure btw?

13:28 such as turning off its java interop and such

13:28 stuartsierra: not in Clojure itself, but Java sandbox tools will work

13:28 mebaran151: ah you mean the security domain and such

13:28 hiredman: ,(.getContents (java.net.URL. (java.io.File. "/etc/passwd")))

13:28 clojurebot: java.lang.ClassCastException: java.io.File cannot be cast to java.lang.String

13:29 hiredman: ,(.canRead (java.io.File. "/etc/passwd"))

13:29 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission /etc/passwd read)

13:31 beutdeuce: http://pastie.org/557925 => runs forever, though i specified that an empty list returns 0

13:31 hiredman: beutdeuce: no

13:31 [] means no args

13:31 beutdeuce: o

13:31 hiredman: clojure does not have pattern matching, it has destructered binding which does some similar things

13:32 beutdeuce: how would that work?

13:32 mebaran151: beutdeuce, you need to apply your mylen

13:32 right now you just continually pass in a length

13:33 beutdeuce: (doc apply)

13:33 clojurebot: "([f args* argseq]); Applies fn f to the argument list formed by prepending args to argseq."

13:33 mebaran151: pass in a list I mean

13:33 hiredman: uh

13:33 mebaran151: I doubt that is what he wants

13:34 (defn length ([lst] (length lst 0)) ([lst count] (if (seq lst) (recur (rest lst) (inc count)) count)))

13:37 ,(reduce (fn [a b] (inc a)) '(1 2 3))

13:37 clojurebot: 3

13:37 hiredman: ,(reduce (fn [a b] (inc a)) '())

13:37 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--3744$fn

13:37 hiredman: :/

13:38 oh

13:38 duh

13:38 ,(reduce (fn [a b] (inc a)) 0 '())

13:38 clojurebot: 0

13:38 hiredman: ,(reduce (fn [a b] (inc a)) 0 '(1 2 3))

13:38 clojurebot: 3

13:39 beutdeuce: so reduce is haskell's fold ?

13:39 hiredman: but strict

13:39 beutdeuce: ah

13:39 hiredman: no lazy reduce in clojure

13:39 clojurebot: lazy is hard

13:41 hiredman: everything in clojure is strict, except lazy sequences

13:42 some operations are sequences are lazy and some are not, generally if it returns another sequence (map, filter, etc) it is lazy

13:43 beutdeuce: k

14:38 rzoom: is there a standard "default" case for cond?

14:38 Chouser: yes, any true expression will do. :else is used by convention

14:38 hiredman: ,(cond (= 1 0) :foo :else :bar)

14:38 clojurebot: :bar

14:39 rzoom: nice!

14:39 thanks

14:39 * Chouser high-fives hiredman

14:39 hiredman: YEAH!

14:39 TO THE MAX!

14:41 danlarkin: aw you guys... having all this fun

14:41 rzoom: is dmiles_afk ever here?

14:42 hiredman: ~seen dmiles

14:42 clojurebot: dmiles was last seen quiting IRC, 759 minutes ago

14:44 dmiles_afk: i am here. clojure is in my tyodo pipeline for what i am coding

14:45 which is a secondlife client for clojure

14:45 but right now still using DotLisp.. but will soon enough use ClojureCLR

14:46 DotLisp was what rhickey wrote right before Clojure.. actually has a few nice extras that the JVM didnt offer

14:53 mebaran151: what does it have that the JVM can't offer?

16:42 wlr: Mention of real world Clojure ~3/4 thru article: http://www.expresscomputeronline.com/20090727/technology01.shtml

17:27 angerman: whee I just wrote my first macro

17:27 allows me to write (query "Item" where (= :name nil)

17:29 Raynes: Congratulations.

17:33 Anniepoo: Just a note to rich to say thanks for such a cool language

17:33 8cD

17:35 angerman: though there is one thing I don't like so much. Descruturing in macros does not work :/

17:36 i couldn't do this: (defmacro [kind _ (op a b)] ...)

17:39 Anniepoo: I'm not getting the 'why is this cool?' of destructuring

17:40 angerman: Anniepoo: the cool part about destructuring is that it's short

17:41 Anniepoo: hmm....

17:41 angerman: for an extreme example take Prolog. If you couldn't do destructuring in the head it would be very painful

17:41 duck1123: it saves you a few let statements, and having to think up new names

17:41 Anniepoo: don't know Prolog

17:42 ok, duck, but you're saying it's not really theoretically powerful, it's a 'typing' level convenience

17:42 hiredman: angerman: uh, destructured binding in clojure does not use parens

17:43 angerman: hiredman: that's what I guessing towards ...

17:43 well ... bedtime

17:43 hiredman: ugh

17:43 ~destructuring

17:43 clojurebot: destructuring is http://clojure.org/special_forms#let

17:44 Anniepoo: I can see that clojure will be an insanely great language to write graphic programs in

17:45 cause they usually bog down in the details of breaking down and packaging up small data structures

17:46 I've had an idea for graphics and never had a good language to express it in.

17:46 most bugs in graphics code turn out to be using the wrong coordinate system

17:46 so a way to 'enforce type' on coord systems would be insanely cool

17:47 duck1123: Clojure gives you loads of tools to make your code as close to the actual idea as possible

17:47 destructuring is just one of those tools

17:49 Anniepoo: yah, I want to have some (move-widget-to [pt] and have it cope with a point in any format and coordinate system without a bunch of code in move-widget

17:50 ideally, so you just say (cast-coord widget-frame 'Point pt) and you get a java.awt.Point in the widget's frame of ref

17:50 duck1123: sounds like a job for multimethods

17:51 Anniepoo: definitely

17:51 duck1123: there was a blog post where the guy was making a raytracer in clojure, you might want to check that out,

17:52 Anniepoo: ah, interestiing

17:52 duck1123: http://www.fatvat.co.uk/2009/01/ray-tracing-in-clojure.html

17:53 Anniepoo: nice, thanks

17:53 that acutally kind of answers my question about destructuring

17:54 hiredman: http://tu.be/graphics/ <-- this a more recent attempt by someone

17:56 Anniepoo: nice

17:56 hiredman: he went by fsm and was in here a few days ago looking for performance tips for array operations if I recall

17:58 Anniepoo: In a curly brace language it's good style not to 'pass the world' around. Does destructuring make that advice more or less apt?

17:59 right now I'm making a swing GUI editor for bunch of widgets

17:59 hiredman: destructuring has nothing to do with that

17:59 it jsut makes binding forms shorter

18:00 Anniepoo: example, right now I'm writing the call in paintComponent that will acutally draw the widgets

18:00 (draw-laid-out-widgets (.state this) g)

18:00 hiredman: (let [a (first lst) b (second lst) c (rest (rest lst)] ) becomes (let [[a b & c] lst] )

18:01 Anniepoo: Ah!!!!!

18:01 8cD

18:01 Destructuring, it's not just for defn any more

18:01 sorry, I didn't get it before, somebody mentioned let

18:02 now I see

18:02 like the first raytracer posted, the guy has a bunch of (:x pt) (:y pt) stuff

18:04 duck1123: that one of the great uses, you can pull those values out into their own variables to make the rest of the code shorter

18:04 Anniepoo: he could have (let [[x y z] pt] ... x y ...

18:04 got it! thanks!

18:04 Y'all are wonderful

18:05 duck1123: actually (let [{x :x y :y z :z} pt] ... I believe

18:05 Anniepoo: oops

18:06 duck1123: check out the let section of the special forms page

18:06 Anniepoo: my own code has a bunch of positional args

18:06 duck1123: it shows all the things you can do

18:07 Anniepoo: yah, reading now

18:07 replaca_: you can try (let [{:keys [x y z]} pt] ... ) and get the same effect

18:07 duck1123: (let [{:keys [x y z]} pt] works too

18:07 Anniepoo: that's nice, and shorter

18:08 I'm shocked at the power of all this

18:08 I'm making a swing GUI - not a promising candidate for shortening, one would think

18:08 duck1123: it's never worth it to be shocked by the power of clojure, you'll wear yourself out.

18:10 I've never played with swing, but isn't there some contrib libraries for doing gui stuff? Have you checked those out?

18:10 Anniepoo: I started writing this in java, thinking I didn't know Clojure well enough to use it on a real project

18:10 codyK: any examples of dealing with circular references?

18:11 hiredman: ,(doc declare)

18:11 clojurebot: "([& names]); defs the supplied var names with no bindings, useful for making forward declarations."

18:11 codyK: deref on a object that contains circular references seems to unroll the whole thing & blow the stack

18:11 Anniepoo: sure, if you print it

18:11 codyK: even in code

18:12 duck1123: "don't do that then" :)

18:12 codyK: hahaha

18:12 yeah, so, in languages i'm familiar with, if youre say writing a serializer, its not too big a deal to deal with circular references

18:12 but clojures printer doesnt seem to deal with them

18:13 and searching for examples or discussion of it isn't very helpful

18:13 duck1123: how do the other languages deal with them? just elide the recursion?

18:13 Anniepoo: you can't deal with it in general

18:14 it requires solving the halting problem

18:14 codyK: eh?

18:14 just keep a list of addresses you've seen

18:14 check it before you deref a pointer

18:14 only deref one level down at a time

18:14 hiredman: uh

18:15 sure sure, pointers


18:15 of course the jvm being designed to stop you from dealing with raw pointers sort of throws a monkey wrench in that

18:16 Anniepoo: or mark and sweep

18:16 codyK: the language clearly has reference types

18:16 hiredman: sure

18:16 Anniepoo: cody, you don't even need to do that

18:16 add a bit to each object

18:16 hiredman: but it doesn't let you touch pointers

18:17 Anniepoo: reset them all, if you have some global list of stuff

18:17 then traverse and print but say 'oh, I visited'

18:17 codyK: the issue i'

18:17 m having is that deref seems to be all or nothing

18:18 Anniepoo: it's reasonable to blow up on a circ ref for something general like print

18:18 codyK: i dont think its reasonable

18:18 common lisp handles it for instance

18:18 Anniepoo: thre's a way to set the max depth of printing

18:18 ~println

18:18 clojurebot: ,(println "clojure bot is the best!")

18:18 hiredman: ,(let [a (ref 10)] (deref (ref a)))

18:18 clojurebot: #<Ref@94f797: 10>

18:18 hiredman: ^- not all or nothing

18:19 durka42: ,*print-depth*

18:19 clojurebot: java.lang.Exception: Unable to resolve symbol: *print-depth* in this context

18:19 codyK: ok, maybe my code is bad

18:19 hiredman: it only derefs one layer

18:19 durka42: it was something like that...

18:19 ,*print-level*

18:19 clojurebot: 30

18:19 hiredman: codyK: anyway, IDerefable things are not printable

18:20 and not readable

18:21 codyK: the things they reference are / could be

18:21 hiredman: sure

18:21 so deref before you print

18:26 codyK: ;; (def *a* (atom [0]))

18:26 ;; (def *b* (atom [1]))

18:26 ;; (compare-and-set! *a* @*a* (conj @*a* *b*))

18:26 ;; (compare-and-set! *b* @*b* (conj @*b* *a*))

18:27 Chouser: you can do the same thing with java collections and their .toString() method

18:28 but that just crashes instead of respecting *print-level*

18:29 hiredman: codyK: so?

18:29 codyK: I would expect to be able to get some unique identifier for *b* without unrolling it

18:30 hiredman: unique how?

18:30 codyK: well, i'm currently trying to add it to a set

18:30 so that I can compare it for set membership

18:30 hiredman: across all possible jvms which might run clojure and read it in?

18:30 codyK: no

18:31 hiredman: a unique identifier for a mutable thing like an atom or a ref is not worth much

18:31 codyK: but the act of comparing it for set membership blows the stack

18:31 (afaict anyway)

18:31 hiredman: *b* is an atom

18:31 atoms are designed to mutate

18:32 codyK: again, if i have a pointer, the address of that pointer doesnt change

18:32 blbrown_win: Chouser, are you the owner of clojure and me

18:32 hiredman: you don't have a pointer

18:32 codyK: even though the contents of that address might change

18:32 hiredman: this is not C or C++

18:32 you do not have a pointer

18:33 codyK: look, i'm not having a language argument

18:33 i promise you

18:33 s/pointer/reference/

18:33 clearly there is something consistent about *b*, because i can refer to it with the same name

18:33 Chouser: blbrown_win: no

18:33 codyK: so whats the correct operator to get that name?

18:35 Chouser: codyK: by default printing an IDeref also derefs and prints that value. But = doesn't do that

18:35 hiredman: codyK: how are you adding *b* to a set?

18:35 blbrown_win: Chouser, oh, I just followed you on twitter,

18:35 Chouser: = on reference types should be just 'identical?'

18:35 codyK: My code doesnt even get to the point of adding it to a set

18:35 hiredman: (conj #{} *b*) will print the results to the repl

18:35 blbrown_win: ahh, he is cgrand

18:35 hiredman: codyK: so add some prns and figure out where it actually stops

18:36 codyK: if my set is *seen*, bound to an empty set, doing (*seen* some-circ-ref)

18:36 alone

18:36 seems to blow the stack

18:36 i'm willing to bet its bad code on my part

18:37 just curious about examples

18:37 hiredman: all works fine for me

18:38 user=> (#{} *b*)

18:38 nil

18:38 user=>

18:38 codyK: yeah i just tried it

18:41 (and ((conj #{} *b*) *b*) 'thing)

18:41 seems to work ok

18:41 so like I said, bad code

18:41 akhudek: Hi, I'm fairly new to clojure and failing at figuring out the right way to do this. I need to store a map of positions to counts that is updated roughly at random. There are typically around a million positions. In other languages I'd implement this as a vector of ints where the position in the vector is the 'key'. But looking at clojure vectors, perhaps this is not the right way to go about it? A big hash map doesn't seem like a good i

18:44 hiredman: ,(do (vec (range 1000000)) nil)

18:44 clojurebot: nil

18:44 hiredman: what is the problem with clojure vectors?

18:44 akhudek: I can't figure out a way to update a single position.

18:44 hiredman: ,(assoc [1 2 3] 0 5)

18:44 clojurebot: [5 2 3]

18:45 Anniepoo: oooh

18:45 akhudek: ah, thanks, I didn't see how assoc worked on vector given the docs

18:46 hiredman: ,(doc assoc)

18:46 clojurebot: "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."

18:46 Anniepoo: ok, what's going the other way, how do I get the 593rd element?

18:47 Chouser: nth

18:47 Anniepoo: ,nth

18:47 clojurebot: #<core$nth__4198 clojure.core$nth__4198@13e38a7>

18:47 hiredman: ,((vec (range 1000000)) 593)

18:47 clojurebot: 593

18:47 akhudek: I should read more thoroughly, I saw map in there and didn't read the last part. :/

18:47 hiredman: ,(nth (vec (range 1000000)) 593)

18:47 clojurebot: 593

18:47 hiredman: vectors are functions of their indices

18:48 akhudek: right, so I guess they are a type of map

18:48 hiredman: not really

18:49 but they implement a few of the same interfaces

18:49 Chouser: maps and vectors are both associative -- can get and set elements based on a key

18:49 hiredman: ,(ancestors (calls []))

18:49 clojurebot: java.lang.Exception: Unable to resolve symbol: calls in this context

18:49 hiredman: ,(ancestors (class []))

18:49 clojurebot: #{clojure.lang.IPersistentStack clojure.lang.Seqable java.util.List clojure.lang.Reversible clojure.lang.Sequential clojure.lang.AFn clojure.lang.Obj clojure.lang.Counted java.util.concurrent.Callable clojure.lang.APersistentVector java.io.Serializable java.util.Collection clojure.lang.IObj clojure.lang.IPersistentCollection clojure.lang.IMeta clojure.lang.IPersistentVector clojure.lang.IFn java.lang.Iterable java.lang.Ob

18:49 Anniepoo: ,([1 3 15 4] 2)

18:49 clojurebot: 15

18:50 Chouser: ,(instance? clojure.lang.Associative [])

18:50 clojurebot: true

18:50 Chouser: ,(instance? clojure.lang.Associative {})

18:50 clojurebot: true

18:51 akhudek: There are so many clever things in clojure. It really is a joy to use.

19:09 blbrown_win: Anyone know where the widefinder input is. The input log file .I am running widefinder in clojure.

19:17 hiredman: http://svn.effbot.org/public/stuff/sandbox/wide-finder/getdata.py is apparently a python script to download the logs

19:22 blbrown_win: so you can't just dow the download

19:22 hiredman, did you google that, I couldn't find it apparently

19:22 hiredman: it looks like you can

19:23 just copy the url out of the python script

19:26 blbrown_win: isn't kind of a crappy benchmark

19:28 hiredman: have you read the rationale behind it?

19:29 blbrown_win: there seem to be volumes out there? it also seems to be centered around ruby

19:29 but not really, I guess just a random test for processing data. How do other languages compare

19:29 hiredman: http://blogs.zdnet.com/Murphy/?p=1030

19:31 http://www.hanselman.com/blog/TheWeeklySourceCode9WideFinderEdition.aspx some C# widefinders

19:33 man

19:33 I wish I had a T2

19:37 krumholt__: is there an api for quote?

19:37 hiredman: uh

19:38 like ' quote?

19:38 krumholt__: yes

19:38 hiredman: what's there to say about it?

19:38 it supresses evaluation

19:38 krumholt__: for example why does (quote 123) evals to 123 a number

19:39 hiredman: because the reader readers 123 as a number

19:40 and emits the list (quote 123) which is a two element list, the first element is the symbol quote and the second is the number 123

19:40 then when (quote 123) is evaluated, 123, a number, is the result

19:41 JAS415: in a macro, how should I handle java classes... for example i have a code that looks like `(. ~URLEncoder (encode ~string "UTF-8")) should I be importing the URLEncoder in the macro code and escaping it with ~ or should I be importing the URLEncoder in the code that the macro goes with?

19:41 krumholt__: hiredman, seems strange that (= 123 '123) => true

19:42 hiredman: '123 is not a symbol

19:42 (class '123)

19:42 ,(class '123)

19:42 clojurebot: java.lang.Integer

19:42 JAS415: is because numbers evaluate to themselves

19:42 hiredman: ' does not make symbols

19:42 ' quotes the following form, which is often a symbol

19:42 JAS415: ,(= true 'true)

19:42 clojurebot: true

19:42 JAS415: (= false 'false)

19:43 ,(= false 'false)

19:43 clojurebot: true

19:43 krumholt__: seems wrong to me :)

19:43 JAS415: think of quote as a way of delaying evaluation

19:44 hiredman: krumholt__: so when the reader comes across the string "(quote 123)" it goes "oh look, a paren, that means I am reading a list!"

19:44 so then it gets into list reading mode

19:45 it reads in the string "quote" says "well this is a symbol" and the string "123" and says oh, this is a number

19:45 so out of the reader you get a list, (quote 123) where quote is a Symbol and 123 is an Integer

19:46 then the list is evaluated

19:46 krumholt__: ok i get it thanks

19:46 hiredman: the evaluater looks at the list and says "this is a list, so it could be function application, but quote is a special form"

19:46 really?

19:47 I was having fun anthropomorphizing the repl

19:47 man

19:47 clojurebot: ☝(^_^)☝

19:47 krumholt__: :)

19:47 hiredman: I could get some puppets

19:47 cemerick: hiredman: been a long week? :-)

19:47 hiredman: and do a video

19:47 cemerick: come to think of it, it has

19:48 cemerick: yeah. Been a long year so far, too.

19:48 hiredman: I don't even think _why has done puppets

19:49 cemerick: I don't get the appeal of his stuff at all.

19:49 JAS415: oh man

19:49 cemerick: though, I don't generally enjoy instructional material anyway

19:49 JAS415: puppets to explain clojure would be awesome

19:50 hiredman: someone did some kind of alagator toy lisp thing

19:51 http://visual-languages.blogspot.com/2009/07/alligator-eggs-revisited.html

19:53 krumholt__: i have another question. how can i estimate the cost of a recur? in the documentation it says it will only use constant space. whats the difference to tail call optimization?

19:53 hiredman: tco is more general

19:54 recur only recurs to the closest loop or fn

19:54 Chouser: there is no tail call optimization in clojure

19:54 hiredman: tco would allow you to call any function

19:55 from tail call position, and not build up stack frames

19:55 krumholt__: ok thanks

20:21 blbrown_win: http://paste.lisp.org/display/84158 anyone see the error here. I got the code from a blog (cgrand-rec, hehe). I can't find 'val' created either

20:24 lisppaste8: Anniepoo pasted "compile error" at http://paste.lisp.org/display/84159

20:25 Anniepoo: me, meanwhile, I've just reached the end of my wits trying to figure out why the compiler is complaining

20:26 JAS415: that's weird

20:26 Anniepoo: what's weird?

20:27 JAS415: if you use fn instead of # does it work?

20:27 Anniepoo: for the # in draw-laid-out-widgets?

20:28 durka42: filter's fn only gets one argument

20:28 JAS415: ah yeah

20:28 that is it

20:28 Anniepoo: ah!

20:28 thanks

20:28 durka42: you can destructure it however

20:28 Anniepoo: yes, meant [[_ lvl _]]

20:28 durka42: precisely

20:28 Anniepoo: thanks

20:31 Chouser: fwiw I make that mistake frequently

20:31 krumholt__: what does _ do?

20:32 Chouser: Anniepoo: that's yours

20:35 Anniepoo: sorry?

20:35 what's mine?

20:36 Chouser: krumholt__'s question is yours to answer. time to step up! :-)

20:36 Anniepoo: underscore is idiomatic for an argument that you will ignore

20:36 yes, you're right

20:37 krumholt, if you need a function that takes 3 args, because that's what the caller expects, but

20:37 krumholt__: ah ok so i could write (foo nil a nil) or (foo _ a _) ?

20:38 Anniepoo: suppose you have a bunch of places that hang onto a function and call it

20:39 like, I'm making a thing where each widget is constrained to others, so each widget has a reference to it's constraint function

20:39 krumholt__: ok i get it i can only use _ in function definiton

20:39 Anniepoo: it's not actually part of the language, it's just an idiom

20:40 (defn foo [x x x] ... something....) is valid Clojure, just not very useful

20:40 (foo 1 2 3)

20:40 means x is 3 inside

20:41 _ is, by convention, what you use to mean 'I'm not using this'

20:41 but you're right, it normally only appears in a defn or destructuring in a let

20:41 krumholt__: oh ok so _ is just a normal symbol. it has no special syntax. you just use it so a human reader knows you will ignore the parameters

20:41 Anniepoo: yes

20:41 krumholt__: ok thanks

20:42 Anniepoo: ok, now, looking upwards in the Clojure food chain

20:42 lisppaste8: Anniepoo annotated #84159 "vec" at http://paste.lisp.org/display/84159#1

20:43 Anniepoo: 259 is the last line of draw-laid-out-widgets

20:43 I assume I'm somehow cdr'ing off the end of the list

20:43 but don't understand how

20:45 ataggart: it might make things clearer to use a struct instead of relying on position

20:46 Chouser: Anniepoo: is there more to that exception?

20:47 That doesn't look like the root cause trace

20:47 Anniepoo: I'll paste the whole thing

20:47 Chouser: I wonder if somewhere you have 'vec' when you want 'vector'

20:48 ataggart: btw where are these "widgets" created?

20:48 I infer a widget is some vector or list

20:49 but I never see it get created in that code

20:49 Anniepoo: no, this is a fragment

20:49 ataggart: so we may be missing some crucial info

20:49 Anniepoo: yes, but I can't paste the entire project in

20:50 ataggart: if I had to guess, the code we aren't seeing is being indirectly realized intoa vec during the destructuring, but it can't so it blows up

20:50 Anniepoo: Chouser is right, there's other stuff highter in the stack trace

20:51 lisppaste8: Anniepoo annotated #84159 "more of the code" at http://paste.lisp.org/display/84159#2

20:52 Anniepoo: 240 is this let in draw-a-laid-out-widget

20:52 (let [[x y w h] (as-screen state r)]

20:52 Chouser: vec only takes 1 arg

20:52 ,(vec (list 1 2 3 4))

20:52 clojurebot: [1 2 3 4]

20:52 ataggart: (vector, not vec

20:52 Chouser: if you want a vector of 4 things, use (vector 1 2 3 4) or just [1 2 3 4]

20:52 ataggart: ya, what chouuser said

20:53 Anniepoo: ah, ok

20:53 the vec in as-screen

20:53 ataggart: (defstruct screen :x :y :z :w :h) imo

20:53 Anniepoo: incidentally, it's obvious there's a more idiomatic way to write that lanie

20:54 but I don't know what it is

20:55 ataggart: (map #(* scale %) [ x y z])

20:55 Anniepoo: thanks!

20:55 ataggart: except with the right names hehe

20:55 Anniepoo: doh!

20:55 Chouser: and then you do want vec to get a vector

20:55 ataggart: no need

20:55 unless you need to manipulate it

20:56 leave it as a lazy seq

20:56 if that grouping is important, it might be better to make use a struct instead of a vector

20:57 Anniepoo: yes, I understand

20:58 ataggart: though the input looks to be some kind of list, so it might be irrelevant

20:58 Anniepoo: I have a bunch of 'widgets' - rectangles essentially

20:58 they're constrained to each other - I'm effectively making a layout manager

20:58 ataggart: (defn scale [factor values] (map #(* scale %) values))

20:58 erm

20:59 (defn scale [factor values] (map #(* factor %) values))

20:59 then it'll take anything

21:00 Anniepoo: there's a root widget, it has 'children' and 'slaves', so there's an n-ary tree that has two kinds of parent-chi

21:00 child relationship

21:00 ataggart: ya I just mean you can avoid the "x y w h" stuff

21:01 Anniepoo: oh, I see

21:01 actually, there's a stylistic reason to leave it in this instance

21:01 ataggart: k

21:02 Anniepoo: in this case we've got a lot of different small structs with coordinates running around

21:02 [x y w h] is pretty clear compared to widget-location

21:03 ataggart: you can have both

21:03 e.g., have one call the other

21:03 but, yeah it's a style thing now

21:05 Anniepoo: I write lots of graphics stuff so I see this issue with representing points and rects all the time

21:06 it's the main reason I'm excited by Clojure, I can see a cure for all that

21:06 krumholt__: is clojure compiling to java or directly to bytecode?

21:06 Anniepoo: bytecode

21:07 ataggart: isn't there an easier way to do something like (reduce #(let [[k v] %2] (assoc %1 k (* 2 v))) {} {:a 1 :b 2})

21:08 esenatially applying a function to the values of a map

21:10 krumholt__: (map foo (vals{:a 1 :b 2}))

21:10 ?

21:10 ataggart: but end up with a new, altered map

21:10 not a seqence of the values

21:11 ,(reduce #(let [[k v] %2] (assoc %1 k (* 2 v))) {} {:a 1 :b 2})

21:11 clojurebot: {:b 4, :a 2}

21:11 cschreiner: (trying really hard to understand agents)

21:12 ataggart: it's easy, they're just like theads, except totally different ;)

21:12 cschreiner: right..

21:13 they are just values?

21:13 ataggart: they hold a value

21:13 then you send it an action to update that value, and that action will be run in a thread pool

21:13 cschreiner: and when you want to change the holded value, you send off a function?

21:14 ataggart: send or send-off, yeah

21:14 cschreiner: thats it?

21:14 ataggart: yup

21:14 well, sort of

21:14 cschreiner: jebuz

21:14 ataggart: the "neat" part is how they work within a transaction

21:15 cschreiner: how they operate with the STM

21:15 ataggart: in fact the one agent I've ever used, the value never changed since it was used to generate output

21:15 ~agents

21:15 clojurebot: Huh?

21:15 ataggart: http://clojure.org/agents

21:15 grep for transactin

21:15 except spelled correctly

21:16 cschreiner_: ,agents

21:16 clojurebot: java.lang.Exception: Unable to resolve symbol: agents in this context

21:16 cschreiner_: ,agent

21:16 clojurebot: #<core$agent__4304 clojure.core$agent__4304@171a8f6>

21:17 cschreiner_: to look at an agent as a generator is odd

21:17 ataggart: yep, who does that?

21:17 cschreiner_: you do

21:18 ataggart: sorry, "generator" means something specific to me

21:18 cschreiner_: ok

21:18 ataggart: since you can't have side effects in a transaction (such as outputting logging) you do it via an agent

21:18 cschreiner_: so its like a monda?

21:18 monad?

21:18 ataggart: or rather, any side effects will reoccur

21:18 it's an agent

21:18 think of it as an agent, and it'll be easier

21:19 cschreiner_: i can speak to the agent, I can also receive something

21:19 the agent is independent from me, that is, it runs in another thread?

21:20 ataggart: I suggest reading the link I posted above

21:20 cschreiner_: I have

21:20 hiredman: http://www.amazon.com/Multi-agent-systems-introduction-distributed-intelligence/dp/0201360489 found this today for $2 at goodwill

21:20 Anniepoo: ok,what if it's the side effect that has to succeed for the transaction to succeed?

21:21 ataggart: ha! where do you live that suck would appear in goodwill

21:21 *such

21:21 hiredman: Anniepoo: no

21:21 cschreiner_: ah, great find!

21:21 hiredman: seattle

21:21 ataggart: ah ok then

21:21 Anniepoo: I misspoke earlier

21:22 it's not that you can't have sideeffects, it's that if the transaction needs to be rerun, those side effects will occur again

21:22 e.g. logging may get printed multiple times

21:22 Anniepoo: I found a palm pilot at goodwill a few weeks ago that had been 'experimented' on - they'd messed with the IR

21:22 hiredman: but sends to an agent are held unto the transaction completes

21:22 Anniepoo: ok, so suppose I have a machine that punches a hole in a paper tape and advances

21:23 hiredman: Anniepoo: ah, a late model turing machine

21:23 cschreiner_: ah, i was thinking of an agent in the spy-movie setting, now, when put into a manager-for-someone, it makes more sense...

21:23 ataggart: lol

21:23 Anniepoo: and some call that initiates the hole punching

21:24 8cD that's a side effect for sure

21:24 Chouser: Anniepoo: yeah. don't do that in a transaction.

21:25 ataggart: if you can't roll it back...

21:25 Anniepoo: not without sticky tape!

21:26 (initiate-range-safety)

21:40 hiredman: (pl (λx.x 1))

21:40 ,(pl (λx.x 1))

21:40 clojurebot: 1

Logging service provided by n01se.net