#clojure log - Jul 10 2009

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

2:03 thearthur: (partition dropps partial blocks at the end. I need one that doesn't do that

2:03 is this in contirb somewhere?

2:04 ???? (partition 4 [1 2 3 4 5 6 7]) => ((1 2 3 4))

2:05 (my-partition 4 [1 2 3 4 5 6 7]) => ((1 2 3 4) (5 6 7))

2:10 nm found that partition can do this with its pas arg

2:10 (partition 4 4 () [1 2 3 4 5 6 7])

2:24 Raynes: Is there a predicate to check whether or not a sequence is empty?

2:24 arbscht_: ,(empty? [])

2:24 clojurebot: true

2:24 Raynes: Thank you. :)

2:27 thearthur: (push and pop mention working on queues. how do i create a clojure.lang.PersistentQueue

2:33 mrpika: there doesn't appear to be a clojure wrapper for it

2:34 you'd have to use it via java interop

2:35 or conj

2:35 http://markmail.org/message/brvozelsgmr5a3ba

4:01 thearthur: how do i undefine a var from the repl?

4:01 dont want to reaload everything

4:06 Chousuke: ns-unmap should help

4:12 Raynes: Why would you need to undefine a var from the REPL?

7:55 Holcxjo`: I am lost with Java interop. I have a class that has a static class as its member. How do I instantiate that inner class?

8:02 To be specific: I am trying out the Evernote API. The Java demo does: import com.evernote.edam.userstore.*; ... UserStore.Client userStore = new UserStore.Client(...args..)

8:03 I can do (import '(com.evernote.edam.userstore.UserStore)) but anything after that fails...

8:03 com.evernote.edam.userstore.UserStore/Client (. com.evernote.edam.userstore.UserStore Client) (com.evernote.edam.userstore.UserStore/Client. <some arg>) ...

8:04 Any ideas?

8:04 liebke: Holcxjo`: you access inner classes with $, e.g. Class$InnerClass

8:04 Holcxjo`: Oh!

8:04 liebke: yeah, not really obvious :)

8:04 Holcxjo`: Also not in the book I believe...

8:05 It's on http://clojure.org/java_interop if you know what the correct term (inner class) is...

8:05 thanks!

8:06 liebke: no problem :)

9:52 Raynes: I accidentially wrote a faster (apply max ..) :o

10:08 Chouser: I think they're making fun of us. http://lambda-the-ultimate.org/node/3488

10:15 Chousuke: nah :)

10:16 cemerick: Chouser: I think they were aiming at NewLisp

10:16 Chouser: ah

10:16 * Chouser googles NewLisp

10:17 liebke: yeah it doesn't look like it's aimed at clojure, read the paper (pdf) http://jfm3.org/phosphorous.pdf

10:18 Chouser: I guess it was the JVM comments that made me wonder

10:18 Chousuke: I like how their CamelCase convention extends to the paper as well.

10:25 cemerick: Chouser: JVM:lispers :: Microsoft:free-software-advocates

10:25 Chouser: heh

10:37 Raynes: Like parent's tell their children. "Don't mind them, they are only upset because you're so special!"

10:41 Chouser: does anyone have a link to the little outline about new-new plans?

10:42 cgrand: Chouser: http://www.assembla.com/wiki/show/clojure/New_new ?

10:42 Chouser: ah, yes. thanks!

10:44 achim`: oh, the NewLisp presentation has a nice font selection

10:45 does anybody happen to know the monospaced font? :)

10:49 lisppaste8: ceninan pasted "macro/seq practice "dsl"" at http://paste.lisp.org/display/83369

10:49 ceninan: I thought I'd learn some macro-fu by doing something that changes lisp semantics, and not just simple syntax "prettification"

10:49 so I "designed" (lol) something that I thought would be interesting to implement

10:50 anyone familiar with the Icon language?

10:52 cemerick: seems like assert should take an optional failure-msg arg

10:52 Chouser: cemerick: you're playing with assert? Have you seen the new pre/post conditions?

10:52 ceninan: not me, sorry.

10:54 cemerick: Chouser: oh, no -- someone mentioned them to me, but I'd forgotten

10:54 we're on v1.0 + patches for a while, though

10:55 Chouser: oh, ok.

10:56 cemerick: I suppose aggressively tracking head might be a good idea, but that'd take some CI work.

10:57 Chouser: I'm using 1.0 at work myself, but I also haven't touched our .clj code in a while.

10:57 cemerick: it's the only reasonable way to do things atm, but I do certainly loathe upgrade cycles.

10:58 lisppaste8: ceninan annotated #83369 "untitled" at http://paste.lisp.org/display/83369#1

11:00 Chouser: ceninan: it looks like you're mutating !tries in the middle there

11:00 ceninan: Chouser: that part isn't really correct

11:01 the :! should have an optional let form

11:01 Chouser: ceninan: and some minor adjustments to your proposed syntax would make it much easier to implement

11:01 ceninan: I'm all ears :)

11:01 Chouser: looks like an interesting experiment

11:01 well, macros are applied at compile time when the compiler sees a (macro-name ...) form

11:03 so with your proposed syntax, you either need to define 'integer?', 'between?' and '=' as macros, or wrap the whole thing in a macro call that will walk the tree looking for your :! :<- annotations

11:03 ceninan: is it possible to do a macro macro generator?

11:03 Chouser: ceninan: yes

11:03 ceninan: then there could be some sort of "def" for these types of "functions"

11:04 correct?

11:04 Chouser: both the options I described are possible, but neither is particularly simple

11:04 yes

11:04 but writing such a macro is several steps removed from accomplishing your goal -- unless this specific syntax is your goal, I suppose.

11:05 ceninan: not really stuck on the syntax, no

11:05 do you have a simpler proposal?

11:05 Chouser: if you instead wrapped another layer, maybe... (icon-step (integer? (read-line)) :<- ... :! ...)

11:05 then you could define a single macro 'icon-step' that did your heavy-lifting.

11:06 ceninan: hmm, yes - that does sound like a more practical approach

11:06 Chouser: and actually, if you got that working and still wanted to write a 'def-icon-fn' macro, it could produce macros that expand to 'icon-step' forms and your life would be more pleasant. :-)

11:07 ceninan: right :)

11:07 thanks, hadn't thought of that

11:07 Chouser: as with any macro, I'd highly recommend writing out code the code you want your example to expand to before you start trying to write the macro

11:08 ceninan: and that leads to my next question :)

11:08 mccraig: Chouser: are pre/post conds described/exampled anywhere ?

11:08 ceninan: what would be a good structure for the "seq"?

11:10 mccraig: found a description : http://github.com/richhickey/clojure/commit/0ac482878a1dd520cbee2faa0f5f6ab1082ffa76

11:10 Chouser: mccraig: sure! in the commit message. :-)

11:10 there ya go

11:13 ceninan: not sure -- seems like figuring that out is the task you've chosen for yourself. :-)

11:14 ceninan: well, that's true ;p

11:14 thanks a lot for the help!

11:15 Chouser: I'm not quite sure I grok your syntax, but if you get stuck feel free to ask more.

11:16 ceninan: I'll try to figure it out without dealing with the syntax first :)

11:16 thanks again

11:18 (btw, they allow you to react to failure conditions; failure can have different causes, eg '=' have the fail conditions '>' and '<')

11:18 (tbh, I don't really grok it myself yet ;))

11:19 Chouser: ah! hm.

11:20 that makes it sound more like a sort of cond applied to each element of the seq

11:24 ceninan: I'm entirely sure that I follow; the "fail conditions" primary purpose is to produce side effects or change local bindings

11:25 they shouldn't escape to a parent operation

11:25 but like some sort of (loop (cond)), yes

11:25 * ceninan is a newb

11:26 Chouser: I'll be fascinated to see what you come up with. :-)

11:26 ceninan: thanks :)

11:28 ozzilee: Chouser: Forgive me for not just trying it or digging through the changelogs, but... the lazy-xml I have doesn't automatically convert tag contents to strings, instead throwing NPEs. Has that changed?

11:29 Chouser: lazy-xml hasn't changed in ages

11:29 ozzilee: you're talking about when emitting?

11:30 ozzilee: Chouser: Yeah. Something like {:tag :foo :content [5]} throws an NPE.

11:31 Chouser: ah. I don't think I'd noticed that. A contrib ticket and patch for that would be welcome.

11:33 ozzilee: Chouser: Okay, will do. Probably. At some point :-) I need to work on getting some tests going on this mess before I start updating dependencies.

11:34 Chouser: a ticket without a patch would be fine too

11:35 ozzilee: Any recommendations on that front, btw? As far as a testing framework. Fact maybe? It's hard to keep up.

11:35 hiredman: test-is got moved into core

11:35 ozzilee: Chouser: Ok, I'll do a ticket now.

11:43 hiredman: That looks like it will work. Do you use it?

11:43 Chouser: Ticket submitted.

11:43 Chouser: ozzilee: thanks!

11:44 hiredman: ozzilee: nope

11:45 I guess I could write tests for clojurebot

11:45 bleh

11:45 Raynes: I wish I knew Java. :\ I might understand what this :state stuff is all about.

11:45 hiredman: Raynes: it creates a field where you can store state information

11:46 generally a ref or a atom

11:46 Raynes: Oh, like a field in Java.

11:46 ozzilee: Raynes: Except you only get one per proxy object.

11:46 * ozzilee thinks

11:46 hiredman: eh?

11:46 * ozzilee could be crazy

11:46 hiredman: proxy has a .state?

11:46 Chouser: one per gen-class instance

11:47 Raynes: Works for me. :D

11:47 hiredman: yeah

11:47 ozzilee: Er, gen-class. Yeah. That's what I meant.

12:34 eyeris: When I want to use destructuring to bind a symbol to a map key of the same name, e.g. (let [{k :k} my-map] (...)), is there an abbreviated form of `a :a` that assumes the same name?

12:38 hiredman: (let [{:keys [a]} {:a 1}] a)

12:38 ,(let [{:keys [a]} {:a 1}] a)

12:38 clojurebot: 1

12:41 eyeris: Thanks

13:26 ataggart: does anyone have a clear sense of which datastructure manipulation functions are meta-data preserving?

13:27 e.g., conj is, but drop isn't

13:27 Chouser: hm

13:27 I'm under the impression that everything on vectors and maps is supposed to preserve metadata

13:27 ataggart: I know I can just look it up, but I thought there might have been some intention behind the choices that I wasn't aware of

13:29 Chouser: lists and seqs ... well I guess I'm not sure

13:30 it does seem a bit odd that conj, pop, and next on a PersistentList all return PersistentLists, and conj keeps metadata but pop and next do not

13:31 ataggart: also depends on the undelrying type

13:31 ,(:foo (meta (conj (with-meta '(1 2 3) {:foo "bar"}) 4)))

13:31 clojurebot: "bar"

13:31 ataggart: ,(:foo (meta (conj (with-meta [1 2 3] {:foo "bar"}) 4)))

13:31 clojurebot: nil

13:31 Chouser: I wouldn't expect fns that take a non-seq and return a seq (like drop) would transfer metadata from the coll to the seq

13:31 ataggart: but drop does take a seq

13:31 or am I totally bonkers

13:32 Chouser: well, it *can* take a seq, but it can also take any other collection

13:32 ,(drop [1 2 3])

13:32 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$drop

13:32 Chouser: ,(drop 2 [1 2 3])

13:32 clojurebot: (3)

13:32 Chouser: vector in, seq out. I'd be pretty surprised if metadata came through that.

13:34 ataggart: though conj is preserrving, depending on the original type

13:34 Chouser: on the other hand, I'm surprised that pop on a PersistentList loses the metadata. PL in, PL out, just like conj. I wonder if pop's behavior there is intentional.

13:34 ataggart: right

13:34 I don't know if this is valid, but I tend to think of a seq as a series of things, and wouldn't expect the same metadata on all elements

13:35 ataggart: heh this is funny:

13:35 (:foo (meta (conj (with-meta (seq [1 2 3]) {:foo "bar"}) 4)))

13:35 ,(:foo (meta (conj (with-meta (seq [1 2 3]) {:foo "bar"}) 4)))

13:35 clojurebot: nil

13:35 Chouser: vs. collections like map, vector, and PersistentList where I tend to think of the collection as stable and the metadata applying to the whole thing

13:35 ataggart: ,(:foo (meta (conj (with-meta (seq '(1 2 3)) {:foo "bar"}) 4)))

13:35 clojurebot: "bar"

13:35 ataggart: though you can with-meta a seq

13:35 as above

13:35 Chouser: hmph.

13:36 ataggart: which makes sense in the idealized abstract ... thing

13:36 where functions might only care about seqiness

13:37 maybe this is just an area for improvement ;)

13:37 Chouser: ,^(next (cons 1 '#^{:my :meta} (2 3 4)))

13:37 clojurebot: {:my :meta}

13:37 Chouser: there metadata is kept on the individual cell of the persistentlist

13:37 ataggart: aha! I was lookig for that with-meta reader macro

13:38 Chouser: it's not exactly the same as with-meta

13:38 ataggart: orly?

13:38 Chouser: it applies metadata to the form read by the reader and passed to the compiler

13:39 with-meta happens at runtime and applies to the collection at that point

13:40 ,(meta #^{:my :meta} (conj [1 2] 3))

13:40 clojurebot: nil

13:40 Chouser: ,(meta (with-meta (conj [1 2] 3) {:my :meta}))

13:40 clojurebot: {:my :meta}

13:40 ataggart: hm, still not grokking why that's different

13:41 Chouser: in the first example, the *form* (conj ...) has metadata. Could provide a line number, type hint, etc. In this case, the compiler doesn't know what to do with :my and it gets thrown away

13:41 ataggart: oh is that first one appplying the metadata to the conj, and not the result of the conj?

13:41 Chouser: right

13:41 ataggart: excellent

13:42 Chouser: ,(meta #^{:my :meta} [1 2 3])

13:42 clojurebot: {:my :meta}

13:42 ataggart: ,^(next (cons 1 '#^{:my :meta} [2 3 4]))

13:42 clojurebot: nil

13:42 Chouser: but in the case of a literal collection like this, the compiler transfers the metadata from the read form onto the resulting collection

13:43 ataggart: ,^(next (cons 1 '#^{:my :meta} (seq [2 3 4])))

13:43 clojurebot: {:my :meta}

13:43 Chouser: right! because 'next' on a vector returns a seq -- a different thing

13:44 but next on a seq returns a list returns a list, and the metadata is kept per-cell on a list

13:44 but next on a list returns a list, and the metadata is kept per-cell on a list

13:46 but the mental model I'm defending here doesn't explain pop (or next) on a list, so either there's a bug or I'm just wrong.

13:47 ataggart: letting this all marinade

13:47 Chouser: hm

13:47 actually, list in general is a bit confusing

13:48 conj on a list preserves metadata, cons does not?

13:48 oh, cons on a list returns a Cons not a PersistentList

13:49 danlarkin: +1 for metadata review

13:49 ataggart: ,^(conj '#^{:my :meta} '(1 2 3) 4)

13:49 clojurebot: {:my :meta}

13:49 ataggart: ,^(butlast '#^{:my :meta} '(1 2 3) )

13:49 clojurebot: nil

13:49 ataggart: I'm guessing butlast has the same issue drop does

13:51 this is coming up for me because I''m splitting a url up into its segments via re-split, then adding meta-data to that seq, but the later manipulating that seq

13:51 using butlast

13:51 Chouser: I use PersistentLists so rarely for data in Clojure.

13:53 ataggart: this is the problem I have:

13:53 Chouser: gah. pop on vector also loses metadata

13:53 that can't be right

13:53 ataggart: ^(butlast (with-meta (re-split #"/" "foo/bar/baz") {:my :meta}))

13:54 ,^(butlast (with-meta (re-split #"/" "foo/bar/baz") {:my :meta}))

13:54 clojurebot: java.lang.Exception: Unable to resolve symbol: re-split in this context

13:54 ataggart: d'oh

13:54 well that woudl output nil

13:54 Chouser: yeah, I'm with you

13:54 I don't know if butlast or drop-last should preserve metadata or not

13:55 ataggart: so I've been doing stuff like (with-meta (butlast orig-seq) {meta orig-seq))

13:55 Chouser: but I would be shocked if pop losing metadata on vectors is intentional

13:55 ataggart: pop is next, right?

13:55 Chouser: no

13:55 ataggart: oh

13:55 ioening the src

13:55 Chouser: it is for lists, but for vectors and queues it pops off the right

13:55 ataggart: *opening

13:55 ah yeah

13:55 Chouser: ,(pop [1 2 3 4])

13:55 clojurebot: [1 2 3]

13:56 Chouser: so that would be ideal for you case

13:56 a thing the naturally grows and shrinks on the right

13:56 but is walked left-to-right

13:56 ataggart: ,(pop (take 3 (iterate inc 1)))

13:56 clojurebot: java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IPersistentStack

13:56 Chouser: it's a vector. And most modifications to a vector preserve metadata (conj, assoc)

13:57 ataggart: so I'd need to turn the seq from re-split into a vector...

13:57 smells funny

13:57 Chouser: nah, that's common

13:57 re-split doesn't know what you're going to do. And it can be lazy (though I don't think it is).

13:57 so a seq is a natural return type

13:58 but you don't care about lazy and want to treat it as a vector. that's exactly what 'vec' is for

13:58 ataggart: hmm fair point

13:58 Chouser: *but* the only way I know to drop an item off the end of a vector is 'pop'

13:58 and that still loses your metadata. :-P

13:58 ataggart: butlast works fine except for the losing of metadata

13:58 heh

13:59 Chouser: right, but butlast is O(n) and more importantly an argument could be made that it should not preserve metadata.

13:59 maybe. I dunno.

14:00 ataggart: the O(n) is a good point

14:00 ya, swithcing to vectors

14:00 Chouser: vec is O(n) but it would happen once and then you can pop/conj in O(1) as needed

14:00 ataggart: regardless of the metadata issue

14:00 right

14:01 Chouser: and I'm haveing a very hard time imagining the argument for dropping metadata on vector pop

14:01 ataggart: maybe Rich can clarify the rules for when manipulation functions should be meta-data preserving

14:01 Chouser: unless there's some other fn for dropping off the last item of a vector. I can't think of one.

14:01 ataggart: pop sounds right

14:02 Chouser: huh

14:02 oh

14:03 ataggart: this is all coming up because I'm porting (sort-of) a rest framework I originally wrote in java. got tired of just toying with clojure.

14:03 REST, not '(rest ) :)

14:04 Chouser: :-)

14:04 ,^(pop (with-meta (conj [1 2 3] 4) {:my :meta}))

14:04 clojurebot: {:my :meta}

14:04 Chouser: ,^(pop (with-meta [1 2 3 4] {:my :meta}))

14:04 clojurebot: nil

14:04 Chouser: it's a bug

14:04 ,(class (with-meta [1 2 3 4] {:my :meta}))

14:04 clojurebot: clojure.lang.LazilyPersistentVector

14:05 ataggart: ah finally a good excuse to register with assembla

14:05 Chouser: the metadata gets lost in the transition from LazilyPersistentVector to PersistentVector

14:10 ataggart: do we need to send in a CA in order to be able to post tickets in assembla?

14:11 well, sicne I'd also want to try writing a patch, I guess so. nvm

14:13 Chousuke: you can use the "support" thing to report a bug I think.

14:14 but you need to be a project member to have full access to the ticket system, and that requires a CA

14:14 ataggart: yup, I'll do the CA thing once I have access to a printer

14:14 and stamps

14:21 chouser: btw thanks for the help

14:22 Chouser: ataggart: sure. I'd still be pleased to have a high-level description from rhickey about when metadata should be preserved vs. not

14:24 cemerick: shouldn't all objects be able to support metadata in JDK7?

14:24 (totally orthogonal to the preservation issue)

14:24 Chouser: cemerick: how? got a link?

14:24 cemerick: Chouser: well, invokedynamic allows for method injection, or so I thought.

14:25 Chouser: huh. like add a method to Integer that ... closes over a variable that points to the metadata?

14:26 technomancy: that's the first I've heard of invokedynamic supporting something like that

14:26 cemerick: right...totally naievely, I'd think with-meta would just swap out another meta method

14:26 technomancy: Rich seemed to imply that it's mostly for supporting dynamic OOP on the JVM

14:27 danlarkin: I think it's to aid in languages where foo.bar might mean "get instance variable bar" or "call instance method var"... or something

14:27 s/var/bar

14:27 cemerick: sorry, the terminology is "interface injection": http://challenge.openjdk.org/projects/mlvm/subprojects.html

14:27 not technically part of invokedynamic, but still part of JSR292

14:29 Chouser: seems like a stretch to me

14:29 doesn't sound like it would let you change the class of an existing object

14:29 hm

14:29 cemerick: Chouser: no need to change the class -- just adding the IMeta interface is enough.

14:30 Chouser: no, you need a place to store the meta value

14:30 cemerick: right, so the method that is injected along with the interface would just be a thunk that closed over the meta value

14:31 Chouser: but now you're talking about a new method per instance

14:31 technomancy: cemerick: that's pretty awesome

14:31 cemerick: *shrug* Better than not having any metadata on java.lang.Objects at all.

14:31 Chouser: and classes like Integer are final -- could you still inject a method?

14:32 cemerick: that I don't know. I *think* so, as I don't think there's anything special about a final class (e.g. the final keyword is for javac's benefit...?)

14:33 alternatively, there could be a single meta() method that looked up the meta value in a global WeakHashMap (if you were worried about creating a meta method per instance)

14:33 hiredman: cemerick: if that was true then you could just use the asm library to generate your own bytecode that ignores final

14:33 ataggart: yes final is for the compiler, and hotspot

14:34 thats why you can change final fields via reflection

14:34 hiredman: final means different things in different places

14:34 cemerick: hiredman: I'm always on shaky ground w.r.t. final and bytecode issues.

14:34 Chouser: you could use WeakHashMap today

14:35 just have meta and with-meta fns use that instead of (or in addition to) .meta() and .withMeta() methods.

14:35 cemerick: Chouser: right, but I presume Rich wouldn't put a big honking switch in the meta fn.

14:36 Chouser: I think his resistance would actually be more toward the WeakHashMap -- he's actually got plenty of bit switches.

14:37 cemerick: well, who knows, maybe pushing a new method into an object on every with-meta will end up being cheap :-)

14:37 Chouser: we can hope!

14:38 hiredman: that would be rather down the line I imagine

14:38 Chousuke: http://blogs.sun.com/jrose/entry/interface_injection_in_the_vm reading this, it seems it would be done for classes, not objects.

14:38 hiredman: (since clojure targets java 5)

14:39 cemerick: hiredman: I think we're going to see some conditional execution macros and a lot of bifurcation as soon as invokedynamic is available (perhaps as an option in a JDK 6 update)

14:39 Chouser: Chousuke: anything about field injection there? :-)

14:40 hiredman: cemerick: I remain skeptical

14:40 Chouser: bifurcation of .. the clojure sources?

14:40 cemerick: Chouser: no, just different code paths for invokedynamic

14:40 Chouser: oh

14:42 cemerick: Chouser: John Rose indicates that traits are a core use case for interface injection, so yeah, injecting fields is on the table

14:42 e.g. an IMeta trait

14:42 (which carries a meta field)

14:43 Chouser: clojure.test confuses me

14:43 oh...

14:50 ataggart: is there a way to add doc to a defstruct?

14:56 Chouser: (defstruct #^{:doc "this is foo"} foo :a :b)

14:57 Chousuke: Maybe I should bookmark this JRose blog :)

14:57 fun stuff

14:58 Also, the JVM apparently has an interesting method to check for null pointer derefs.

14:59 eyeris: Is there a standard function in the api for flattening a list?

15:00 Chousuke: basically, it assumes that they don't happen doesn't do any checking (probably not true for some cases, but anyway). Instead, it traps them when they happen, recovers, and recompiles the code at runtime to include a null check :P

15:00 hiredman: cute

15:00 Chousuke: +and

15:00 eyeris: there is flatten in contrib

15:01 eyeris: Thanks

15:03 cemerick: Chousuke: yeah, I've subscribed jrose's blog :-)

15:04 Let's hope he stays hale, hearty, and healthy. Quite a positive voice in the jvm circus.

15:05 ataggart: chouser: yup that did it. thanks.

15:06 Chouser: ataggart: so you're planning on filing a bug, sending in a CA, and writing a patch, right?

15:07 ataggart: I woudl but it'll take me a few days to get to a printer. feel free to open it in the meantime.

15:07 Chousuke: hmm

15:08 ,(remove coll? (tree-seq coll? seq [[1] {1 2} [2 [5 4]] 3]))

15:08 clojurebot: (1 1 2 2 5 4 3)

15:08 Chouser: ataggart: I wouldn't want reduce your incentive to register and contribute. :-)_

15:08 Chousuke: nice!

15:09 ataggart: hehe fair enough, just didn't want to hold you up.

15:11 Chouser: ataggart: you don't need a CA to file an assembla ticket, though. Just use the Support tab

15:11 ataggart: ah excellent. doing it now.

15:14 Chousuke: I have to say, searchable menu entries in OS X Cocoa apps are sheer genius.

15:14 fffej: with the latest release, i'm having a little problem using zip_filter.clj. I get this message "descendants already refers to: #'clojure.core/descendants in namespace" - any ideas? I see in the source it is excluding descendants, so I'm a little confused

15:15 Chouser: fffej: you're doing (use 'clojure.contrib.zip-filter) ?

15:15 Chousuke: I wasn't able to find the menu item for adding an RSS feed in mail but then I remembered the help system, wrote "add rss" into it and it instantly showed me what I wanted <3

15:15 fffej: chouser: I'm doing (ns mynamespace (:use [clojure.contrib.zip-filter]))

15:16 Chouser: Try (:require [clojure.contrib.zip-filter :as zf]), then use zf/descendents or whatever

15:16 cemerick: Chousuke: whoa, I had *no* idea Mail could consume RSS!

15:16 Chousuke: cemerick: heh

15:17 fffej: chouser: thanks, that works

15:17 texodus: How can I determine if a something is an array?

15:18 Chouser: texodus: are you sure you want to be using an array? If you're trying to determine membership, usually a set or map works better.

15:18 texodus: yes, im positive - im writing a specific Writer proxy that needs to dispatch differently on byte arrays

15:19 ozzilee: Chouser: Submitted a patch for lazy-xml. Pretty simple, unless I missed something.

15:19 texodus: so, proxy to a defmulti - but then how to determine an array ...

15:19 ,(class (to-array [1 2 3]))

15:19 clojurebot: [Ljava.lang.Object;

15:20 texodus: ,(= (class (to-array [1 2 3])) [Ljava.lang.Object)

15:20 clojurebot: Unmatched delimiter: )

15:20 texodus: clearly doesnt work

15:20 ataggart: ,(Class/isArray (class (to-array [1 2 3])))

15:20 clojurebot: java.lang.IllegalArgumentException: No matching method: isArray

15:20 Chouser: ,(some #{(byte 2)} (into-array Byte/TYPE (map byte [1 2 3])))

15:20 clojurebot: 2

15:20 ataggart: hmm

15:21 ,(.isArray (class (to-array [1 2 3])))

15:21 clojurebot: true

15:21 hiredman: !

15:21 clojurebot: CLABANGO!

15:21 hiredman: beat me to it

15:21 ataggart: lol

15:21 texodus: ,(. (class (to-array [1 2 3])) isArray)

15:21 clojurebot: true

15:21 texodus: bingo

15:21 thanks alot

15:22 Chouser: wow, I completely misread the question

15:22 eyeris: I am taking a first stab at writing a macro. I have a seq of bindings I want, but (let) wants a vector. How can I create a vector from that seq?

15:23 hiredman: vec

15:23 Chouser: I had an extra "in" in there. "if a something is in an array"

15:23 ataggart: ,(vec (seq [1 2 3[))

15:23 clojurebot: Unmatched delimiter: )

15:23 ataggart: ,(vec (seq [1 2 3]))

15:23 clojurebot: [1 2 3]

15:23 hiredman: or just pass a vector

15:23 like most other bindings

15:25 Chouser: ozzilee: thanks! BTW, issues have moved to assembla, and code to github. See http://clojure.org/patches

15:26 ozzilee: Chouser: Oh, contrib too? Neato.

15:26 Chouser: yep. We're trying to create as long a list of out-of-date project hosting services as possible

15:26 ozzilee: Chouser: Heh no kidding :-)

15:27 eyeris: Is %1 valid inside (fn) as it is inside #()?

15:27 Chouser: eyeris: no

15:27 Chousuke: ,((fn [] %1))

15:27 clojurebot: arg literal not in #()

15:27 Chousuke: ,((fn [] %))

15:27 clojurebot: arg literal not in #()

15:27 Chouser: although the error case has changed a bit recently

15:28 Chousuke: hmm

15:28 old clojure? :P

15:28 should simply be an unresolved symbol.

15:28 Chouser: right, to support :post

15:28 eyeris: Is there a compliment for (keyword)?

15:29 hiredman: :post?

15:29 eyeris: name

15:30 ataggart: ,*clojure-version*

15:30 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}

15:30 Chouser: hiredman: ((fn [] {:post [(= % 5)]} 6)) ==> java.lang.Exception: Assert failed: (= % 5)

15:30 wow, that's a whole lot of parens

15:31 hiredman: Chouser: oooooo

15:31 Chouser: and various other grouping chars

15:31 hiredman: no :pre yet?

15:31 Chouser: :pre is there too, but doesn't need %

15:31 hiredman: ah

15:38 eyeris: Is :as not allowed in the defn arg list?

15:38 Chouser: right.

15:40 ,(let [foo (fn [& [a b :as all]] [a b all])] (foo 1 2 3))

15:40 clojurebot: [1 2 (1 2 3)]

15:40 Chouser: but you can do that, I suppose

15:41 eyeris: Yeah, I've been using it in let/

15:42 Chouser: sure, but you see I'm doing it in fn args there, just destructuring the "rest" part

15:42 eyeris: Oh, you mean I could do (def foo (fn... and use the destructuring there

15:42 Chouser: or just (defn foo [& [a b :as all]] [a b all])

15:45 eyeris: I see. I tried that, but I was doing it wrong :/

15:45 Chouser: nested destructuring can get a bit convoluted

15:46 eyeris: I am using it with a nested map, so I was trying (defn foo [& {{:keys [a b]} :sub-map} :as my-map] ...)

15:46 But it shoudl be (defn foo [& {{:keys [a b]} :sub-map :as my-map}] ...)

15:50 zakwilson: I'm trying to decide between Haskell and Clojure for a project. I know Clojure better, but Haskell seems like it will make FRP easier and I intend to make fairly heavy use of that.

16:04 ataggart: chouser: what clojure implementation code were you looking at when we were talking about pop and meta-data?

16:04 I haven't quite grokked how to get from clj function defs in clojure.core over to clojure java

16:05 hiredman: ataggart: when you see a java method call

16:05 ataggart: I'm referring to clojure's java implementation

16:05 e.g., where pop, conj, etc are implemented

16:06 hiredman: yeah

16:06 ~def pop

16:06 so you look at the pop method in the RT class

16:07 ~def c.l.RT

16:07 ataggart: yes, but chris was referring to something earlier andni'm trying to find out exactly what he was looking at

16:08 in order to write a bugfix patch

16:08 hiredman: oh

16:08 pardon

16:08 ataggart: np, I should have been more clear

16:10 guille_: hi there

16:18 ataggart: how does one add further comments on a ticket in assembla?

16:19 hmm must be because I'm not CA'd yet

16:20 guille_: if i'm implementing a interface in a single file, should I use the last name of the namespace (using same convention as java), that's the interface name, or the whole package name in :name too?

16:24 ataggart: chouser: I figured it out. pop is meta-data preserving, but it's just that we see the meta-data associated with that sublist, which in the example is nil.

16:25 ,(meta (pop (conj (with-meta '(1 2 3) {:my :meta}) 4)))

16:25 clojurebot: {:my :meta}

16:27 ataggart: ,(meta (pop (with-meta '(1 2 3) {:my :meta})))

16:27 clojurebot: nil

16:27 ataggart: because (meta '(1 2)) is nil

16:28 so ticket #149 should probably be marked as invalid

16:42 eyeris: Will someone here help me figure out where I am going wrong with this macro? http://pastebin.ca/1491100

16:44 If I load it into the repl and use macroexpand, it just prints out the input, without any expansion.

16:44 That must be a sign that I've used defmacro incorrectly, but I can't figure out how

16:46 Chousuke: hm

16:47 eyeris: The (one) and (two) in the example usage are incorrect, but that isn't what the exception refers to.

16:49 Chousuke: you can't pass runtime values to a macro

16:49 you need to call it as (with-map-bindings {:one 1 :two 2} (+ one two))

16:50 eyeris: I see.

16:51 Is there a way to pass a runtime vector to let instead of a literal vector, so that I could write that macro as a fn?

16:51 Chousuke: a macro is a function that takes clojure code as its parameters, and does not evaluate them; so, in your example, you're passing it a plain symbol :)

16:51 that would require eval I think.

16:52 but... are you sure you need to do that at all?

16:52 eyeris: I don't *need* to, but I'd sure like to.

16:52 I have a map that has 6 keys, my function uses all of them.

16:52 Chousuke: in which case would you need to pass a binding vector to let at runtime?

16:53 eyeris: I could use :keys [...], but that just feels overly verbose when I am binding them all

16:53 Chousuke: hmm

16:53 eyeris: It also is misleading to me, because when I see :keys [...] I instinctively look at what *isn't* bound from the map

16:54 Chousuke: will simple-map be static?

16:54 eyeris: No

16:54 Chousuke: hm.

16:55 I still don't get your use case though. :/

16:56 you can't bind locals based on runtime values, unless you also generate the code at runtime and use eval

16:56 and that's not what you want to do.

16:57 eyeris: Oh, wait.

16:57 The keys in my map will be static.

16:57 The values will change though.

16:57 Chousuke: in that case there's no problem

16:59 eyeris: I just have to use this map in a lot of functions, so I'd like to write a function or macro that binds the keys to local symbols so that I don't have to write out the destructuring for every function

17:00 Chousuke: just write (defmacro defspecialfn [& body] `(let [{:keys ~'[your keys here]} *the-global-map*] ~@body))

17:00 assuming *the-global-map* will be bound with (binding ...) here.

17:01 otherwise, it *would* be static and the values would not be changing :)

17:02 eyeris: Okay

17:02 I think I understand that.

17:02 Chousuke: alternatively, it could be a ref

17:02 in which case you'd want to do:

17:02 just write (defmacro defspecialfn [& body] `(let [{:keys ~'[your keys here]} (deref *the-global-map*)] ~@body))

17:02 * Chousuke is lazy :P

17:03 Chousuke: forgot to remove the just write.

17:04 note the funky ~' unquote thing there. that needs to be used so that let won't complain about binding to qualified names.

17:04 it also serves as documentation to the reader that the macro introduces local names implicitly.

17:05 eyeris: I think this is one step removed from what I want to do.

17:05 The map I am using is always passed into the function. I don't rebind the global symbol to update the values.

17:07 Chousuke: well, in that case you can add the map name as a parameter to the defspecialfn macro

17:08 eyeris: And, inside the function, that would be a local symbol just like a normal function parameter?

17:08 Chousuke: (defmacro defspecialblock [mname & body] `(let [{:keys ~'[your keys here]} ~mname] ~@body))

17:08 then (defspecialblock *global-map* (do-stuff using your keys))

17:08 eyeris: http://pastebin.ca/1491131

17:09 That is what I am doing

17:09 (dispatcher) returns the next function to pass the state map into

17:10 that function returns the next map to bind to the state symbol

17:10 repeat

17:11 Chousuke: investigate the macroexpansions of these functions, you'll see what kind of code they produce :)

17:16 eyeris: Where does the name of the special block go?

17:16 Chousuke: well, that above thing doesn't actually define a function.

17:16 just a let block

17:16 but you could easily extend it to a defn

17:19 eyeris: This still doesn't make sense, because I can't call it from inside my state loop, because I don't have a symbol for the map outside the state loop

17:20 can't call it = can't call the special fn defined by the macro

17:20 Chousuke: it doesn't define a fn :P

17:21 eyeris: if does if I make if (defspecialfn [fname mname & body] (defn fname `(let ...

17:22 Wait a minute

17:22 I think I got something

17:23 Chousuke: the ` should go before defn, not let.

17:25 http://pastebin.ca/1491144

17:25 I used [] around map-name because giving the binding in a vector to the macro is more idiomatic

17:30 eyeris: I want the map symbol inside the generated fn to always be the same

17:31 Removing map-name from the defmacro parameters and then removing the ~ from before each use of it yields an exception though

17:32 Chousuke: well, of course.

17:32 eyeris: Why?

17:32 Chousuke: because it's passed to defn as the parameter name

17:32 and inside ` it becomes qualified, and qualified names can't be used to bind to.

17:33 if you want to force the name, do ~'whatever

17:34 eyeris: This whole "the macro language is the language" is bs

17:34 Chousuke: hm?

17:34 no it's not.

17:34 a macro must return a data structure.

17:34 which is clojure code.

17:34 eyeris: but it must do so using different evaluation rules

17:35 Chousuke: not really. the only differing thing is that macro parameters are not evaluated

17:35 otherwise a macro is a normal function

17:35 it may look different because of `(foo bar whatever

17:36 but syntax-quote is not restricted to macros

17:36 ,(let [x 1] `(foo bar x ~x))

17:36 clojurebot: (sandbox/foo sandbox/bar sandbox/x 1)

17:37 Chousuke: you could write every macro without syntax quoting

17:38 eyeris: http://pastebin.ca/1491155

17:38 Why is that wrong?

17:38 Chousuke: (defmacro [x] (list 'clojure.core/+ x x)) <- equivalent to (defmacro [x] `(+ ~x ~x))

17:39 hiredman: eyeris: map-name is not specified anywhere

17:39 eyeris: Right, so I have to use 'map-name

17:40 Chousuke: ~'map-name

17:40 clojurebot: map is *LAZY*

17:40 Chousuke: :P

17:40 eyeris: Chousuke so what does ~'map-name evaluate to?

17:40 Chousuke: if you do 'map-name, you will see (quote user/map-name) in the expansion

17:40 hiredman: eyeris: 'map-name

17:40 Chousuke: eyeris: just the symbol map-name

17:40 hiredman: ~ is unsyntax quote and ' is quote

17:40 clojurebot: Alles klar

17:41 hiredman: erp

17:41 Chousuke: eyeris: in other lisps, you'd just write "map-name" without the unquote-quote thing.

17:41 eyeris: but in clojure, map-name will be qualified in that case, and you can't bind to qualified names

17:41 ataggart: eyeris: are you just trying to reimplement (binding [...] ...)?

17:42 Chousuke: to get around this, you unquote a quoted, plain symbol. thus the result is the plain symbol

17:43 compare:

17:43 ,`sym

17:43 clojurebot: sandbox/sym

17:43 Chousuke: ,`~sym

17:43 clojurebot: java.lang.Exception: Unable to resolve symbol: sym in this context

17:43 Chousuke: ,`~'sym

17:43 clojurebot: sym

17:43 eyeris: I get that part

17:44 but you syntax quote the macro to prevent evaluation, right?

17:44 Chousuke: no

17:44 the evaluation is already prevented by the macro expansion.

17:44 hiredman: Chousuke: you kinda do

17:45 Chousuke: well, hm.

17:46 hiredman: you quote the form the form you want to be the result of the macro

17:46 and you use syntax quote because you want all its snazzy features

17:47 eyeris: Yeah, but that form is unevaluated until it is called

17:47 hiredman:

17:47 eyeris: e.g. the defn isn't evaluated before defmacro returns

17:47 Chousuke: eyeris: no.

17:48 well, in a way yes.

17:48 but there's a more fundamental point.

17:48 eyeris: the macro, when called, *returns* the defn form

17:48 as a value

17:48 and then the compiler calls eval on it.

17:48 eyeris: Right

17:49 Normally, to prevent the evaluation of a symbol, you quote it, right?

17:49 (let [x 1] 'x) returns the symbol x

17:49 but (let [x 1] x) returns 1

17:50 s/returns/evaluates to/

17:50 Chousuke: you can also try the following in a repl: (defn f [x] (println x) x) (defmacro m [x] (println x) x) and try (f (+ 1 1)) (m (+ 1 1))

17:51 the former will print 2 and return 2, the latter will print (+ 1 1) and return 2

17:51 (because of the implicit eval)

17:52 eyeris: Right, but inside defmacro, x is not resolved when it is an argument to println

17:52 Chousuke: after that, you can try using syntax-quote on x in both the macro and the function

17:52 eyeris: whereas outside defmacro, it would be

17:53 Chousuke: yes it is resolved.

17:53 it's just that its value is '(+ 1 1)

17:53 not 2, like in the function

17:53 eyeris: erm

17:54 I misspoke

17:54 it is not evaluated

17:55 Chousuke: yes.

17:56 or to make it painfully clear, x is evaluated inside the macro, but when you pass in arguments to the macro, the arguments are not evaluated, and thus the value of x becomes the literal list '(+ 1 1)

17:57 in a similar way, the local x is evaluated inside a function, but also the arguments you pass to the function are evaluated; and (+ 1 1) evaluates to 2, so the value of x becomes 2

17:58 eyeris: Okay

17:59 So

17:59 So 'x in a fn evals to the symbols x.

18:00 Chousuke: yes.

18:00 eyeris: So what does 'x eval to inside a macro?

18:00 Chousuke: the same as in a function.

18:00 to the symbol x

18:01 eyeris: So the syntax-quote function is doing the namespace resolution?

18:01 Chousuke: yes.

18:01 eyeris: Why? What problem does that solve?

18:01 Chousuke: hygiene

18:02 it's more difficult to accidentally introduce names

18:02 that could shadow names in other code.

18:02 very useful for macros, which is why ` is very popular when writing them

18:02 but ` is not restricted to macros

18:03 ,((fn [x] `(x :is ~x :unqualified ~'x)) 5)

18:03 clojurebot: (sandbox/x :is 5 :unqualified x)

18:04 eyeris: So I can write macros without `?

18:04 Chousuke: sure.

18:05 (defmacro add-to-y [x] (list '+ x 'y))

18:05 next (def y 3); (add-to-y 4) -> 7

18:06 because the macro will return '(+ 4 y) which is 7 when evaluated in that context

18:09 the problem comes when you do something like : (defmacro eval-with-y [code] (list 'let '[y 5] code)); (def y 1) (eval-with-y (+ y 10)) -> 15

18:10 however, if you do (list 'let `[y 5] ...), you will get an exception

18:10 because y is qualified and let does not like that.

18:11 so you won't mistakenly override names in the context.

18:12 eyeris: Is there a contrib that function as syntax quote without the ns resolution?

18:12 Chousuke: no.

18:13 but as show, you can override syntax-quote's ns resolution by prefixing the symbol you want to be bare with ~'

18:13 eyeris: I get that.

18:13 That is just plain not intuitive for me.

18:14 Chousuke: well, it's not supposed to be :)

18:14 eyeris: ' = quote

18:14 ~ = unquote

18:14 clojurebot: Excuse me?

18:14 Chousuke: yeah

18:14 eyeris: reversing something should yield the same thing

18:14 erm

18:14 Chousuke: and when you quote a symbol, and unquote it, you get the symbol back.

18:14 eyeris: (inc (dec 1)) == 1

18:15 Chousuke: but see

18:15 ,`'y

18:15 clojurebot: (quote sandbox/y)

18:15 eyeris: Right, but if ~'x evaluates to x, why doesn't it get resolved?

18:15 Chousuke: hmm

18:15 ,`~'y

18:15 clojurebot: y

18:15 eyeris: See

18:15 it's different

18:16 Chousuke: ,`~'sandbox/y

18:16 clojurebot: sandbox/y

18:16 Chousuke: (quote sandbox/y)

18:16 ,(quote sandbox/y)

18:16 clojurebot: sandbox/y

18:17 Chousuke: well, you can just take this behaviour for granted now :)

18:17 it's useful.

18:18 it *is* a bit funky though.

18:18 clojurebot: 0

18:19 Chousuke: but you can think of it as unquoting a quoted form yielding the same form.

18:20 eyeris: It seems to me that syntax-quote must do resolution before any evaluation and simply doesn't recurse into an unquote form

18:21 Chousuke: possibly.

18:21 syntax-quote is a special thing implemented in java, after all

18:21 it has some special semantics.

18:22 but it's undeniably useful, and not at all that difficult after you understand how it works.

18:22 eyeris: For Symbols, syntax-quote resolves the symbol in the current context, yielding a fully-qualified symbol (i.e. namespace/name or fully.qualified.Classname).

18:23 That should be followed by "except when preceded by ~'" or something more complete.

18:24 Thanks for your help

18:24 I'll need a lot more practice, but it's a start

18:28 ataggart: rule 1 of macros: don't write macros.

18:29 Chouser: such a good rule.

19:09 ataggart: chouser: did you see my comments from earlier regarding pop?

19:17 Chouser: I hadn't. But yes, I guess I was failing to describe it.

19:17 glad you figured it out anyway, though.

20:34 newbie: hi, i am iterating pixels on the screen using 2 doseq loops one for x one for y then i cam doing some calculations on the pixels i end up with some valid pixels how can i return a vector of pixels?

20:35 hiredman: newbie: use for

20:37 newbie: but how can i create a vector and add on it like in loop?

20:38 hiredman: vectors can be created with the literal [] or the function vec, or vector

20:40 newbie: yeah but vector is not persisted between iterations so i can add on it

20:41 hiredman: if you are looping, you can rebind names in the loop

20:42 ,(loop [foo 0 r []] (if (= foo 5) r (recur (inc foo) (conj r foo))))

20:42 clojurebot: [0 1 2 3 4]

20:42 newbie: no thats why i am asking is there a way to achive the same effect while using doseq

20:42 hiredman: doseq is for side effects

20:44 newbie: so loop inside loop is my only choice? to iterate x,y coordinates?

20:45 hiredman: for

20:46 ,(vec (for [x (range 10) y (range 10)] [x y]))

20:46 clojurebot: [[0 0] [0 1] [0 2] [0 3] [0 4] [0 5] [0 6] [0 7] [0 8] [0 9] [1 0] [1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [1 8] [1 9] [2 0] [2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [2 8] [2 9] [3 0] [3 1] [3 2] [3 3] [3 4] [3 5] [3 6] [3 7] [3 8] [3 9] [4 0] [4 1] [4 2] [4 3] [4 4] [4 5] [4 6] [4 7] [4 8] [4 9] [5 0] [5 1] [5 2] [5 3] [5 4] [5 5] [5 6] [5 7] [5 8] [5 9] [6 0] [6 1] [6 2] [6 3] [6 4] [6 5] [6 6] [6 7] [6 8] [6 9] [7 0

20:56 newbie: thanks that solved it.

21:11 Raynes: hiredman: Why is :state necessary? The only times I've seen it used are by clojure-generated classes that extend Java classes. http://www.fatvat.co.uk/2009/05/clojure-and-robocode.html being one example. It looks to me like :state could be replaced with any ol' ref.

21:11 hiredman: Raynes: it generally is a ref

21:12 Raynes: I know, but what is the point of it? I'm not really sure why it's needed.

21:12 hiredman: the key point is the is a state per instance

21:12 * Raynes didn't think of that.

21:13 Raynes: So it's primarily for Clojure classes that will be instantiated by Java classes?

21:13 Well, clojure-generated classes.

21:13 hiredman: yes

21:14 Raynes: I've noticed that Stuart's example in Programming Clojure instantiated a Clojure-generated class inside the same Clojure-generated class. That blew my mind for a few minutes. :p

21:14 Thanks.

21:37 Knekk: I am looking for something new to read, related to CS/Programming, in case anyone wants to recommend something they've found enlightening or interesting.

21:37 thanks

21:42 gnuvince: Knekk: SICP?

21:42 Knekk: http://mitpress.mit.edu/sicp/?

21:43 gnuvince: Aye

21:43 hiredman: clojurebot: delicious

21:43 clojurebot: delicious is http://delicious.com/clojurebot

21:43 Knekk: nice, didn't know about it. Thanks :)

21:44 gnuvince: Knekk: as far as CS books go, this one is way high up there.

21:44 Knekk: $114 at amazon, free on the site. Yay

21:44 hiredman: thanks

23:43 flying_spaghetti: anyone can help with a noob question?

23:46 fUD: Greets

23:47 flying_spaghetti: hail

23:50 i seek a clue

23:52 Chouser: go

23:54 flying_spaghetti: well, i am learning clojure, writing a raytracer.. i want to know, is there an easy way to get a list representation of the content of a struct or vise versa

23:54 because i have, e.g. colour structures with members r, g, b, and sometimes it would be nice to apply the same operation to all of them using map

23:55 and then convert the resulting list back into a colour structure

23:55 i am wondering if there is a generic means to do that

23:56 texodus: ,(into {} (map (fn [[_ v]] (+ 1 v)) [1 2 3])

23:56 clojurebot: EOF while reading

23:57 texodus: ,(into {} (map (fn [[_ v]] (+ 1 v)) [1 2 3]))

23:57 clojurebot: java.lang.RuntimeException: java.lang.UnsupportedOperationException: nth not supported on this type: Integer

23:58 flying_spaghetti: oh great thx i will try

23:58 texodus: oh right, struct

23:58 (into {} (map (fn [[_ v]] (+ 1 v)) {:1 1 :2 2 :3 3})

23:58 ,(into {} (map (fn [[_ v]] (+ 1 v)) {:1 1 :2 2 :3 3})

23:58 clojurebot: EOF while reading

23:59 texodus: ,(into {} (map (fn [[_ v]] (+ 1 v)) {:1 1 :2 2 :3 3}))

23:59 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

Logging service provided by n01se.net