#clojure log - Jul 18 2011

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

0:47 ieure: Can someone explain this seemingly insane MessageDigest behavior? https://gist.github.com/e8cead34d39c2b93fae1

0:47 I get a different hash value every time I hash the same text.

0:47 At least, that’s what it looks like.

0:48 brehaut: ieure: are you sure thats not just the address of the byte array?

0:49 ieure: brehaut, No, but I’m not sure how to get any other value out of it, and (.compareTo a b) results in "No matching method found: compareTo for class [B"

0:51 brehaut: ieure: deprecated but you can use ##(String. (.getBytes "abc"))

0:51 lazybot: ⇒ "abc"

0:52 ieure: Killed slime. :(

0:52 brehaut: ,(dotimes [n 3] (prn (String. (.digest (doto (java.security.MessageDigest/getInstance "MD5") (.update (.getBytes "abc")))))))

0:52 clojurebot: "�P�<�O�֖?}(�r"

0:52 "�P�<�O�֖?}(�r"

0:52 "�P�<�O�֖?}(�r"

0:52 brehaut: haha

0:53 yeah the digest isnt a string; probably want to base64 encode it if you want to print it ;)

0:54 ieure: And of course there isn’t a Base64 codec in the stdlib.

0:54 brehaut: indeed

0:54 Blackfoot: sha1 gist for files https://gist.github.com/377964

0:54 brehaut: theres an apache commons one though

0:54 ieure: Yeah, I just wanted to avoid another dependency.

0:55 brehaut: ieure: are you trying to compare digests, or get a string repr of them?

0:55 ieure: brehaut, Both.

0:55 technomancy: it's more common to represent md5 as a hex string rather than base64

0:55 fwiw

0:56 you might be able to do that with format?

0:56 brehaut: technomancy: oh duh of course.

1:02 ieure: Commons-codec’s DigestUtils is way less hassle.

1:02 Another dep on the pile, I guess.

1:04 brehaut: ieure: crappy imp (str/join "" (map (comp #(format "%h" %) (partial + 128)) bytes))

1:06 ieure: im pretty sure my + 128 is wrong

1:18 Havvy: Hmm, what is the easiest way to remove the added spaces between each parameter sent to (println)?

1:18 amalloy: ieure: fwiw, i recently noticed Vash, who produce pretty images (like gravatar's defaults but much nicer) out of md5s

1:18 Havvy: use str

1:18 &(println (str "A" "B"))

1:18 lazybot: ⇒ AB nil

1:18 brehaut: ieure: better version (str/join (map #(format "%02x" %) b1))

1:19 ieure: brehaut, That’s awesome, thanks.

1:19 amalloy, Interesting, link?

1:19 brehaut: ieure: no problem. credit goes to timc on the ML

1:19 amalloy: https://github.com/thevash/vash/

1:19 brehaut: ieure: http://groups.google.com/group/clojure/msg/3cba3a68b477b39a

1:19 Havvy: brehaut: But I'm trying to remove the characters that are joined between parameters. While str/join is useful, it's the opposite of what I was looking for. :P

1:19 brehaut: ieure: ive checked the output aginst python hashlib

1:19 Havvy: Oh, for somebody else;

1:19 amalloy: Yeah, thanks.

1:20 ieure: brehaut, I only care about internally consistent, but you are a champ.

1:20 brehaut: Havvy: added spaces? println adds newlines

1:20 amalloy: brehaut: you're a champ, but you're just not internally consistent

1:20 brehaut: it adds spaces too

1:20 &(println 1 2 3)

1:20 lazybot: ⇒ 1 2 3 nil

1:20 brehaut: amalloy: oh right

1:21 &(str 1 2 3)

1:21 lazybot: ⇒ "123"

1:22 brehaut: amalloy: lol re:internal consistency

1:28 Havvy: Is there a way to shutdown just one agent?

1:29 amalloy: Havvy: uhhh, it's not clear what the point of that would be

1:31 Havvy: I'm recreating wolf through Clojure, and don't want to keep the agent holding its state to exist where there is no game going.

1:31 amalloy: so let it get GCed. no big deal

1:32 just drop your references to it, and the jvm will pick up after you

1:32 Havvy: "to it" being the agent or the data in the agent?

1:33 amalloy: the agent, i meant, but i suppose either could be right

1:33 Havvy: And how do you drop a reference to an agent?

1:34 amalloy: just...no longer have a reference to it

1:34 ibdknox: lol

1:34 amalloy: stop keeping pointers to it

1:48 Pupeno: Why is there a clojars when there's already a maven?

1:49 amalloy: Pupeno: good luck pushing your half-baked library to maven central

1:50 Pupeno: amalloy: the filter what they accept? I'm honestly asking, I don't know.

1:51 amalloy: Pupeno: i'm pretty sure your product has to be pretty polished to get into maven central

1:51 but i haven't tried

1:51 Pupeno: Ok, got it.

2:00 Havvy: amalloy: Thanks;

2:12 technomancy: they also require silly things like domain-name group-ids

2:16 amalloy: technomancy: when you're typing java package names all day at work, being asked to specify just a domain name must feel like a real relief

2:45 Havvy: (I return.) How do I get a record from a vector of records if it has :id equal to "Havvy"?

2:47 kumarshantanu: Havvy: (map (= "Havvy" (:id %)) records-vector)

2:47 s/(=/#(=/

2:47 member:Havvy: (map #(= "member:Havvy" (:id %)) records-vector)

2:50 amalloy: (filter (comp #{"Havvy"] :id) records)

2:51 kumarshantanu: Havvy: amalloy: amalloy's version is correct - it should be filter instead of map

2:51 Havvy: amalloy: That works (after changing ] to a }).

2:52 Gracias;

2:52 * amalloy still hasn't figured out where that shift key is

2:52 * Havvy wonders what #{"Havvy"} does.

2:53 Havvy: Oh, a set.

3:06 amalloy: Havvy: clear how that works, then?

3:11 Havvy: Yeah.

3:12 (comp) is one of my more favorite functions. But I'm not used to using sets and keywords as executables.

3:12 s/executables/callables

3:12 lazybot: <Havvy> (comp) is one of my more favorite functions. But I'm not used to using sets and keywords as callables.

4:57 jeffrey04: erm, i am a bit lost here

4:58 i want to build an application that uses some machine learning libraries

4:58 currently looking at weka and mahout

4:58 if i am to use mahout, where do i start? hadoop? mahout?

5:07 clgv: jeffrey04: are there no project related "getting started" pages or tutorials?

5:08 jeffrey04: yes, there is, trying to read thru them, looks like a lot to pick up before i can use mahout in java

5:09 clgv: maybe they have an irc channel as well then you probably have better success chances over there I guess

5:09 jeffrey04: clgv: i hope so

5:10 clgv: jeffrey04: otherwise try setting some example up step by step

6:08 dbushenko: I have updated my web-framework a bit (former ClojureBlog). It is located here now: https://github.com/dbushenko/Clojure-WebApp

6:08 for now it is easier to reuse it and the exmaple code

6:41 bsteuber: dbushenko: looks interesting

6:41 but I wonder, why do you put the framework source in a webapp subdir instead of just a dependency?

6:51 dbushenko: bsteuber: I'm a bit new to all of this. Good idea, btw! I definitely should split it and make a clojar!

6:52 bsteuber: ^^

7:04 lnostdal-laptop: (let [[a b] '(1 2)] (+ a b)) => 3 ;; is very nice, but is the same thing possible with `binding' ..?

7:04 at the moment i'm getting; "clojure.lang.PersistentVector cannot be cast to clojure.lang.Symbol"

7:28 sritchie: lnostdal-laptop: binding doesn't do destructuring -- it rebinds a current symbol, outside the scope of the function

7:34 lnostdal-laptop: yeah, it'd be trivial to create a binding* macro i guess

8:18 Cozey: Hello. I want to create a deftype which behaves like a map but is backed by a java bean

8:18 where field access is passed to setX getX

8:18 which interface should i use? IPersistentMap or ITransientMap ?

8:36 fullets: Any suggestion as to why (pmap identity [1]) would be throwing RejectedExecutionException when eval'd in a slime session, but not when eval'd in e.g. lein repl

8:53 bendlas: fullets: that looks like a bug in swank-clojufre

8:53 /s/swank-clojufre/swank-clojure/

8:53 feel free to open an issue here https://github.com/technomancy/swank-clojure/issues

8:55 fullets: bendlas: looks like i'm a bit out of date, i'll try 1.3.2 first

8:56 bsteuber: fullets: yes, that should be fixed now

8:57 so better update both lein and swank

9:02 bendlas: bsteuber, fullets: Oh, now I know why that sounded familiar. Verified on an outdated version myself. Sorry about that.

9:03 Cozey: how do i set deftypes fields ? assoc? they are mutable - so assoc will return the same object right ?

9:03 stuartsierra: deftype fields are not mutable.

9:04 Cozey: "deftype supports mutable fields, defrecord does not" @ http://clojure.org/datatypes

9:04 bsteuber: not per default, that is

9:05 stuartsierra: You have to add ^{:unsynchronized-mutable true} or ^{:volatile-mutable true} metadata to the fields. Then they can be modified with `set!`

9:06 tomoj: isn't there a warning

9:06 stuartsierra: yes.

9:06 "Don't do this." :)

9:07 Cozey: here be dragons

9:07 tomoj: ah, right - "They are for experts only - if the semantics and implications of :volatile-mutable or :unsynchronized-mutable are not immediately apparent to you, you should not be using them."

9:07 I still have no clue what they do :/

9:07 Cozey: btw : what is the difference between them?

9:07 stuartsierra: Read "Java Concurrency in Practice"

9:08 Cozey: :unsynchronized-mutable means just 'there's no lock here'

9:08 stuartsierra: No!

9:08 volatile != locking

9:08 Cozey: and volatile-mutable means - some other thread may modify it ?

9:09 stuartsierra: Like I said, read Goetz.

9:09 The definition of 'volatile' is subtle and complicated.

9:09 tomoj: is there no way to make those fields private?

9:11 I mean, so anybody who has a reference to one of these can mutate those fields? sounds scary

9:12 Cozey: ok. i'll check out the book.

9:12 one question though: in the 'persistent/transient' context, how are normal java objects treated?

9:12 or is this a wrong question ?

9:13 or are their methods treated like any other 'side effect' call

9:13 bendlas: Cozey: when using java interop, you're on your own

9:13 TimMc: persistent/transient are guarantees some Clojure objects make

9:13 bendlas: that especially include mutable fields

9:13 Cozey: mhm

9:14 TimMc: ,(transient (Object.))

9:14 clojurebot: java.lang.ClassCastException: java.lang.Object cannot be cast to clojure.lang.IEditableCollection

9:14 TimMc: ,(persistent! (Object.))

9:14 clojurebot: java.lang.ClassCastException: java.lang.Object cannot be cast to clojure.lang.ITransientCollection

9:14 Cozey: mhm

9:15 i wanted to be able to pass a java object to clojure functions, where object's properties would be accessed via getX/setY/isZ methods

9:15 i thought that i might create a deftype implementing some of clojure's interfaces

9:16 and reference the object in its field

9:16 but now i'm a little bit afraid i will get all the persistent/transient semantics wrong

9:16 especially that i can't find documentation for those interfaces - what do they promise etc.

9:18 buddywilliams: Good morning

9:19 I was hoping someone could tell me why I cannot sharp-quote an anonymous function

9:19 #'(fn [x] (* x 2))

9:19 but I am allowed to sharp-quote a named fn

9:19 fullets: bendlas, bsteuber: thanks - upgrading to the current versions of lein & swank-clojure did indeed fix the problem

9:19 tomoj: what would you expect that to do?

9:19 stuartsierra: buddywilliams: sharp-quote means "get the Var named …"

9:19 Scriptor: #'(fn foo [x] (* x 2))

9:20 ,#'(fn foo [x] (* x 2))

9:20 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

9:20 TimMc: I suspect buddywilliams is trying to do something like #'some-fun

9:20 buddywilliams: gotha

9:20 gotcha*

9:20 since there is no var named.. it fails

9:20 stuartsierra: yep

9:20 buddywilliams: A friend and I are going through onlisp and converting all the examples to clojure

9:21 to both read a good book and learn clojure

9:21 Scriptor: buddywilliams: yep, fn just returns the function object while any def form returns a var, which is what sharp-quote uses

9:21 TimMc: Cozey: Those interfaces are not really for user consumption, unless you really want to introduce a new transient/persistent pair, which is probably not really what you want.

9:21 bendlas: #' does indeed work on all vars, not just named fns

9:21 stuartsierra: And #' means something very different in Common Lisp.

9:21 buddywilliams: apparently, this works in common lisp: #’(lambda (x) (* x 2))

9:22 so from what I am gathering, this is impossible in clojure

9:22 Scriptor: yay for lisp 2's

9:22 TimMc: What does it do in CL?

9:22 bsteuber: Cozey: but you don't need mutable references to hold mutable objects

9:22 Scriptor: buddywilliams: that's because CL is a lisp-2

9:22 buddywilliams: returns #<Interpreted-Function C674CE>

9:22 stuartsierra: Functions and variables have different namespaces in CL. #' means "use the function namespace"

9:22 bsteuber: so even a record might be fine

9:23 buddywilliams: I haven't heard of lisp-2

9:23 Cozey: bsteuber: yes ok, i thought it might be ther right way

9:23 Scriptor: basically, whereas in clojure you can pass an actual function object to another function as a parameter

9:23 Cozey: but apparently it's not

9:23 when would one use mutables? for speed?

9:23 bendlas: so a plain (lambda (x) ...) in CL would be an error?

9:23 buddywilliams: gotcha stuart

9:23 no

9:23 bendlas

9:24 Scriptor: so if the parameter is called 'a' and it contains a function object, clojure is perfectly happy doing (a arg1 arg2...)

9:24 fullets: bendlas: no; #'(lambda ...) and (lambda ...) are equivalent

9:24 bsteuber: Cozey: yes if you implement somethig very low-level and very performance-critical yourself

9:24 bendlas: I see

9:24 bsteuber: like a new collection type

9:24 buddywilliams: stuart I was reading somewhere that you went through onlisp and converted some of the examples - do you have that posted anywhere?

9:24 fullets: bendlas: 'foo : (quote foo) :: #'foo : (function foo)

9:24 Cozey: mhm ok

9:24 buddywilliams: maybe I could reference it if I get stuck

9:24 stuartsierra: buddywilliams: wasn't me

9:25 buddywilliams: ok, I wasn't sure

9:25 Scriptor: buddywilliams: other stuart, I think

9:25 http://thinkrelevance.com/blog/2008/12/12/on-lisp-clojure.html

9:25 buddywilliams: thanks Scriptor

9:26 I am very new to Clojure/LISP but I want to say that it is very compelling

9:26 bendlas: fullets: yep, been aware of that. Therefore I found #'(lambda ..) confusing

9:27 fullets: bendlas: I think lambda is just special cased because lambda is special. I remember reading somewhere lambda not requiring #' was a change late in the standardisation process, but I may well be wrong

9:28 So, incanter has swank-clojure 1.3.0-SNAPSHOT in its :dependencies, and I want to use swank-clojure 1.3.2 that I have in my :dev-dependencies. Is there a way to resolve this in favour of 1.3.2?

9:28 bendlas: fullets: I see, thanks

9:29 stuartsierra: fullets: use an exclusion.

9:29 fullets: stuartsierra: ah, thankyou

9:40 dbushenko: how to access HttpRequest from the Ring web-application?

9:40 and the same for HttpResponse?

9:43 Scriptor: dbushenko: check the docs, requests are passed to the function and responses are returned

9:45 dbushenko: Scriptor: I still don't get it. where is HttpServletResponse in the response map?

9:45 stuartsierra: I don't think Ring exposes those.

9:46 dbushenko: stuartsierra: so it is not possible?

9:46 stuartsierra: Probably not with Ring. But you can use the Servlet API directly from Clojure.

9:46 dbushenko: :-( I wanted to use the JavaSequrity from a Ring-based app

9:47 but I need the httpservletrequest to get the context and the current user

9:51 stuartsierra: Check the source - the servlet object must exist somewhere, perhaps you can get at it.

9:52 joegallo: i don't think it does, sadly

9:52 https://github.com/mmcgrana/ring/blob/master/ring-jetty-adapter/src/ring/adapter/jetty.clj#L10

9:52 they're there alright (the request and response that it), but i don't think you can get at them easily

9:53 that said, you could easily copy&paste your own new ring jetty adapter that stored the request object in a var or something

9:53 dbushenko: shit happens.....(((((

10:00 are there any examples of using wrap-flash ?

10:16 bendlas: when using M-x clojure-jack-in, where does the stdout go?

10:18 looking at the source, i suspect it just gets muted

10:18 Fossi: anybody else who always reads that as "stout"?

10:18 bendlas: with (set-process-filter process nil)

10:19 Fossi: I'm not a native speaker, so till now: no ;)

10:20 technomancy: any comments on that?

10:20 bsteuber: Fossi: normally to the swank-repl

10:20 are you in another thread?

10:20 bendlas: bsteuber: yes, I'm talking about BG threads

10:20 bsteuber: the thing is, *out* just points to swank in the main thread

10:21 so what you can do

10:21 bendlas: like logging from a jetty, or something

10:21 bsteuber: (alter-var-root #'*out* (constantly *out*))

10:21 then it'll be the same in all threads

10:21 bendlas: bsteuber: right, that should do

10:22 and it really should be made so by default

10:22 bsteuber: oups it was you, not fossi :)

10:22 * bendlas goes to prepare a patch

10:23 bendlas: hm, but still, it won't work for java code, writing directly to System.out

10:23 or native libs, printf'ing

10:25 bsteuber: hmm

10:25 so better change System.out?

10:26 bendlas: you thing native code isn't an issue?

10:26 s/thing/think

10:26 lazybot: <bendlas> you think native code isn't an issue?

10:27 bsteuber: well no idea

10:27 for me, rebinding *out* is enough

10:28 but if you have a clean way to redirect everything, why not

10:28 bendlas: we could just redirect it into an emacs buffer

10:29 called *swank stdout/stderr* or smth

10:34 * bendlas places palm firmly on forehead

10:35 bendlas: actually, stdout *goes* to the buffer right now

10:35 it's just appended on top, which is why i overlooked it till now

10:51 dnolen: this is awesome, https://github.com/frenchy64/Logic-Starter/wiki

10:53 ambrose explains in great and entertaining detail the simple type checker for the simply typed lambda calc that I posted a while back.

11:08 vijaykiran: Hi all .. I've a noob question editing clojure in Emacs - how can I wrap the existing code in a new function ? is there a shortcut for it ?

11:10 nevermind found it: M-x paredit-wrap-round :-)

11:11 kumarshantanu: vijaykiran: Alt+Shift+Left_bracket

11:11 after placing the cursor at the beginning of the s-exp

11:12 vijaykiran: kumarshantanu: sweet - thanks !

11:13 kumarshantanu: vijaykiran: another way is to type an empty parens first...any kind of bracket, then press Ctrl+Right_arrow_key

11:13 Scriptor: confusing, brackets can specifically be [] in British English and () and US English

11:13 er, the reverse of that

11:14 kumarshantanu: Scriptor: :-) regular brackets in Lisp are these --- ()

11:15 Hodapp: Scriptor: How is it in British English? In US English the convention seems to be to use the latter for outermost, and [] if you're doing that inside of parentheses.

11:16 joly: US here, and I've always heard "brackets" or "square brackets" for [], "parens" or "parentheses" for (), and "angle brackets" for <>

11:16 Hodapp: Same here.

11:16 vijaykiran: kumarshantanu: Ctrl+Right_arrow doesn't work for me - the mac spaces takes over that shortcut. But the Alt+Shift+LeftBracket will help me.

11:16 Scriptor: Hodapp: I'm going by what's in http://en.wikipedia.org/wiki/Bracket#List_of_types

11:17 but what joly said is how I think of it

11:18 kumarshantanu: vijaykiran: Ctrl+Cmd+Right_arrow is the switch-space keystroke on my Snow Leopard, so Ctrl+Right_arrow works for me

11:18 Hodapp: damn, I don't much like #java.

11:18 joly: Interesting list. I don't think of {} as "curly brackets". I've always heard "braces"

11:18 Hodapp: I get that they get a lot of dumb questions, but I really don't like the sorts of dismissive replies that are common.

11:19 Scriptor: I've had cs teachers say curly brackets, probably because it was easier to remember

11:19 Hodapp: joly: I always hear them as "curly brackets" or "curly braces" mostly because "brackets" or "braces" on their own would always be confused with something else.

11:19 joly: yeah

11:19 vijaykiran: kumarshantanu: I'm using lion - anyway - I'll remap the keyboard :-) thanks for the tip.

12:08 dnolen: sorenmacbeth: my take, https://github.com/swannodette/query-extractor/blob/master/src/query_extractor/core.clj

12:12 sorenmacbeth: dnolen: awesome, I like it. you didn't copy/paste the query-key map, but I still see it referenced (line 24). I assume you meant for it to still exist?

12:13 dnolen: nm, I see what you did.

12:16 dnolen: if you wanna do a pull request, I'll merge it. Otherwise, I'll probably just copy/paste your changes manually ;)

12:17 dnolen: sorenmacbeth: done

12:17 sorenmacbeth: dnolen: cheers and thanks!

12:21 technomancy: holy crap, scala.net attempts to automatically map JDK classes to their .NET equivs. that sounds impossibly shaky.

12:23 Scriptor: technomancy: under which question in the release page does it say that?

12:24 nvm, think I found it

12:26 technomancy: it sounds like they have a lot of wrapper classes the likes of which Clojure explicitly avoids

12:27 Scriptor: such as Scala.IO?

12:27 pjstadig: yes, but Scala is statically typed, so presumably it can compile away wrapper classes when necessary?

12:27 technomancy: ah, hadn't thought of that. possibly.

12:29 pjstadig: but maybe that is the "assume a sufficiently smart compiler" fallacy

12:39 sorenmacbeth: I've got 3 irccloud.com invites. If anyone is interested, shoot me an email to soren {at} dopeness {dot} org

12:39 Scriptor: just asked in #scala, apparently JIT inlining is enough to make it not as bad

12:44 gfrlog: is there any reason that calling (slurp) on the org.mortbay.jetty.HttpParser$Input that is my ring request body would be in inappropriate way of processing it?

12:45 I'm having this strange problem where my json data works from browser/ajax, but fails from curl.

12:45 from curl the content-length header is plainly 23, as reported by curl and the ring request, but slurping the body returns the empty string.

12:46 * gfrlog wonders if saying "the empty string" indicates he's spent too much time with math

12:47 gfrlog: I'm not sure how to debug this :/

12:57 apparently setting the correct content-type (application/json) makes it work :/

12:57 seems pretty weird to me.

12:58 Scriptor: gfrlog: what content-type were you using before?

12:58 gfrlog: I guess compojure probably eager-reads forms so it can provide it to the routes

12:58 Scriptor: it was the curl default, application/x-www-form-urlencoded

13:18 volton: Hi, I am currently reading The Joy of Clojure and I don't understand this function: https://gist.github.com/1090074

13:18 Why does it return a PersistentVector?

13:19 raek: heh, that looks strange...

13:19 maybe a typo

13:19 volton: I copied it from the book tho and it works

13:21 now I get it, it adds the result of f to a vector

13:21 sorenmacbeth: voltron: it returns a PersistentVector because everything is wrapped in square brackets

13:21 volton: sorenmacbeth: you said it so much better

13:25 ,()

13:25 clojurebot: ()

13:26 volton: So the main difference between Lists and Vectors is that elements are added to the front of the list and to the back of the vector?

13:27 And the following:

13:27 ,('(\a \b \c) 1)

13:27 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

13:27 volton: ,([\a \b \c] 1)

13:27 clojurebot: \b

13:27 amalloy: volton: well, you also don't have to quote vectors, as you demonstrated

13:27 kumarshantanu: volton: ,[\a \b \c]

13:28 amalloy: volton: the fact that lists are not callable is not just an inconvenience, either: nth provides fast random access to vectors, but slow random access to lists

13:30 volton: so Vector ~ ArrayList and List ~ Linked List?

13:30 amalloy: uhhh

13:31 kinda? i mean, that's more true than if you reversed the associations, but mutability creates a number of other asymmetries

13:31 raek: volton: basically. they are immutable (and persistent), so there are some other differences

13:31 volton: yes of course I know that but just regarding the runtime complexity of basic operations

13:31 raek: volton: to create a new list with one element in the middle changed, you need to create new nodes for all elements before the middle one

13:32 vectors have more sophisticated random access and update capabilities

13:32 yes. kinda.

13:33 and a clojure list is singly linked, unlike the java LinkedList

13:33 volton: ah, good to know

13:33 amalloy: volton: that kinda falls out of the immutability

13:34 having a backlink is fairly pointless if you can't update it, and it would mean that every change to a list requires recreating every entry

13:41 raek: name-this-function time! https://gist.github.com/1090133

13:41 * raek feels he steps into Monad territory

13:42 amalloy: raek: imo error-fn should accept [res & args]

13:42 raek: that makes sense.

13:43 amalloy: i'd call it something like attempt

13:43 raek: then should success-fn accept [res & args] too? :-)

13:43 amalloy: good name

13:47 volton: thanks for your help guys!

13:52 cemerick: I'd become the biggest google+ booster *ever* if it provided a way to vote GGroups threads down into oblivion.

13:54 mayankkohaley: Hello Guys

13:55 I want to learn clojure , can somebody please let me know some good books for learning clojure

13:59 dnolen: mayankkohaley: http://www.amazon.com/s/field-keywords=clojure

13:59 I have Programming Clojure & Joy of Clojure, both are good.

14:00 mayankkohaley: dnolen thanks a lot

14:02 amalloy: oh dnolen, i see you responded to my tweet-question. mispaste would be weird, because the (run 4) example sxhibits similar behavior

14:04 dnolen: amalloy: so you're running this on your machine? I don't see _.0. clojure 1.2.1 + core.logic 0.6.2 right?

14:04 amalloy: dnolen: no, i'm not

14:04 dnolen: amalloy: both examples are wrong, I've sent ambrose corrections.

14:05 amalloy: dnolen: whew, thanks

14:05 dnolen: amalloy: _.0 is ridiculous, that type can only be a function.

14:05 for those cases

14:05 amalloy: right

14:06 dnolen: amalloy: good catch, thx.

14:28 buddywilliams: ,(println "hello world")

14:28 clojurebot: hello world

14:28 buddywilliams: very cool

14:33 pmbauer: botsnack

14:34 amalloy: ~botsnack ;; pmbauer

14:34 hm. apparently clojurebot doesn't like excess args

14:34 clojurebot: forget botsnack is Thanks, but I prefer chocolate

14:35 pmbauer: ah :)

14:35 amalloy: $botsnack ;; or this

14:35 lazybot: amalloy: Thanks! Om nom nom!!

14:35 technomancy: clojurebot: forget forget botsnack |is| Thanks, but I prefer chocolate

14:35 clojurebot: I forgot that forget botsnack is Thanks, but I prefer chocolate

14:35 technomancy: geez

14:35 amalloy: hahaha

14:35 technomancy: how did that get in there

14:35 amalloy: technomancy: ISTR someone getting very excited about clojurebot accepting instructions from random strangers

14:36 and teaching him a bunch of nonsense

14:36 technomancy: The Internet: it's new to some people.

14:36 amalloy: just don't tell him about Wikipedia

14:36 amalloy: haha

14:37 technomancy: though I guess you could always point him to the page about chickens

14:37 because dudes already know a lot about chickens

14:37 as do ladies, typically

14:37 http://www.everytopicintheuniverseexceptchickens.com/

14:37 * amalloy wonders what meme he's missing

14:39 amalloy: technomancy: fascinating

14:40 hah. and the writing style is so distinctive, i almost didn't have to doublecheck that it was ryan

14:40 technomancy: so true

14:40 bulters: you've got to love the sound of memes swooshing by...

14:41 Scriptor: no wonder I kept picturing a T-re

14:41 x

14:44 amalloy: technomancy: and yet that article seems unmolested. does this explain all the vandalism on the rest of wikipedia?

14:47 technomancy: yeah, entirely too tame: http://en.wikipedia.org/w/index.php?title=Chicken&action=historysubmit&diff=418205235&oldid=418205062

14:52 pmbauer: Here we are, Wikipedia chicken vandalism ... all because I couldn't remember the delimiter for botsnack

14:53 ;)

14:54 bulters: mankind will remember you

14:54 they will talk about you when discussing the beginning of the end of Wikipedia

15:33 dans: can anyone help me with setting up vimclojure? cant get the ng console to work: https://gist.github.com/1090423

15:33 i've installed it with leiningen

15:50 markskilbeck: dans: I never even got that far. Had to bite the bullet and use emacs. Mucho simpler.

15:52 dans: i have never used emacs, not really an option

15:54 Somelauw: dans: I have the same problem. Right now I use vim for writing + syntax highlighting + autocompletion and copy pasting to console for testing.

15:54 markskilbeck: Somelauw: sounds long-winded.

15:54 Scriptor: dans: have you looked into slimv?

15:54 might be enough to replace nailgun

15:55 markskilbeck: Actually, it was slimv that I couldn't get installed.

15:55 I think... My memory isn't cooperating.

15:56 Somelauw: markskilbeck: When using emacs I am always fighting with it. Like if I want to surround a form by another one, I put a ( before it and it creates (). Then I press backspace and it deletes ().

15:56 chouser: I recommend https://bitbucket.org/agriffis/screenrepl

15:56 dans: Somelauw: i think i will do the same, at least the syntaxhighlighting is sort of working

15:57 Scriptor: how do I wrap a sexpr in square brackets with paredit?

15:57 amalloy: Scriptor: M-x paredit-wrap-square

15:57 raek: Somelauw: that's paredit (which can be disabled). just select the thing you want to wrap and then press (, or type the ( and then press C-<right>

15:57 amalloy: bind that to a key if you want

15:57 Scriptor: Somelauw: that's because you have paredit enabled

15:57 amalloy: raek: (or just M-(, which seems easier to me)

15:58 Scriptor: I'm trying to learn it though and it's actually pretty cool, http://www.emacswiki.org/emacs/PareditCheatsheet helps a ton

15:58 amalloy: thanks

15:58 dans: lets face it, vim is so much cooler

15:58 raek: amalloy: oooh, nice!

15:59 amalloy: raek: yeah, i only recently bound M-[ and M-{ to similar things

15:59 Somelauw: I wonder if there are many people that use emacs for lisp languages and vim for everything else.

15:59 markskilbeck: Somelauw: I do.

16:00 amalloy: Somelauw: gfrlog uses emacs just for irc, i think. madman

16:01 Scriptor: Somelauw: that's what I'm using

16:01 *doing

16:02 though if it wasn't for slime being so easy I'd be pure vim

16:02 markskilbeck: Scriptor: ++

16:03 Somelauw: But thanks for helping me with paredit. I will remember it for when I give emacs another go.

16:03 amalloy: paredit is solid gold

16:04 once you stop fighting it, anyway. a settling-in period is inevitable

16:04 Somelauw: Okay, I am going to try it right now.

16:06 amalloy: Somelauw: and when you get really desperate or frustrated with paredit, you can always insert a character manually with C-q

16:06 but it's super-handy to, eg, just hit ] whenever you want to close any kind of bracket, and let paredit figure out which kind and where it belongs

16:06 ejackson: or, in aquamacs, with an OSX copy paste. sneaky.

16:07 amalloy: ejackson: just an emacs kill/yank works fine too

16:07 dnolen: Somelauw: depends on what languages, Emacs support for functional/logic programming languages seems superior.

16:07 ejackson: ok, wasn't sure.

16:07 amalloy: ejackson: even M-x delete-backward-char is fine; paredit only rebinds the backspace key, not the function it's usually bound to

16:08 ejackson: that's polite !

16:08 Somelauw: dnolen: logic programming languages? Do you mean the set of languages consisting solely of prolog? :P

16:08 ejackson: anyway, copy paste of ) etc is a very handy paredit override

16:09 amalloy: ejackson: blech. it's useful to know, but if you use it often enough for it to be "very handy" i'm concerned

16:09 ejackson: no, its just when you need it, you need it.

16:09 dnolen: Somelauw: there are many Prolog variants, Mozart/Oz, Mercury

16:10 Somelauw: But paredit seems to work well, now that I understand it.

16:10 ejackson: oh yeah, its fantastic.

16:11 amalloy: also probably worth remembering are M-r, M-UP, and C-}

16:12 C-} looks like some kind of crazy emoticon

16:20 Scriptor: what's the shortcut for switching to the slime repl? (other than C-x b'ing into it)

16:21 bsteuber: C-c C-z

16:22 Scriptor: ah, thanks!

16:23 amalloy: Scriptor: see also C-c M-p: "set the repl's namespace to this file's namespace"

16:24 Scriptor: dude...

16:24 so I don't have to keep doing use?

16:24 amalloy: well, C-c M-p won't do that, it just issues an (in-ns) call, i think

16:25 but C-c C-k compiles/loads the current buffer

16:25 Scriptor: right

16:26 amalloy: in that case you never had to do (use), i think

16:27 Scriptor: hmm, I still did if I have functions in my-project.core and I didn't want to have to prefix every function call in the repl with that

16:28 amalloy: Scriptor: you're missing a feature of clojure's repl, not of slime

16:28 &(doc in-ns)

16:28 lazybot: ⇒ "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."

16:28 amalloy: so you could, eg, in a plain repl: (require 'myproj.core) (in-ns 'myproj.core) (my-unprefixed-fn 1)

16:29 Scriptor: amalloy: right, just saying that having to do (use ...) every time I added a new function got tedious

16:29 pmbauer: dans: I tried vimclojure and had much more success with slimv. Swank, paredit, repl buffer, completion are all built-in

16:29 amalloy: Scriptor: i don't understand. you don't have to do that

16:29 Scriptor: amalloy: ah, didn't realize that, thanks

16:29 (regarding the in-ns code)

16:30 amalloy: technomancy's much-loved shortcut for that is (doto 'myproj.core require in-ns)

16:32 bsteuber: I prefer C-c C-k, C-c M-p, C-c C-z

16:32 maybe I should define a shortcut for the three in a row ^^

16:33 ejackson: i feel so backwards. I just keep (use :reload-all ...) in the command buffer and M-p

16:33 amalloy: bsteuber: yeah, i keep meaning to shortcut some combination of those

16:33 probably just the last two

16:33 michaelr524: hello everybody

16:33 amalloy: ejackson: shhh, if you say that aloud nobody will ever respect you again

16:34 ejackson: :p

16:34 bsteuber: amalloy: yeah, last two sounds reasonable

16:35 michaelr524: what's the shortcut in emacs to switch to the slime window at the bottom and then back to the code window at the top?

16:36 icey: So, any truth to the rumor that on Wednesday Rich is going to be announcing Smjalltjalk?

16:36 ejackson: michaelr524: C-x o ?

16:37 Scriptor: icey: I'd figure if there's gonna be anything about a new language it'd be more prolog-y

16:37 maybe finally clj-in-clj?

16:37 michaelr524: ejackson: thanks!!!

16:37 amalloy: Scriptor: i imagine we'd have seen git commits leading up to that

16:37 ejackson: np

16:38 bsteuber: maybe clojure's collection types are mutable now for performance reasons :P

16:38 icey: I think it's interesting that nobody's really sure what's going to be talked about

16:39 ejackson: icey: we call it frijjon.

16:39 technomancy: icey: that's clojure/core for you

16:39 Scriptor: if he started targetting php I'll be pissed

16:40 icey: ejackson: lol

16:40 technomancy: it's very apple-y of them... not that i really mind

16:40 Scriptor: the thing is, both rich and sierra were at the last meetup, are they just really good at keeping secrets?

16:40 icey: technomancy: although, I also don't write tons of libs that would be impacted by language changes

16:42 raek: michaelr524: if you use the emacs starter kit, you can use shift and the arrow keys to switch between buffers

16:43 michaelr524: raek: ah, i'm using the clojure-jack-in stuff from technomancy. just starting with emacs, used vim for years... :)

16:43 bendlas: is there some kind of clojure meeting at wednesday?

16:43 amalloy: bendlas: rich is presenting at the nyc meetup

16:44 pmbauer: amalloy: rich hasn't committed very often to clojure's github this year. My guess is there's development going on that's not public.

16:44 amalloy: pmbauer: good point

16:44 Scriptor: bendlas: yep, in nyc

16:44 but they'll be streaming it live

16:45 bendlas: i see

16:45 pmbauer: http://www.ustream.tv/channel/clojurenyc

16:45 6:45 PM EST

16:50 ejackson: my money is on streams

16:51 Scriptor: would streams offer anything new from lazy-seqs?

16:52 raek: EST = UTC-5 ?

16:52 amalloy: raek: yeah

16:53 technomancy: should beEDT

16:54 islon: this code: (let [cal (as-calendar date)

16:54 year (.get cal Calendar/YEAR)]

16:54 (.isLeapYear cal year))

16:54 gives me: Reflection warning, /home/islon/Dropbox/date-clj/src/date_clj.clj:108 - call to isLeapYear can't be resolved.

16:54 as-calendar is already typehinted

16:54 raek: technomancy: so the 6:45 PM time is in UTC-4 then?

16:55 islon: anyone knows how can I remove the warning?

16:55 raek: 02:45 at thursday here, then... :)

16:55 technomancy: raek: I don't know, you should ask hiredman to load clojurebot with joda so you could ask him =)

16:57 sorenmacbeth: islon: have you seen https://github.com/getwoven/clj-time ?

16:58 islon: sorenmacbeth: I don't know how looking at clj-time will solve my type hint removing problem

16:59 *reflection-warning removing

16:59 Raynes: technomancy: fwiw, lazybot has joda on the classpath.

16:59 raek: joda-time (clj-time is a wrapper for it) is a much better date and time library

17:00 Raynes: islon: The answer to any question related to dates and times in Java is 'joda'. Period.

17:00 dabd: does anyone know how can I apply the latex listings patch http://alexott.net/common/clojure/clj-latex.txt to include clojure source code in latex documents?

17:01 islon: Raynes: sorry, but I didn't ask anything about dates, i asked about how to remove a reflection warning

17:03 benreesman: how do i check if a reference points to an instance of a primitive array? i can't remember how to spell that

17:04 pmbauer: islon: what is the type returned from as-calendar? isLeapYear is defined on GregorianCalendar, not Calendar.

17:04 amalloy: &(instance? (class (int-array 0)) 10)

17:04 lazybot: ⇒ false

17:04 kjeldahl: Any nrepl client running on Emacs yet, or updates on recommended method of running clojure from emacs?

17:05 (yeah, I've managed to hack together slime stuff and gotten it working before, but it seems less than ideal..)

17:05 islon: pmbauer: (defn- ^Calendar as-calendar ...

17:06 benreesman: amalloy: cool thanks

17:06 technomancy: did someone find the name sexpbot offensive?

17:06 I feel like I may have missed out on some Internet Drama.

17:06 Somelauw: very offensive

17:06 pmbauer: islon: That would be why you are getting the reflection warning. isLeapYear isn't defined on the Calendar interface.

17:06 Somelauw: :P

17:07 amalloy: technomancy: there wasn't much drama

17:07 Raynes: technomancy: No. We're using it in a work-related channel and ninjudd gave me a $50 amazon gift card to rename it so that he wouldn't have to explain to his wife what 'sexpbot' had to do with work.

17:07 It was actually a pretty fun day.

17:07 technomancy: hah; classic.

17:08 islon: pmbauer: hmmm... you are right, thank you =) i'll try to cast to GregorianCalendar

17:08 amalloy: i figure we'll rename him every week now to make it harder for hiredman to keep him on /ignore

17:12 fliebel: what, sexpbot is now lazybot?

17:12 Raynes: Yessir.

17:12 fliebel: :)

17:20 michaelr524: is there a trick to use (map) int (->)?

17:20 s/int/in

17:20 lazybot: <michaelr524> is there a trick to use (map) in (->)?

17:20 fliebel: michaelr524: how do you want to use it?

17:20 michaelr524: I want to trim every string in a list

17:21 fliebel: michaelr524: So what do you need -> for?

17:22 michaelr524: I already use ->

17:23 fliebel: you can do (-> some code (->> (map fn)) other code

17:23 michaelr524: ahh

17:23 good idea

17:23 let me try that

17:23 :)

17:25 worx!!

17:25 thanks

17:25 fliebel

17:26 bsteuber: michaelr524: but -> inside ->> won't work

17:26 which makes sense when you think about it

17:26 fliebel: Dos anyone have a neat trick for going the other way around? like (->> seq map filter reduce (<<- (nth 4))

17:26 michaelr524: btw, anyone knows why C-C C-C compiling a function is really quick buy C-C C-K compiling the whole buffer takes like 30-40 seconds here?

17:27 amalloy: fliebel: anonymous functions

17:27 &(->> (range) (filter even?) (take 10) (#(nth % 4)))

17:27 lazybot: ⇒ 8

17:27 stuartsierra: michaelr524I think It's a bug in Emacs on some windowing systems (e.g. OSX) - it takes too long to draw the progress bar.

17:28 amalloy: michaelr524: try (setq font-lock-verbose nil)

17:28 michaelr524: stuartsierra: i'm on xp, here I don't get a progress bar even :)

17:28 fliebel: amalloy: hm, yea, that might work.

17:28 stuartsierra: michaelr524: dunno then

17:29 michaelr524: amalloy: what's that supposed to do?

17:30 fliebel: michaelr524: the reverse of what I showed you.

17:30 michaelr524: fliebel: yeah. I was asking regarding the elisp snippet :)

17:31 * fliebel goes to bed instead

17:33 michaelr524: amalloy: didn't help, took 38 seconds

17:33 amalloy: michaelr524: the part that's slow is usually emacs running a bazillion regexps on the compiler output, or something crazy like that

17:33 michaelr524: amalloy: yeah, who knows... it might be calling home to andromeda or something :)

17:35 bendlas: michaelr524: in that case you should contact NASA, cause 38 seconds would be wicked fast for that

17:35 ;)

17:35 michaelr524: didn't they close nasa already?

17:41 bsteuber: damn, I was just writing a cool "-> inside ->>" macro for fliebel and now he left

17:41 but for the fun

17:41 (defmacro ->* [& args] `(-> ~(last args) ~@(butlast args)))

17:43 bendlas: heh, one of our bots should keep a mailbox for offline users

17:43 bsteuber: good idea

17:47 amalloy: bendlas: lazybot already does

17:47 $mail bendlas hey a message for you

17:47 lazybot: Message saved.

17:47 bsteuber: cool

17:47 clojurebot: Pardon?

17:48 amalloy: then next time you join/talk, he /msgs you

17:48 bendlas: wut?

17:48 Raynes: amalloy: He sends a NOTICE, I believe.

17:48 bendlas: ok, it didnt message me

17:48 brb

17:49 Raynes: Some people have weird settings and don't NOTICE the NOTICEs.

17:49 amalloy: Raynes: yeah, but i don't really understand notices

17:49 bendlas: ok, i didn't get anything

17:49 amalloy: i think it may be a default erc setting. the last guy who had trouble was using erc too

17:49 bendlas: would ERC notify me in a fairly std config?

17:49 amalloy: *shrug*

17:50 raek: when reading the RFC, you get the impression that notices would be ideal for bot utterances

17:50 Raynes: amalloy: It definitely has to be notices though. PMs would get really annoying really fast.

17:50 bendlas: In any case, you can /msg lazybot $mail to get the message.

17:50 raek: but for some reason clients seem to interpret notices as announcements

17:50 and trigger the bell, etc

17:50 bendlas: i see

17:50 it worked

17:50 Raynes: raek: Or ignore them altogether. Which is what ERC seems to be doing.

17:51 bendlas: Raynes: no, i just saw it

17:51 Raynes: Oh.

17:51 Cool.

17:51 bendlas: but it is fairly well camouflaged

17:51 in the irc.freenode buffer

18:17 miltondsilva: ~30 min to live feed right?

18:17 clojurebot: The Clojury says to stop making puns.

18:20 icey: miltondsilva: are you asking about the ClojureNYC meetup?

18:20 miltondsilva: ohh... forget it, I see I got the wrong date ;)

18:20 icey: miltondsilva: :)

18:25 bendlas: I have written a dir macro: http://paste.lisp.org/display/123338

18:25 feedback very welcome!

18:30 bsteuber: bendlas: why does it need to be a macro?

18:30 bendlas: pure convenience

18:30 raek: miltondsilva: hrm. that time seems 2 hours off to me... are my calculations wrong?

18:30 bendlas: it's for repl use

18:30 so you can write (dir clojure.java.io)

18:30 amalloy: bendlas: (if (= `*ns* dir) *ns* ...) is madness

18:32 raek: ...or one hour, I think

18:32 amalloy: raek: the meetup starts 48 hours and 15 minutes from now

18:32 bendlas: amalloy: let me think for a moment, what that was the workaround for

18:32 amalloy: bendlas: it was for you quoting *ns* incorrectly in the other clause

18:33 miltondsilva: raek: hmm... I got the wrong day... about the time, according to this http://24timezones.com/world_directory/current_new_york_time.php and this http://www.google.com/url?sa=D&q=http://www.meetup.com/Clojure-NYC/events/16166953/ I think I'm right.. or am I missing something?

18:33 raek: amalloy: eh. my calculations were wrong...

18:33 miltondsilva: no, you were right! (modulo the day)

18:34 00:45 is way more convenient than 02:45 for me... :-)

18:34 amalloy: it's starting to seem like i should give lazybot a $meetup command that says how long till the dang thing starts

18:34 bendlas: amalloy: hm, could you help me make a version that wouldn't need it?

18:34 miltondsilva: I was so excited when I heard there was going to be a live feed that I didn't even confirm the date ;)

18:34 amalloy: the no-arg version should read ([] `(dir ~*ns* ns-publics)) if you want to do it that way

18:34 Raynes: Where would I create an issue for tools.cli?

18:35 amalloy: since that's basically equivalent

18:35 bendlas: go ahead, try it that way

18:35 Raynes: Only like 3 new contrib projects are even listed on Jira.

18:35 tools.cli doesn't seem to have a way to collect extra, unused arguments, which seems like a massive black hole of a missing feature.

18:36 patchwork: Hey #clojure, I have a question on stackoverflow for you guys:

18:36 http://stackoverflow.com/questions/6739962/clojure-how-do-i-refer-to-functions-from-a-loaded-file

18:37 Thought it would be better to put it there rather than try to type it all out in here, though if that is not kosher let me know

18:38 bendlas: amalloy: ok, got it

18:38 first clause needs to read ~(ns-name *ns*)

18:54 Bronsa: n

18:59 bendlas: amalloy, everybody else: I've slightly rewritte the dir macro, care to have a look again? http://paste.lisp.org/+2N62/1

19:02 amalloy: dorun..map println? i much prefer a doseq

19:04 bendlas: I normally do too, but it saved a gensym that way ;)

19:07 anyway, if there is no heaver criticism, I'll propose it for inclusion

19:11 amalloy: inclusion in what?

19:11 bendlas: clojure.repl

19:11 instead or maybe in addition to the current clojure.repl/dir

19:12 oh, in that case I should also sort it, like the current one does

19:20 methods: what does this mean ? "Clojure multimethods go further still to allow the dispatch value to be the result of an arbitrary function of the arguments."

19:21 brehaut: methods: in the typical OO programs, the dispatch function for all methods is (fn [& args] (class (first args)))

19:21 amalloy: methods: instead of eg java's inheritance-based polymorphism, you can dispatch based on, say, the first three characters of the string

19:21 brehaut: methods: with multimethods you can write whatever function of the arguments you wish

19:22 amalloy: define a handler for "get" and a handler for "set", and then later some user of your lib can add a handler for "put" and they all work together an play nice

19:22 methods: yea but I think the page was implying that it goes a step farther then generic functions ?

19:23 "CLOS generic functions extend dispatch value to a composite of the type or value of multiple arguments, and are thus multimethods. Clojure multimethods go further still ... " ^^

19:23 amalloy: methods: aha. that's dispatch on the *value* of some argument

19:24 methods: so what your saying is that, "an arbitrary function of the arguments" allows you to do something like test the first 3 letters of a string or something ?

19:24 amalloy: yes

19:24 bendlas: i'm aware that this is not very helpful, but i don't like your function and i'm not sure why

19:24 methods: is there an example ? i would to see how it fits in

19:25 brehaut: methods: (defmulti fac identity) (defmethod fac 1 [_] 1) (defmethod fac :default [n] (* n (fac (dec n))))

19:25 amalloy: one thing you can fix at least is (if-let [line1 line2] (-?> ...))

19:25 Raynes: It's difficult explaining abstract concepts.

19:25 brehaut: admittedly thats a terrible example

19:26 Raynes: I'm so happy I don't have to do i... Oh, man, I'm writing a book, aren't I?

19:26 methods: http://clojure.org/runtime_polymorphism

19:26 well i guess that page already shows an example

19:26 amalloy: oh yeah Raynes, how's that book coming?

19:26 methods: i've used `count` as a dispatch function

19:26 Raynes: amalloy: Slowly.

19:26 methods: I assume that normally [] is just a type of array or something so by him doing actual matching on the values in the array then he's doing just that

19:27 Raynes: amalloy: My publisher is going to hate me if I don't get to work. And hard.

19:27 brehaut: methods: empty vector

19:27 ,(type [])

19:27 clojurebot: clojure.lang.PersistentVector

19:27 methods: sorry I'm really new just reading up on it

19:27 brehaut: thats fine

19:28 methods: yea but my point though is that in clos generic functions would you be able to do the same thing or would it simply only be able to dispatch based on fact that you passed a vector ?

19:28 brehaut: i dont know enough about CLOS to answer that

19:29 methods: someone tried to explain to me once the whole solution that generic functions provide .. something about visitor pattern ... but I'm still not sure if I fully get it

19:29 bendlas: amalloy: it's ok, maybe the wider community will flame it with better arguments ;)

19:29 brehaut: visitor pattern is a clunky implementation of double dispatch to implement a generic fold

19:30 the visitor calls the visitable thing which calls back to the visitor; it allows single dispatch (based on class) used twice to select the correct implementation

19:30 amalloy: jesus, brehaut, really? that's terrible

19:30 brehaut: yeah really

19:31 amalloy: that class was a really long time ago for me, apparently

19:31 $google visitor pattern

19:31 lazybot: [Visitor pattern - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Visitor_pattern

19:31 brehaut: multiple dispatch functions choose their polymorphic implementation based on the types of al lthe arguments

19:31 multimethods choose their polymorphic implementation on any function of the arguments

19:32 if CLOS uses multiple dispatch on type alone then multimethods are more versitle

19:32 if CLOS lets you define any ufnction of the arguments to dispatch then it is equivalent

19:32 methods: oh wait i see .. i was wondering why there was any code in the defmulti part.. that's where he looks into the values passed in and figures out which method to call..

19:33 brehaut: methods: isa? is used under the hood to do the tests

19:34 amalloy: methods: for example, i have a multimethod here (closed-source, sorry) that takes a map as input. to dispatch, it pulls out one of the keys from the map, does some juggling to convert it into a namespace, and then returns as its dispatch value a keyword with that namespace

19:35 brehaut: oh duh. necesssary evil uses multis to process XML

19:36 methods: https://github.com/brehaut/necessary-evil/blob/master/src/necessary_evil/value.clj#L83-101

19:37 apparently xmlrpc is more repelant than i realised

19:39 amalloy: brehaut: xml is like the poster child for defmulti

19:39 brehaut: amalloy: it really is

19:39 amalloy: somewhere in cake there's a defmulti i wrote for generating pom.xml, but curiously i can't find it anymore

19:40 i wonder if they threw it out

19:40 brehaut: raynes has refactored again hasnt he

19:40 Raynes: amalloy: Really?

19:41 brehaut: Raynes: that was me ruining your good name, not amalloy

19:41 amalloy: Raynes: well, i don't remember where i put it. but a recursive grep turns up only three defmultis, none of which are mine

19:41 Raynes: amalloy: It's in depot.pom now.

19:41 amalloy: ah. depot. i forgot about that nonsense

19:42 Raynes: Watch your mouth. Justin will tase you.

19:42 amalloy: methods: https://github.com/flatland/depot/blob/master/src/depot/pom.clj is another example

19:45 methods: is there anything good to read to understand why multi's are better than oo approaches ? (not trying to flame here) .. like you can obviously have the debate about just writing a big switch statement or creating your own defmulti

19:45 in another language.. but i remember someone arguing with me that it's still not the same ?

19:46 brehaut: methods: theres no reason OO canth ave multiple dispatch over arbitrary functions

19:46 methods: yea but people in #lisp might try to kill you if you say that

19:46 brehaut: methods: the main reason to choose between single dispatch and multiple dispatch is performance

19:47 methods: those people are idiots then

19:47 methods: yea because it's like c++'s name mangling

19:47 it's just directly linked right ?

19:47 brehaut: a virtual method in C++ codes is a pointer indirection through the classes vtable

19:48 methods: yea

19:49 brehaut: methods: however, the realm of runtime optimsation and call site caching is deep voodoo for someone like me, so potentially a multiple dispatch scheme might end up no slower than single disptch

19:50 methods: yea i mean in ruby circles people like the duck typing approaching and they don't care really for using obj.type? .. so clojure allowing you to write your own dispatcher seems like it would be more flexible in that approach

19:50 s/approaching/approach

19:50 lazybot: <methods> yea i mean in ruby circles people like the duck typing approach and they don't care really for using obj.type? .. so clojure allowing you to write your own dispatcher seems like it would be more flexible in that approach

19:51 brehaut: im not sure how duck typing has anything to do with multiple dispatch

19:51 methods: well like you said normally it's based on the "type" of the argument right ? but here you can basically write your own dispatcher to test if the object looks like something instead of actually being something

19:51 brehaut: re:just using a big switch statement: if the dispatching logic doesnt need to be externally extensible (in particular run time extensible) then a switch statement may well be smarter

19:52 methods: hm what do you mean by run time extensible ?

19:53 brehaut: code loaded after the multi is defined can extend the multimethod to handle morecases

19:53 a switch statement (cond family for example) cannot

19:53 its simple late binding

19:53 the java equivalent is classes implementing an interface are loaded

19:54 amalloy: methods: see eg clojure.core/print-dup, which is a multimethod in core for readably-printing objects. you can add your own implementation any time, which wouldn't work with switch/case/cond

19:54 brehaut: amalloy: thanks :)

19:55 amalloy: that one only dispatches on type, so it could be a simple protocol, but it demonstrates runtime-extensibility

19:56 brehaut: methods: there a couple of axis here: #{do you need late binding, dont need late binding), #{single dispatch, multiple dispatch}, #{dispatch on type, dispatch on value} and one case not available in clojure: dispatch on return type.

19:59 methods: multimethods are late bound, multiple dispatch on value. switch statements are early bound dispatch on value. protocols (and interfaces) are late bound single dispatch on type.

20:00 methods: each choice has a tradeoff, but generally the later and less restricted your dispatch mechamism the more powerful it is

20:04 amalloy: (defmulti super-powerful [& args] (JOptionPane/showInputDialog nil (apply str "What should I do with " args))

20:04 brehaut: haha awesome :)

20:08 mudge: anyone know what let* means?

20:09 amalloy: mudge: in a clojure context? it's just a more limited version of let, which let (a macro) uses internally

20:09 mudge: yes, in clojure, ah, is let* a function that let uses?

20:10 amalloy: it's not a function, it's a compiler built-in

20:12 mudge: hmm, i didn't see it on clojures list of primitives

20:15 methods: brehaut: well unless your dispatch method has a register hook or something..

20:16 brehaut: methods: i have no idea what you mean

20:16 methods: amalloy: yea that print-dup reminds me of how they do it in haskell ?

20:17 brehaut: hm on return type ?? wouldn't that just be passing the return value to another defmulti ?

20:17 brehaut: methods: read in haskell is an example of a function that switches on return type

20:17 read :: String -> a

20:18 if you do (for example) 1 + (read "1") the result is 2

20:18 if you do say 'if read "True" then 1 else 2' then it returns 1

20:18 because read chooses an implementation based on what the inference engine determines is needed

20:19 methods: I'm confused on how 'read' is doing any switching ?

20:19 amalloy: methods: because it knows what context the result will be used in (it needs an int), it can use the int-making version of read

20:19 brehaut: methods: in the first instance its being used as the second argument to +; the first argument to + is an Integer, so reads return type needs to be an integer, thus read uses that implementation to parse the string.

20:19 methods: in the second it needs a Bool

20:19 methods: oh awesome

20:20 hm reminds me of perl's ability to automatically call scalar() on an array in the right context ?

20:21 brehaut: read's return type is determined at compile time not run time

20:21 technomancy: does it blow anyone else away that there's an alternate JVM out there that's 50kloc and still able to run Clojure?

20:21 methods: yea i think a good example would of been 1+(read "1") == 2 vs "1"+(read "1") == "11"

20:21 technomancy: I mean, one that nobody's ever heard of

20:21 brehaut: technomancy: wow. link?

20:21 technomancy: http://oss.readytalk.com/avian/index.html

20:21 brehaut: methods: thats invalid haskell

20:22 methods: technomancy: 50kloc ?

20:22 technomancy: it's missing a certain JMX class that breaks with one feature of Leiningen, but I was planning on nixing that feature anyway

20:22 brehaut: technomancy: thanks

20:22 methods: loc = lines of code ?

20:22 technomancy: methods: 50,000 lines of code

20:22 give or take

20:22 methods: hm it's going after the embedded market ?

20:22 technomancy: I guess

20:23 brehaut: lazybot: $heval (read "1")::Integer

20:23 methods: what's wrong with hotspot ? doesn't it have massive jit optimizations...

20:23 technomancy: it can perform native-code AOT that cuts launch time in half, though overall it's still a fair bit slower.

20:23 hotspot is like a bazillion kLOC

20:23 and hotspot can't AOT to native code

20:24 methods: yea i really wish it supported warm up profiles for the jit runtime

20:24 brehaut: still potentially useful for desktop apps

20:24 technomancy: avian can take clojure 1.2 boot time down to 0.3s; I'd imagine it could do even better with 1.3 since they were planning on loading less at boot for android

20:25 anyway, I'm just surprised because it basically came out of nowhere

20:25 brehaut: technomancy: what is your 1.2 boot time? (for a relative comparisons)

20:25 methods: is there any plans to support dispatch on return type ?

20:25 technomancy: brehaut: on the machine he was using it was 0.6s with client hotspot iirc

20:26 brehaut: oh sure

20:26 methods: the JVM does not provide a facility to do that

20:26 methods: and its only infrequently useful compared to other dispatch models

20:27 methods: yea it just allows you to not need to type the extra code at times

20:27 brehaut: perhaps if dnolen's core.logic and associated type engine plays out well it might get added?

20:27 methods: why would the jvm not support it ? like haskell it could be compile time ?

20:27 bendlas: wow, avian is free software

20:27 brehaut: because the JVM doesnt support a lot of things that are useful for non-java languages? haskell suppots TCO at compile time, but the JVM doesnt

20:27 bendlas: how nice, thanks for the tip, technomancy

20:27 methods: what about llvm's java front end ?

20:28 ^ I mean in comparrison to avian

20:28 brehaut: methods: additional inference engines are hard to get working nicely in the presence of subtyping

20:28 methods: what do you mean by tco ?

20:28 brehaut: tail call optimisation

20:29 methods: yea that's what i figured but wasn't sure

20:29 but why would tco be related to return type inference ?

20:29 brehaut: its not; its just an example of something that haskell has that would be nice but because the jvm doesnt have it, we dont have it

20:29 methods: yea i mean it's the same problem that language that compile directly to c have when they want to support tco right ?

20:29 brehaut: (simulating it muddies interop)

20:30 thats a can of worms

20:30 GCC supports TCO for instance

20:30 methods: ah it has special stuff for it ?

20:30 brehaut: it just plain does it with the right flags

20:30 technomancy: it's funny that avian claims to be "a lightweight alternative to Java"

20:30 rather than an alternative to hotspot

20:32 methods: there was this dialect of c i saw once that was made for all these reasons and made for compilers to output to

20:32 brehaut: GHC for a long time targeted C-- as its output language

20:33 JVM bytecodes are much higher level than C however

20:33 they have classes baked right in for instance

20:33 methods: as far as i know ghc still does the llvm backend or whatever isn't as fast yet

20:34 brehaut: GHC has a number of backends, it uses its own native code one by default though i believe

20:34 mneedham: hey - trying to understand how to dynamically create a symbol - I then wanted to write an assertion that it worked and I thought this one would be ok -> (is (= (symbol ":foo") :foo)) - but it isn't - must be missing something?!

20:34 methods: yea i mean but still your runtime could support some more advanced features on top of the bytecode right ? or is hte main goal to not have anything like that for speed ?

20:34 brehaut: mneedham: :foo is a keyword

20:35 ,(type (symbol "foo"))

20:35 clojurebot: clojure.lang.Symbol

20:35 mneedham: oh so I want to create a keyword instead?

20:35 brehaut: ,(= (keyword "foo") :foo)

20:35 clojurebot: true

20:35 brehaut: correct

20:35 mneedham: ah!

20:35 so anything beginning with a : is a keywrod

20:35 is that right?

20:35 brehaut: correct

20:35 ::foo is a namespaced keyword

20:35 ,::foo

20:35 clojurebot: :sandbox/foo

20:36 brehaut: ,(keyword "mymythicalns" "foo")

20:36 clojurebot: :mymythicalns/foo

20:36 mneedham: ah

20:36 didn't know you could do that

20:37 bendlas: what's the correct way to propose a feature with a done implementation, for inclusion in clojure?

20:37 ticket + pull request?

20:37 brehaut: mneedham: if you are defining heirarchies or similar you definately should namespace your keywords

20:37 bendlas: ticket with attached patch?

20:38 brehaut: bendlas: sign the contributers agreement, post your intentions on the mailing list and then an issue on dev.clojure.org might be created

20:38 bendlas: clojure core is conservative on what it accepts and contrib is in a reshuffling phase, and not accepting many (any?)new libs at present

20:39 bendlas: i know, but it's just an improved version of clojure.repl/dir

20:39 thanks

20:40 brehaut: bendlas: start with http://clojure.org/contributing if you javem't seen it

20:41 bendlas: I have, just not signed yet, due to inconvenience of faxing

20:41 brehaut: bendlas: international mail agrees

20:41 technomancy: clojurebot: fax machine is http://achewood.com/index.php?date=11222006

20:41 clojurebot: In Ordnung

20:42 brehaut: technomancy: win

20:42 bendlas: analogous mail? oh boy ...

20:43 technomancy: brehaut: my super power is to be able to recall relevant web comics for any given situation.

20:43 brehaut: arrows!

20:43 technomancy: it's up there with Mr. Furious and the Shoveller

20:43 brehaut: hehe :)

20:43 bendlas: :D @ comic

20:45 brehaut: what the hell is wrong with twitter today

20:46 tomoj: they're running clojure now? :D

20:47 (nah, not for the frontend, and the stuff that is clojure is workin great I bet..)

20:47 brehaut: heh

20:47 tomoj: wonder if they even have any

20:48 stuartsierra: I think they use Scala a bit.

20:48 brehaut: they have backtype?

20:49 i read an infoq thing or similar that claimed theyve got quite a bit of scala now

20:49 tomoj: but I wonder how long it would take for backtype code or its progeny to start affecting twitter.com

20:49 brehaut: i recon it will start effecting their bottom line

20:50 i found it to be way better analytics than google analytics for my site

20:54 the failwhale was better when it didnt occur inside requests for json

20:57 tomoj: what is it, ascii art, or they give you html back, or..?

20:58 brehaut: i can only see the html if i look in the webkit inspector; the page is empty

20:59 methods: yea i would think this is basically defmulti for ruby ? https://gist.github.com/d78805b13870b6570a9c

21:01 brehaut: not quite

21:01 theres only one dispatch function for a multi (put that in your initializer), and then the add_dispatch method takes a value for match not a fn

21:02 methods: well my matcher can do anything it wants to test the passed in values and then if it returns true then i call the given body of code... actually that would call every single method that matches .. and each method has it's own

21:02 tester.. instead of just 1 tester that produces the args to test against

21:02 brehaut: thats more general than a multimethod

21:02 and slower again

21:02 methods: wow that was messy way to say that.. let me try again.. instead of 1 test function that produces the arguments used for dispatching

21:03 brehaut: dispatch is now O(n)

21:03 methods: hm and it's not O(n) before ?

21:03 brehaut: whereas multimethods could be much faster O(log n) ?

21:03 methods: well yea i mean O(n) because you have n matchers

21:03 brehaut: exactly. you have to test each matcher function until one matches

21:03 methods: i can make it work more like clojure's approach

21:03 brehaut: of course

21:03 methods: yea but what if you wanted that ?

21:04 $ ./test.rb

21:04 I heard quack

21:04 :]

21:04 brehaut: most people would call that a 'rules engine' or something

21:04 and you run into clause ordering problems

21:05 methods: hm

21:05 well yea in this case you just run them all

21:05 brehaut: eg, if i added class BlueDuck < Duck; def quack; "blue quack"; end; end;

21:05 methods: what happens if you define a multi method that has the same arguments of something already defined ? does it over ride it ?

21:05 brehaut: i think i screwed that up

21:06 i believe so

21:06 methods: well adding a class would'nt matter i think what you mean is you added another tester function you run in the problem of which one do you hit first ? and since it's a hash it's not even ordered.. then again ruby 1.9 has ordered

21:06 hash's

21:06 brehaut: theres still some ordering on multis i think, but its less significant than having full logic for each test

21:06 yeah thats what i meant

21:06 methods: yea but you still run into ordering problems in clojure too right ?

21:07 brehaut: its less of an issue when you are testing values

21:07 with comparison

21:08 methods: hm but why ? i mean it's just based on the order y ou define your matchers

21:10 well that example is what i meant earlier when i said instead of using a switch statement

21:10 brehaut: becuse there is exactly one transformation between arguments and dispatch value. each dispatch value can only have one function associated with it

21:10 and its an isa? test

21:10 methods: cause that lets you add matches later

21:10 brehaut: a switch statement is not late bound

21:18 icey: do any of you use amazon's simpledb with clojure?

21:24 brehaut: icey: http://www.clojure-toolbox.com/ lists two libraries for simpledb, rummage and sdb so i presume there are some people using it

21:27 icey: brehaut: i'm using a fork of the sdb library from there (https://github.com/bapehbe/sdb) but it's not behaving the way the examples & tests do, so I figured I'd see if there were people using it so I could ask them if I was missing something obvious. Thank you though :)

21:27 I'll try out rummage and see if that works a little better

21:30 brehaut: by the way, "A brief overview of the Clojure web stack" was amazing

21:30 brehaut: thanks :)

21:51 methods: how's that ? https://gist.github.com/21e3aed658edd7b0f785

21:58 brehaut: methods: still greenspunned

21:59 methods: yes I know :] I can't magically add it .. oh wait let me hack up the vm really fast :]

22:00 amalloy: methods: i wrote a whole vm while you were doing that. decided to call it nop

22:00 methods: lol

22:00 brehaut: amalloy: is it metacircular?

22:00 methods: what ?

22:01 lol fill me in here...

22:01 amalloy: http://www.esolangs.org/wiki/Nil

22:02 Scriptor: methods: http://en.wikipedia.org/wiki/NOP

22:02 amalloy: my implementation is basically the same but i changed the name to NOP

22:03 methods: no matter what defmulti has to run at runtime right ? there is no way to do it at load time cause the arguments can be of any type ?

22:03 at any time..

22:03 I'm just doing this to see the trade offs or benefits

22:03 I'm wondering now how this shiny little class can help my existing code get out of some kind of trap

22:04 or spaghetti'd class's as Rich HIckey put it

22:05 brehaut: methods: once again, if you need late bound decisions over multiple values, then it will help

22:08 cemerick: I think the ML is teetering on the brink at this point.

22:08 :-(

22:09 brehaut: cemerick: icey was asking about rummage earlier; thats your simpledb lib right?

22:09 cemerick: yup

22:09 dnolen_: cemerick: ? seems the same as usual to me :)

22:09 cemerick: dnolen_: it's actually taken a serious turn downwards in the past 2-3 weeks IMO.

22:10 There needs to be a designated community manager or…something. I need to go read some Clay Shirky, etc.

22:10 icey: come find me tomorrow, I'm toast for tonight

22:11 dnolen_: cemerick: really? current crop of threads seem like the usual fare. The only serious downturn was Steve Yegge thread.

22:13 cemerick: I've long since stopped reading any Ken Wesson post that isn't actually answering someone's question.

22:17 Scriptor: cemerick: what do you consider to be the discussion going off the rails, just when it goes off topic?

22:18 what about non-clojure talk in #clojure when there's no question being asked?

22:26 amalloy: hah, fun times. i solved http://4clojure.com/problem/104 with no parens or curly braces

22:31 ischyrus: When I start Leiningen I get this message: "IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character"

22:32 what would cause that?

22:37 methods: hm so clojure is lazy like haskell ?

22:40 hm the transactional memory reminds me of atomic variables that you can use in device drivers

22:46 dnolen_: methods: Clojure is not lazy, but it does make heavy use of lazy sequences.

22:46 methods: ok i guess I'll figure that out later

22:47 dnolen_: methods: atomic variables are probably more like atoms in Clojure.

22:47 methods: hm ?

22:49 dnolen_: methods: can you coordinate changes between two atomic variables ?

22:49 methods: not sure

22:49 dekuderp: I have a vague problem, and I can't really figure out how to solve it in lisp

22:50 dnolen_: methods: it doesn't sound like it from the pages of Linux Devices Drivers that google barfed up. sounds more like Clojure atoms.

22:50 dekuderp: I want to create a function that handles events, but I don't really know how to

22:52 amalloy: (fn [event] (println event)) is pretty much all you need?

22:52 methods: dnolen_: yea idk i know it reduces down to like a machine instruction or something that is atomic ..

22:53 dekuderp: (fn [events] (call-function (:function-handler (first events) (first-events)) is more of what I want to do

22:53 dnolen_: methods: yes, an particular instruction is guaranteed to be atomic on that reference. STM is quite a bit fancier - more like DB transaction you can coordinate changes between many references.

22:54 dekuderp: so the function-handler would be a reference to the function(s) which should be called given the changes that the event represents

22:54 methods: yea i mean underneath though it has to use locking anyway right ?

22:55 dekuderp: basically I want to make it so that someone else can plop in a new event-type, encode the functions to call in the event-type, and never have to modify the event handling function

22:55 for*

22:58 methods: brehaut: obviously you could still use defmulti beneficially without needing to bind it lately ? i mean what if you had a physics lib and defined a bunch of collision types like [:sphere,:plane] I could picture that all being

22:58 done in the same area without needing to late bind it from other places ? or is there something better for that then ? and where does the isa? test ever happen ? based on my implementation i never called anything that was testing

22:58 types .. i simply tested that special = desired value ... but that's not the same as the type of an object ..

23:00 dekuderp: something like a basic event system ? event.register("some event name"){ /* code to get invoked on the event */ } .. later .. event.publish("some event name") ?

23:01 amalloy: dekuderp: sounds like you want to talk to methods about using multimethods

23:01 methods: depends on if he wants multiple handlers to listen for the same event

23:02 dekuderp: yes, I would like multiple methods listening for the same event

23:02 multimethods you say?

23:02 methods: does clojure offer any kind of classes ?

23:03 if not from the little I have read you'd want to create a state that holds your events and handlers and then some functions to publish/subscribe

23:03 dnolen_: methods: multimethods separate hierarchies from dispatch, you can define your own hierarchies w/o involving types. Clojure doesn't do = to match multimethods, it uses isa?

23:04 methods: at least that's all i could think of right now and I never wrote 1 line of clojure

23:04 dnolen_: (derive ::car ::automobile)

23:05 methods: ^ I've defined a relationship w/o actually creating an actual type.

23:05 methods: I don't get where isa? is used though.. (defmulti encounter (fn [x y] [(:Species x) (:Species y)])) that basically looks like it's yanking :Species out of a hash (def b1 {:Species :Bunny :other :stuff}) ..

23:05 dnolen_: method: you also have deftype/record, but they offer a tiny subset of what you might be used to coming from traditional OO langs.

23:06 methods: so clojure supports building blocks then i guess kind of like scheme ?

23:06 (not that I even know what scheme offers)

23:07 dnolen_: methods: sort of except that Clojure ships with a lot of meaningful interfaces, you reuse as much as you create.

23:08 methods: so where in this implementation would there be an isa? test ? https://gist.github.com/21e3aed658edd7b0f785

23:08 dnolen_: if _pattern == pattern

23:08 methods: hm wait a second.. so then what does isa? actually do ?

23:09 tufflax: Does anyone know how I can speed this up? dnolen_, amalloy told me you might know :P http://pastebin.com/bVHRKaKz

23:09 dekuderp: wait what does "::" represent in clojure so I can google it

23:10 jsnikeris: Hi all. Fairly basic question here. How can I avoid the repitition found in the last few lines of the following gist? e/at is a macro found in Enlive where a series of selector/transformation pairs are written like so: https://gist.github.com/1091232

23:10 dnolen_: methods: there a lot of hardwire behavior in multifn. Collections needs to be traversed checking isa? on each element. multifn have lot of optimization logic to make this stuff fast.

23:11 tufflax: dekuderp A keyword that begins with two colons is resolved in the current namespace (The Reader, clojure.org)

23:11 methods: isa? to me sounds like a.class == Something though ? but in this case it looks like it's just testing 2 scalars to be equal ?

23:11 amalloy: jsnikeris: because at is a macro, the only way to avoid repetition in it is to write another macro that expands into an invokation of (at) that's more to your liking

23:12 dnolen_: tufflax: sorry not feeling like optimizing code at the moment, but I can tell you that you need type hints for those asets to perform well.

23:12 jsnikeris: amalloy: ah OK

23:12 tufflax: ok, dnolen_ :)

23:13 dnolen_: tufflax: my advice to stop a moment a figure out some minimum operation on arrays, discover what is required to make them fast outside your problem.

23:14 amalloy: dnolen_: one of these days i'll need to write fast arithmetic operations for myself, and then i can stop telling people to ask you

23:14 dnolen_: tufflax: your code should trounce the Python once you've sorted that out.

23:16 methods: not isa? looks at the hierarchy, but the Java class hierarchy and a global tag hierarchy (or a custom one if you've provided it)

23:17 methods: wow I'm confused now

23:17 I mean :Bunny to me just looks like a non mutable string or something

23:18 dnolen_: methods: you can establish relationships between fully namespaced keywords. (derive ::bunny ::animal)

23:18 (isa? ::bunny ::animal) => true

23:18 methods: what about the case where you want to define a handler regardless of the order of the arguments ? like you want to define the same handler for [:Bunny,:Lion] and for [:Lion,:Bunny] but obviously you want to be able to reference

23:18 the correct one in your handler ...

23:20 dnolen_: methods: return a set from your dispatch fn, your fn will get the arguments in the right order.

23:20 methods: I guess at that point they'll probably just tell you to always order it the same .. or sort it first and define your callbacks in the sorted way

23:20 dnolen_: methods: you could of course stop speculating and start writing some Clojure ;)

23:21 methods: oh , this is bigger though , I'm trying to understand usage of them and how it could help my existing code

23:21 i really want to understand the benefits of this approach over classical oo styles and apply it

23:22 when you said , "return a set from your dispatch fn" what did you mean ? It's already returning [(:Species x) (:Species y)] is there a way to sort that quickly or something ?

23:28 dnolen_: methods: https://gist.github.com/1091247

23:28 methods: (into #{} [x y])

23:28 what is that ?

23:28 dnolen_: methods creating a set

23:29 methods: so a set has no order basically ?

23:29 dnolen_: methods: no.

23:29 Scriptor: methods: right, it's the mathematical definition of a set, an unordered collection of unique elements

23:30 ,(cons 2 #{1 2 3})

23:30 clojurebot: (2 1 2 3)

23:30 Scriptor: scratch the unique part

23:31 wait

23:31 ,(conj 2 #{1 2 3})

23:31 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection

23:31 Scriptor: ,(conj #{1 2 3} 2)

23:31 clojurebot: #{1 2 3}

23:31 Scriptor: unscratch the unique part

23:32 dnolen_: methods: https://gist.github.com/1091247

23:32 ^ hierarchy w/o types

23:33 methods: yea just weird that ::car is never defined or anything

23:34 i guess it really doesn't have to be defined ?

23:35 I'm just not sure what (derive) would do then besides allowing 1 thing to look like another ?

23:35 it wouldn't actually like extend any type of functionality would it ?

23:36 hm so you could use vectors or sets and define methods for both ? I assume then you need to order your defmethod's from most specific to least..

23:37 dnolen_: methods: no.

23:37 you can define them in any order.

23:37 scottj: methods: why do you always add a space before your "?" ?

23:37 methods: idk I'm nuts..

23:38 I guess I like it to stick out

23:38 scottj: methods: ok you're pretty consistent about it

23:39 methods: lol it's funny though cause I type it something like? and then go back and add a space... I guess my brain believes the ? belongs to the sentence not the word.. or I just want it to stand out more or something.. idk..

23:39 dnolen_: yowza: http://arxiv.org/abs/1107.3539

23:39 methods: s/something/sometimes

23:39 lazybot: <methods> lol it's funny though cause I type it sometimes like? and then go back and add a space... I guess my brain believes the ? belongs to the sentence not the word.. or I just want it to stand out more or sometimes.. idk..

23:39 methods: what's up with that ^ ?

23:40 scottj: you used s/...

23:40 methods: WOW!

23:40 Scriptor: lazybot detects that and actually does the substitution

23:40 methods: yea that rocks !

23:40 I'm going to add that to my bot right away .. actually that would be a good plugin in your client perhaps ..

23:40 scottj: would be nicer if it highlighted the change

23:41 methods: yea you could do that with unicode i think

23:41 scottj: or just bolding/coloring format strings I think irc supports

23:42 methods: \u0002

23:43 that's for bold

23:43 should be really easy to add that to the bot http://oreilly.com/pub/h/1953

23:44 does it also support /g and other options ?

23:45 what about backrefs ? lol .. hopefully it doesn't allow me to inject variables names or call a method in the replacement portion..

23:51 Scriptor: going through the lazybot source, it's...interesting

23:51 methods: oh it's public ?

23:51 Scriptor: methods: yep, https://github.com/flatland/lazybot/tree/master/src/lazybot

23:51 https://github.com/flatland/lazybot is the main repo

23:53 brehaut: Scriptor: comparing lazybot and clojure bot is particular interesting

23:54 s/e b/eb/

23:54 lazybot: <brehaut> Scriptor: comparing lazybot and clojurebot is particular interesting

23:54 methods: does clojure support native regex testing like you might see in perl ?

23:55 brehaut: (re-seq #"[a-c]+" "aabcedfeaaba")

23:55 ,(re-seq #"[a-c]+" "aabcedfeaaba")

23:55 clojurebot: ("aabc" "aaba")

23:55 methods: cool

23:55 brehaut: for instance

23:55 but res are not fns (for performance reasons)

23:55 methods: I'm trying to remember how to match any character and then right after that match anything except that character... i don't think backrefs are available in the search string right away

23:55 fns ?

23:56 brehaut: ifn specifically; anything callable like a function

23:56 (map (juxt class ifn?) [inc [] (symbol "foo") :foo "str" #"re" {} #{} ()])

23:57 ,(map (juxt class ifn?) [inc [] (symbol "foo") :foo "str" #"re" {} #{} ()])

23:57 clojurebot: ([clojure.core$inc true] [clojure.lang.PersistentVector true] [clojure.lang.Symbol true] [clojure.lang.Keyword true] [java.lang.String false] [java.util.regex.Pattern false] [clojure.lang.PersistentArrayMap true] [clojure.lang.PersistentHashSet true] [clojure.lang.PersistentList$EmptyList false])

23:59 amalloy: #"(.)((?!\1).)" probably works, methods

23:59 &(re-seq #"(.)((?!\1).)" "aabb")

23:59 lazybot: ⇒ (["ab" "a" "b"])

Logging service provided by n01se.net