#clojure log - Mar 03 2009

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

0:27 arohner: is there any way to say "this" when defining a function with multiple arities?

0:28 I would really like to say (defn foo ([a b] (bar a b)) ([a] (this a nil))

0:31 cp2: you can just say foo

0:31 hiredman: ^-

0:32 cp2: ,(defn bar [a b] (prn a)) (defn foo ([a b] (bar a b)) ([a] (foo a nil))) (foo "a" "b")

0:32 clojurebot: DENIED

0:32 cp2: eh

0:32 you get the idea

0:32 lol

0:32 durka42: or use a Y combinator ;)

0:34 cmvkk: no defn?

0:34 ,(defn foo [] 1)

0:34 clojurebot: DENIED

0:34 hiredman: no def, defn uses def, so no defn

0:35 cmvkk: ah.

0:37 cp2: what does defn- use

0:39 hiredman: run macroexpand on it

0:39 cp2: bah

0:40 dont have anything clojure related on this fresh install

0:40 hiredman: ~def defn-

0:40 cp2: should fix that :)

0:40 what

0:40 it went to re-find

0:40 oh

0:40 hiredman: gah

0:40 cp2: nevermind

0:40 well, yeah

0:40 revisions are off

0:40 but it was close

0:41 i see

0:41 still uses defn

0:41 hiredman: they shouldn't be

0:41 that is really annoying

0:42 ah

0:42 the url is broken

0:43 ~def defn-

0:48 arohner: ,(macroexpand '(defn- foo [x] (* x x)))

0:48 clojurebot: DENIED

0:48 arohner: anyways, the point is that I don't want to write foo again

0:48 I want it to refer to the same function with a different arity

0:49 hiredman: uh

0:49 I am pretty sure we solved that

0:50 (defn foo ([a b] (bar a b)) ([a] (foo a nil))

0:50 durka42: you can do something like this: (def f (fn g ([a b] nil) ([a] (g nil nil))))

0:51 if you really don't want to mention the fn's real name

0:51 hiredman: this is an idiom used all over core.clj

0:51 ~def max

0:51 for example

0:52 cmvkk: why was my first thought "they should just use apply there instead of reduce since max can take any number of arguments"

0:52 no cmvkk, that is not how it works

0:53 that is not how it works at all

0:53 hiredman: haha

0:53 that would truely be magic

0:53 arohner: hiredman: how does your example solve that?

0:54 durka42: arohner: what are you trying to do? why can't you use the function's name?

0:54 arohner: durka42: I shouldn't have to repeat myself

0:55 durka42: your example works, but I think there should be an easier way

0:55 hiredman: arohner: you want (foo a) to call (foo a nil) yes? that is what your example indicated

0:55 that is what my example does

0:56 arohner: that's what my original code did. the point was that I didn't want to repeat the name foo

0:56 it's just a DRY issue

0:57 hiredman: that is just silly

0:57 arohner: how?

0:57 durka42: a macro could solve it

0:57 cmvkk: it would be nice if recur worked that way i guess but it makes sense that it doesn't

0:57 hiredman: because at some level you must repeate your self, or split the function into two

0:58 arohner: hiredman: this makes sense to me: (defn foo ([a b] (bar a b)) ([a] (this a nil)))

0:59 or to make it simpler: (defn foo ([a b] (bar a b)) ([a] (recur a nil)))

0:59 cmvkk: i do that now in some code i'm writing, with a macro that wraps over an fn

0:59 it just calls the fn 'prev' every time

0:59 hiredman: (def foo (fn this ([a b] (bar a b)) ([a] (this a nil)))

0:59 arohner: cmvkk: I assume recur doesn't work because the two different arities are two different functionss as far as java is concerned

0:59 cmvkk: yep, that seems to be the case.

1:01 definitely a case of (defmacro defnt [name & body] `(def ~name (fn ~'this ~@body))) though

1:05 durka42: (let [recurr foo] (defn foo ([a b] nil) ([a] (recurr nil nil))))

1:06 cmvkk: i don't think that would work.

1:06 durka42: nevermind, that doesn't work

1:06 it works if foo is already defined...

1:06 doing it at the repl deceived me

1:08 cmvkk: hmm, i wonder if tricky rebinding would allow me to do mutual recursion without having to use atoms.

1:08 hiredman: ...

1:08 why not use trampoline?

1:09 cmvkk: hmm...trampoline is only for tail recursion though right?

1:09 hiredman: true

1:09 cmvkk: this would be mutual the-wrong-kind-of-recursion.

1:09 that i want to do, i mean.

1:10 hiredman: ew

1:10 durka42: whee

1:10 (letfn [(bar ([a b] nil) ([a] (recurr nil nil))) (recurr [& args] (apply bar args))] (def bar bar))

1:10 cmvkk: heh

1:10 cp2: ok, now i know where people get the stereotypes for lisp having excessive parens

1:11 one liners like that :)

1:11 even then thats not too bad

1:11 durka42: that would be so much better if it were indented

1:11 cp2: yeah

1:11 cmvkk: chat rooms are decidedly bad environments for complex data structures.

1:12 lisppaste8: durka42 pasted "more palatable?" at http://paste.lisp.org/display/76403

1:13 hiredman: ,(pl inc $ inc $ inc $ 0)

1:13 clojurebot: 3

1:14 cmvkk: are you including libraries besides the normal one?

1:14 ,(doc pl)

1:14 clojurebot: "([& forms]); replaces a $ b with (a b) walking right to left replaces a � b with (comp a b) left to right ?a with (uncurry a) left to right ?a with (flip a) left to right"

1:14 hiredman: yes

1:15 cmvkk: those symbols are all garbled in my chat, by the way

1:15 hiredman: unicode

1:15 cmvkk: i assume that's because i'm using a stupid chat client

1:15 hmm, does clojure do okay with unicode?

1:16 hiredman: java is all unicoded up

1:16 so so is clojure

1:16 cmvkk: i'm gonna start writing all my code in hangul...that way i don't have to worry about name collisions

1:16 hiredman: are you korean?

1:17 durka42: ,(let [? "snowman"] (.replace ? "w" "?"))

1:17 clojurebot: "sno?man"

1:17 cmvkk: no, i just took the language in college.

1:17 hiredman: my parents are english teachers over there

1:18 cmvkk: oh oh

1:18 i want to do that, actually.

1:18 hiredman: :(

1:18 cmvkk: heh, it's bad?

1:18 hiredman: for me

1:18 cmvkk: what for?

1:18 hiredman: many people do it so it cannot be that bad

1:19 cmvkk: well that's hopefully the case

1:20 hiredman: my personality and the korean cultural obsession with foriegners don't jive

1:21 gotta watch out cause in the last four months the won has really tanked against the dollar

1:22 cmvkk: yeah that's true, well every currency is tanking

1:22 i'm not looking to make it rich, being employed at all would be nice

1:22 fresh out of college with a degree in linguistics and no work experience, i'm not exactly going to find a programming job here in america or something

1:22 so i might as well finish learning a foreign language and work at the same time.

1:23 hiredman: I am sure there are plenty of korean software companies looking for people who speak english

1:24 cmvkk: hmm..m

1:27 hiredman: clojurebot: English?

1:27 clojurebot: English is the official language of the universe

1:27 hiredman: ~translate to ko English is the official language of the universe

1:27 clojurebot: ??? ??? ?? ?????

1:31 durka42: ~translate from ko ??? ??? ?? ?????

1:31 clojurebot: English is the official language of the universe is

1:31 slashus2: is

1:44 replaca: hiredman: what does pl stand for?

1:45 hiredman: replaca: pointless

1:45 replaca: hiredman: ahh, ok. not pf?

1:46 hiredman: :|

1:46 replaca: :)

1:47 it's in contrib?

1:47 hiredman: hah

1:47 no

1:47 replaca: your own thing?

1:47 hiredman: yeah

1:47 ~pl

1:47 clojurebot: examples is http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples

1:47 hiredman: hmmm

1:48 that was not what I was expecting

1:48 ~transform

1:48 clojurebot: transform is http://github.com/hiredman/odds-and-ends/blob/8a84e6ddbad9d71f714ba16c3e1239633228a7eb/functional.clj

1:48 hiredman: there

1:48 replaca: cool. looks neat.

1:49 wow, now that's clojure! I can learn from that.

1:53 * durka42 is afraid of the S/K/I/M combinators in kevin.clj

1:54 hiredman: ugh

1:54 don't look at that

1:55 durka42: all right

1:55 i'll go to bed instead

1:56 cmvkk: heh heh

1:56 definitions for a bunch of combinators, and then out of nowhere, (def ? :heart)

1:57 hiredman: heh

1:58 durka42: ,?

1:58 clojurebot: java.lang.Exception: Unable to resolve symbol: ? in this context

1:58 hiredman: I was using jline for a repl at the time and it had problems with unicode

1:58 replaca: The sad thing about ? is that it is unused.

1:59 cp2: i ? you

1:59 replaca: :-(

1:59 cmvkk: and we can't define it here because def is disabled.

1:59 hiredman: I have "&heart;" setup in irssi to change to ?

2:30 brennanc: is there something like comp that goes from left to right instead of right to left?

2:32 hiredman: ,(flip comp)

2:32 clojurebot: #<sandbox$flip__7102$fn__7104 sandbox$flip__7102$fn__7104@1712a80>

2:33 brennanc: thanks, how do I find where flip is?

2:33 hiredman: heh

2:33 flip is not part of clojure

2:34 sorry, it is something I wrote

2:34 ~transform

2:34 clojurebot: transform is http://github.com/hiredman/odds-and-ends/blob/8a84e6ddbad9d71f714ba16c3e1239633228a7eb/functional.clj

2:34 hiredman: source is there

2:34 "->" is sort of like that

2:34 ,(-> 0 inc inc inc)

2:34 clojurebot: 3

2:36 brennanc: my thinking is when you have a long string of function compositions it's much easier to work with it in a post-fix notation like forth or factor

2:36 hiredman: ,((flip comp) inc println) 1)

2:36 clojurebot: #<core$comp__3945$fn__3947 clojure.core$comp__3945$fn__3947@1c390b8>

2:36 hiredman: hmmm

2:36 ,(((flip comp) inc println) 1)

2:36 clojurebot: 2

2:37 hiredman: brennanc: definately take a look at "->"

2:37 brennanc: will do, thanks

2:39 hiredman: I think comp actual works ok for those situations too

2:39 brennanc: it saves you from the parentheses but it's still more natural to work left to right

2:40 hiredman: http://github.com/hiredman/clojurebot/blob/6452d7353b60a33bcb0adc04d9fab25cdd0b98c4/hiredman/clojurebot/tweet.clj#L12

2:40 stuff bubbles up through the function

2:42 brennanc: (-> "abc" .toUpperCase ,, (.replace ,, "B" "-"))

2:42 what are the 2 commas?

2:42 hiredman: dunno

2:42 cmvkk: just placeholders.

2:42 hiredman: commas are whitespace

2:43 they mean nothing to the compiler

2:43 brennanc: weird, wonder why they are there

2:43 cmvkk: they're placeholders

2:43 hiredman: to help understand what "->" is doing I guess

2:43 cmvkk: to mark where the object would be in that function call

2:43 brennanc: ahh

2:44 hiredman: :(

2:44 cmvkk: i don't think it's very useful to do that though

2:44 to each their own i guess

2:45 hiredman: I was using "," to seperate stuff out when I first started using (cond ...)

2:45 brennanc: the "functional programming" in the "programming clojure" book is tough. Not sure if that is just because I'm not used to lisp or if it will get easier with time.

2:46 cmvkk: i try not to ever use commas. i figure if i get used to them, i'll just end up being more confused when i see someone else's code that doesn't use them.

2:48 hiredman: ,(pl (?map (replicate 3 range $ 3) call � (?map inc)))

2:48 clojurebot: ((1 2 3) (1 2 3) (1 2 3))

2:49 brennanc: what's with the funky symbols?

2:49 anyone else seeing that?

2:49 hiredman: the unicode?

2:49 cmvkk: yes they mean something apparently

2:49 hiredman: the arrows, the cicle with the line and the interpunc

2:50 brennanc: they part of the token or are they tokens in and of themselves?

2:50 hiredman: the only mean something inside the pl macro

2:51 cmvkk: there's uh...not any point to that stuff other than obfuscation is there?

2:51 hiredman: ?map is a symbol

2:51 brennanc: I'm not even going to bother asking until I'm much further along into my clojrue education. :)

2:51 cmvkk: or maybe that example just seems pointless to me.

2:51 hiredman: pl stands for pointless

2:51 ,(macroexpand-1 '(pl (?map a b)))

2:52 clojurebot: (do ((flip map) a b))

2:52 brennanc: reminds me of "APL, in which you can write a program to simulate shuffling a deck of cards and then dealing them out to several players in four characters, none of which appear on a standard keyboard."

2:52 hiredman: ? is an apl symbol

2:52 no idea what it does in apl

2:53 ,(macroexpand-1 '(pl (?map b)))

2:53 clojurebot: (do ((uncurry map) b))

2:57 brennanc: (-> "abc" .toUpperCase reverse str)

2:57 how do I get the escape characters out of the string?

2:57 ... and the parentheses

2:57 hiredman: ,(-> "abc" .toUpperCase reverse (#(apply str %)))

2:57 clojurebot: "CBA"

2:58 hiredman: :(

2:58 , ,(-> "abc" .toUpperCase reverse)

2:58 clojurebot: (\C \B \A)

2:58 hiredman: (str '(\C \B \A))

2:58 ,(str '(\C \B \A))

2:58 clojurebot: "(\\C \\B \\A)"

3:22 cmvkk: ,*ns*

3:22 clojurebot: #<Namespace sandbox>

4:37 hiredman: http://weblogs.asp.net/podwysocki/archive/2009/02/23/adding-parallel-extensions-to-f.aspx

4:53 djpowell: are any of the people looking at cells online?

4:55 http://blog.sigfpe.com has some interesting stuff about using comonads implement spreadsheet like stuff functionally

4:55 - not recently, in the archives

6:09 Ben`: how can I cast a lazy list to java.util.List?

6:10 I'm trying to use Collections/binarySearch but I get "java.lang.ClassCastException: clojure.lang.LazyCons cannot be cast to java.util.List"

6:10 Chousuke: that means it's not a list, but a lazy seq

6:11 but does a binary search make sense for a list? :/ wouldn't it be really slow.

6:11 anyway, you can force the seq into a real collection: (into [] yourseq)

6:12 Ben`: oh, thanks

6:34 AWizzArd: Chousuke: btw, why (into [] foo) and not (vec foo)?

6:34 is this lazy vs eager?

6:35 Chousuke: AWizzArd: nah, both are strict.

6:35 I think they do the same thing

6:35 (into [] foo) just reads better IMO and I thought of it first :)

7:03 timothypratley: I want to make a state machine whereby I have a number of functions which return a new state and cause me to transition to another function. These functions would only return on transition events - how would I go about blocking for an event in java/clojure?

7:04 analogous to showing a swing dialog and waiting for the result.

7:08 leafw: timothypratley: make a future and grab its output -- and within the future, show your dialog. This will halt execution at that grabbing of the future output.

7:11 you could do this trivially using pmap and a list that contains a single element, the function to exec and wait on.

7:16 timothypratley: even easier, see (doc future)

7:18 timothypratley: Hmmm not sure how to apply that... I was thinking that the state machine would be essentially a group of functions which spin until a change of state event whence they would return the new state to transition to. But I was hoping to do a blocking wait instead of a loop spin. Maybe I'm thinking about it all wrong.

7:24 futures don't really block for an event as such - they just create a thread that will eventually have a value

7:40 cgrand: timothypratley: a BlockingQueue?

7:42 timothypratley: ah of course

7:42 thanks!

8:30 cgrand: Chouser: ok for merging javadoc into repl-utils

8:32 Chouser: cgrand: ok, great.

8:32 do you read all the IRC logs?

8:33 cgrand: I mirror and grep them :-)

8:34 clojurebot: svn rev 1321; fix cast in read-line [issue 82], patch from Chouser/Trolard

8:45 cgrand: Chouser: I move javadoc.clj to repl_utils/javadoc.clj and load it from repl-utils.clj. Ok?

9:17 Chouser: cgrand: oh, sure, that's a good idea. I hadn't thought of keeping the files separate.

9:21 cgrand: Chouser: dcommited!

9:21 Chouser: heh

9:46 cgrand: I'm in no particular rush, but just so you know: I'm not seeing your change.

9:50 * cgrand grmbl dirty index grmbl cannot dcommit grmbl

9:50 Chouser: you know about 'git stash'. not sure if that fixes your situation or not

9:50 I'm no git wiz

9:51 Lau_of_DK: Whats the situation ?

9:52 cgrand: Lau_of_DK: it's ok, everything is fine with git

9:54 Lau_of_DK: Good, I'll calm back down :)

9:54 cgrand: Chouser: yup git stash does the trick (the error message is helpful enough and says to use git stash btw), it's a recurrent problem due to a pb with line separators

9:56 Chouser: hm, interesting. are you on Windows?

9:57 cgrand: yes

9:57 Chouser: but you don't use vim?

9:57 leafw: cgrand: I thought git win devs had solved the line char problem in latest git release.

9:58 cgrand: Chouser: it depends, a mix of eclipse and gvim

9:58 Chouser: ok.

9:59 cgrand: msysgit disabled git svn, so I resort to cygwin's git for git svn and I think that's cygwin automagic EOL conversion that messes everything

9:59 Chouser: gvim usually does pretty well at using the right line endings on a per-file basis, but I have noticed the sources in clojure and contrib both seem to have a mix.

10:00 Hooke: hello

10:00 Lau_of_DK: Hey Hooke :)

10:01 Hooke: hi Lau_of_DK :)

10:02 how r u

10:04 I'm wondering what may be the best IDE for clojure. I've seen a little of enclojure, clojure-mode for emacs and also an eclipse plugin

10:04 Lau_of_DK: Emacs

10:04 Without a doubt

10:04 Im good thanks :)

10:04 clojurebot: svn rev 1322; bytecode-based constants, [issue 78], patch from rwvtveer

10:04 Lau_of_DK: Get Emacs going with Clojure-mode and SLIME, you're set for life

10:10 Hooke: hmm, thanks for the tip

10:10 I've been reading about clojure IDEs here: http://www.ociweb.com/mark/clojure/article.html

10:11 what's the difference between using clojure-mode and swank-clojure? It's a bit confusing, no? :)

10:15 Lau_of_DK: Hooke: its very confusing, look up Bill Clements blog, he's got a very excellent blogpost explaining Emacs, Swank and SLIME in relation to one another

10:16 Hooke: oh, I see. thank :)

10:19 Lau_of_DK: np

10:19 Hooke: its here, right? http://bc.tech.coop/blog/081209.html

10:19 Lau_of_DK: Thats the one

10:21 Hooke: lots of reading to do :)

10:21 Lau_of_DK: Good stuff though

10:21 Hooke: yeah, looks good

10:22 Lau_of_DK: On the same blog you'll find a really easy guide on how to install/setup emacs, but if you want to try something else, try technomancy's clojure-mode on github, it has an installer which is supposed to do all the work for you, Ive only heard good stuff about it

10:23 Hooke: ah, I installed the clojure-mode and saw the clojure-installer command, but didnt dare to use it :D

10:23 Lau_of_DK: It looks safe, it does a few git-clones, and then gives you an example of a configuration, I cant see how I should break anything

10:24 and techomancy is solid in elisp

10:25 Raynes: Oh cool. By saying "Someone should fix issue 82" yesterday, I actually /got/ it fixed.

10:26 Hooke: okay :)

10:26 Raynes: you should claim some credit, then

10:26 Raynes: Totally Hooke :p

10:31 Hooke: ah, the clojure-mode I'd tried is not technomancy's. technomancy's is a fork of it

10:38 duck1123: should we be switching to technomancy's now?

10:38 I'm still using the other one

10:39 Lau_of_DK: Im going with Technomancys, have been for a while

10:39 (doc average)

10:39 clojurebot: Gabh mo leithsc�al?

10:39 Lau_of_DK: Do we have some average calc stuff yet, or is it still (/ (count seq) (apply + seq)) ?

10:40 ayrnieu: (defn average [seq] (/ (count seq) (apply + seq)))

10:40 although you should use 'coll' instead of 'seq'.

10:40 Lau_of_DK: You didnt answer my question, you just pasted my own code... O_o

10:41 ayrnieu: I pasted your own code.

10:41 tashafa: lol

10:41 ayrnieu: It turns out that you can define procedures in this language.

10:41 Lau_of_DK: Yarly ?!

10:42 Raynes: Nevar.

10:42 tashafa: (doc index)

10:42 clojurebot: Titim gan �ir� ort.

10:43 tashafa: (doc index-of)

10:43 clojurebot: excusez-moi

10:43 tashafa: i think 'index-of' should also be part of core

10:43 Lau_of_DK: I gotta jet

10:43 ayrnieu: tashafa - what would it do?

10:44 Raynes: (doc nth)

10:44 clojurebot: Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences.; arglists ([coll index] [coll index not-found])

10:44 Raynes: What's wrong with that?

10:44 Chouser: indexes into collections are used much less frequently in idiomatic Clojure than in, say, javascript.

10:44 tashafa: (index-of 5 [1 2 4 5 0 3]) -> 3

10:44 Raynes: ,(nth [1 2 3 4 5] 5)

10:44 clojurebot: java.lang.ArrayIndexOutOfBoundsException: 5

10:44 tashafa: sorry.. (index-of [1 2 4 5 0 3] 5) -> 3

10:45 Raynes: ,(nth [1 2 3 4 5] 4)

10:45 clojurebot: 5

10:45 Raynes: ^

10:45 Chouser: tashafa: that would require a linear search of the vector -- not someting you want to do if you can avoid it.

10:45 tashafa: true...i figured as much

10:45 Chouser: what would use do with the index once you got it?

10:46 tashafa: i think i had this discussion here a while ago

10:46 Chouser: :-)

10:46 Raynes: find-doc is the most useful thing evar.

10:47 tashafa: Chouser: hmmm... thinking

10:49 Chouser: Every test case i can think of (for the use of index-of), I can now figure out a more elegant way to do it.

10:50 Chouser: great!

10:50 the main functions that use an index on a vector are nth and assoc

10:51 tashafa: hmm.. what about the starting point of a word in a string

10:51 Chouser: if you found the index by a linear search for the value, using nth on it is pointless -- clearly you already know the object you're looking for.

10:51 tashafa: String has a method for that, I believe.

10:52 tashafa: ah got me

10:52 Chouser: ,(.indexOf "Hello" "l")

10:52 clojurebot: 2

10:52 tashafa: i always forget clojure is bolted on Java

10:52 Chouser: so that leaves assoc.

10:52 I suppose you might want to search for a item in a vector and then replace it with a new value using assoc.

10:53 But unless the order is important, that could be done much more efficiently on a set instead -- get, disj, conj

10:53 tashafa: Chouser: Re: if you found the index by a linear search for the value, using nth on it is pointless -- clearly you already know the object you're looking for.

10:54 but what if i want to noo at what nth the value occurs in a seq

10:54 to know*

10:55 Chouser: my point is that knowing that hardly ever helps you

10:55 tashafa: true

10:55 Chouser: I'm trying to think of what you would use that index value *for*, once you got it.

10:55 using it to pass to 'nth' is pretty silly.

10:56 tashafa: yeah... but what if that was your whole application... to find the index of where a pariticular value appears in a seq

10:56 Chouser: I can come up with contrived examples, like the one above -- the order of the items is important, so you want a vector not a set. You want to replace a particular value with another value, or replace a nearby value.

10:56 but I don't know if a builtin function is needed to support such an odd case.

10:57 tashafa: yeah..

10:57 Chouser: in fact, if I was going to do a lot of that, I'd probably keep some index map in sync with the vector so that the lookups could be constant time rather than linear.

10:57 tashafa: forget i brought it up, i lost the discussion the first time around :)

10:57 ayrnieu: tashafa, not everything you want to make use of will be in core. If this particular function were placed in core, it would be in core.clj and not different from what you'd write yourself.

10:58 tashafa: ayrnieu: no doubt, i think core is huge as it is anyways

10:58 Chouser: hm, might be fun to make an "indexed vector" object, that provides constant time lookup.

10:59 ayrnieu: as opposed to vectors, which provide constant time lookup?

11:00 Chouser: constant time lookup of the index when given the value

11:01 ayrnieu: would these map values to lists of indexes?

11:02 Chouser: yes

11:02 rhickey: ,(.index (nthnext (vec (range 100)) 2))

11:02 clojurebot: 2

11:02 Raynes: Orly.

11:03 rhickey: vector/array/string seqs are indexed

11:04 Chouser: oh

11:04 * Chouser closes the vector-map buffer

11:04 * Raynes laughs at Chouser :)

11:06 tashafa: lol

11:06 Chouser: ,(.indexOf '[a b c d] 'd)

11:06 clojurebot: 3

11:06 tashafa: (doc nthnext)

11:06 clojurebot: Returns the nth next of coll, (seq coll) when n is 0.; arglists ([coll n])

11:10 tashafa: java saves the day

11:10 cgrand: apart from java interop (and destructuring) do people use indexing that much?

11:13 tashafa: cgrand: there are probably more elegant ways to do want you need to do if you are using index

11:14 ..or think you need an index of a val in a vec

11:20 but ofcourse there might be some edge cases

11:20 cgrand: I can just think of algorithms that require some kind of hashing (eg hashmaps, bloom filters) or those that require the ability to skip elements to be sublinears (eg KMP)

11:32 Chouser: cgrand: your blog posts are like your lisp code: succinct but full of meaning.

11:35 cgrand: Chouser: thanks

11:52 scottj: So are all the bugs with fully-lazy worked out in contrib and swank/slime? latest compojure uses fully-lazy and I want to upgrade to that, but I don't want my dev environment/libs to break.

11:52 Chouser: I think contrib is good to go.

11:53 I hear swank/slime is working too, though I'm not sure if you need an unusual branch or something.

12:13 scottj: ok, thanks

12:43 Lau_of_DK: ({:id 5, :name "Frank"} {:id 6 :name "Brooks"}) - Lets say I want to go through that seq, and when I hit someone named Brooks, I want to attach another key called age, which has value 25 for instance. Whats the most effecient way to do this?

12:45 Chouser: most efficient would be to keep a map indexed by :name as well.

12:46 Lau_of_DK: how?

12:48 Chouser: if your seq is called 'db', then: (set/index (set db) [:name])

12:48 Lau_of_DK: (doc set/index)

12:48 clojurebot: Excuse me?

12:48 Chouser: doc clojure.set/index

12:49 ,(doc clojure.set/index)

12:49 clojurebot: "([xrel ks]); Returns a map of the distinct values of ks in the xrel mapped to a set of the maps in xrel with the corresponding values of ks."

12:49 Lau_of_DK: Is that new?

12:49 Chouser: no

12:49 or if you just want to work in linear time:

12:49 (for [{nm :name :as rec} db] (if (= nm "Brooks") (assoc rec :age 25) rec))

12:50 Lau_of_DK: in terms of time, what is the above?

12:50 the... set/index

12:50 Chouser: oh, set/index is linear, but then any lookups on it are constant-time

12:50 gnuvince: (doc if)

12:50 clojurebot: Gabh mo leithsc�al?

12:51 gnuvince: ,(doc if)

12:51 clojurebot: "([tst & etc]); "

12:51 gnuvince: That doesn't look right, does it?

12:51 ,(if true)

12:51 clojurebot: java.lang.Exception: Too few arguments to if

12:51 Chouser: (doc if) at a repl says Please see http://clojure.org/special_forms#if

12:51 clojurebot: It's greek to me.

12:52 gnuvince: Chouser: hmm, not in Slime

12:52 Oh

12:52 wait

12:52 yes it does

12:52 wth...

12:52 Chouser: bother. I was hoping to make fun of it again.

12:53 gnuvince: Ah

12:53 It's C-c C-d d

12:54 durka42: that is weird, why does (doc if) say it's a special form when it's really a macro

12:56 Chouser: durka42: that it's a macro is an implementation detail

12:57 it's only been a macro since the lazy assert thing, and I imagine it will go back to being a special form later.

12:57 durka42: ah i see

12:59 Chouser: Similarly 'let' is discussed as a special form, but is currently implemented as a macro in order to do destructuring.

12:59 durka42: and loop

12:59 Chouser: indeed

12:59 jbondeson: the * forms are the true special forms.

13:00 * durka42 is trying to get my head around if using if* to decide whether to output if* or throw

13:01 Chouser: yeah, that's a fun one.

13:01 jbondeson: modifying the if macro was good times...

13:02 you have almost nothing in terms of clojure functionality

13:02 Chouser: right. no gensym, for example.

13:02 durka42: also loop calls destructure, which loops...

13:03 jbondeson: if you modify anything that high up you do lots of calls to the java code

13:03 durka42: i would imagine

13:03 Chouser: also fun is the assert-if-lazy-seq private macro, which does a bunch of work then emits just nil or true as a constant.

13:04 jbondeson: = uses if so you have to use clojure.lang.Util/equiv ... good things like that

13:04 Chouser: this allows the 'if' macro, when compiled, to store only that resulting constant and not have to check the system property ever again and yet still get consistant results.

13:05 durka42: oh, it's a macro

13:05 i was just going to say, doing a System/getProperty on every branch would slow things down pretty quick

13:05 jbondeson: i wonder how bad it would be to move gensym up higher.. heh

13:05 Chouser: well, it's still doing an 'instance?' check on every branch, which is why it's optional.

13:05 Chousuke: durka42: hopefully there is a base case in destructure where it does not loop :P

13:05 jbondeson: initial glaces say: HARD

13:06 guess the only macros up higher are pretty simple...

13:07 Chouser: well, like I said, I assume 'if' will be going back to normal eventually.

13:34 Lau_of_DK: Is there a function for (in-range? 5 0-10) true function ? Or do I make my own

13:38 jbondeson: huh, contains? doesn't work on lists like you'd expect.

13:38 ,(contains? (range 0 10) 5)

13:38 clojurebot: false

13:38 kotarak: ,(some #{5} (range 10)) ; Lau_of_DK

13:38 clojurebot: 5

13:39 kotarak: ,(some #{100} (range 10))

13:39 clojurebot: nil

13:40 jbondeson: ,(contains? (into #{} (range 10) 5))

13:40 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$into

13:40 jbondeson: whops

13:40 ,(contains? (into #{} (range 10)) 5)

13:40 clojurebot: true

13:41 Lau_of_DK: Thanks pappa and jbondeson

13:41 jbondeson: (set ...) would be more concise than (into #{}...)

13:41 weird that contains doesn't work on generic seq's

13:43 kotarak: ,(#(< 1 % 10) 5)

13:43 clojurebot: true

13:43 kotarak: ,(#(< 1 % 10) 100)

13:43 clojurebot: false

13:43 jbondeson: oohh, from the docs contains? will *NOT* perform a linear search

13:43 iiinteresting

13:43 kotarak: @Lau_of_DK sometimes ranges can also be easy. (see above)

13:44 Lau_of_DK: hmmm :)

13:45 that was fancy

13:45 pjstadig: i think i'm pretty close to getting Clojure to share everything with Terracotta

13:45 but i've hit a snag with *in*, *out*, and *err*

13:45 WizardofWestmarc: pjstadig: having to jump through many hoops?

13:46 pjstadig: it's been "interesting" mostly because of some dumb mistakes on my part

13:46 *in*, *out*, and *err* need to be per VM

13:46 WizardofWestmarc: those are just input and output streams yes?

13:47 if so that technically isn't a big deal as you may WANT the defaults to be different per vm/machine

13:47 pjstadig: yeah they need to be per VM values

13:48 but since they are Vars interned into a namespace...

13:48 and the namespace table is shared...

13:48 Terracotta is trying to share the root values of those Vars

13:49 i've thought of a couple of solutions

13:50 I think making the root field for *in*, *out*, and *err* transient would make terracotta do what we want

13:50 but i don't want to make the root of all Vars transient (which is the only option I have in the TC config)

13:51 So I'm thinking I want to introduce a new class TransientVar which has a transient root

13:51 First problem is that Var is final, but I can get around that using TC's class replacement

13:52 second problem is that i'd have to make a bunch of changes to the compiler to support TransientVar, which seems like a path filled with pain

13:53 WizardofWestmarc: I'd say talk to Rich and see if he has any ideas

13:53 since he seems rather interested in getting a strong interconnection between Terracotta and clojure

13:54 durka42: clojurebot: bat signal

13:54 clojurebot: /summon rhickey

13:54 WizardofWestmarc: haha

13:55 * hoeck guesses that lots of people want clojure+terracotta

13:55 WizardofWestmarc: oh certainly, I know I will at some point

13:55 just not for a while ;)

13:55 durka42: terracotta does sound really cool

13:56 pjstadig: i'm *that* close (makes really small distance with fingers)

13:56 durka42: how can you test things without *in* *out* or *err*?

13:56 rhickey: pjstadig: if you defn in one VM does TC move the def to others?

13:57 i.e. the fn objects?

13:57 pjstadig: I can see compiled functions in the object cache if that's what you mean

13:57 rhickey: and they work?

13:58 pjstadig: well i think so

13:58 rhickey: amazing

13:58 pjstadig: i've stepped through with JSwat and I see it pulling out the objects

13:58 i just can't get the REPL because of *in*, *out*, and *err*

14:00 one of the tests I want to do is set a root binding and see it propagated to other VMs

14:00 rhickey: right, that's what I'm asking about, specifically a fn

14:00 Raynes: http://stackoverflow.com/questions/563356/which-lisp-should-i-learn read the comments on Greg Hewgill's post.

14:01 rhickey: for the *in* etc for now oyu can hack Clojure source to make roots nil, then rely on repl binding

14:01 pjstadig: ok

14:01 let me try

14:12 d'oh

14:12 NPE in main

14:16 durka42: if the repl is going to bind them anyway, what does it matter if the root bindings are shared?

14:16 pjstadig: yeah i had thought about leaving the root binding nil, but in browsing through the code i thought that wouldn't work

14:17 so of course I went straight for the more difficult solution

14:50 forkingYourIO: are hashmaps BSTs? or hashtables?

14:52 jbondeson: forkingYourIO: it's a trie

14:56 pjstadig: uh

14:56 REPL

14:56 what should I type?

14:58 rhickey: (defn foo [] 42)

15:01 pjstadig: java.lang.IllegalArgumentException: No matching method found: unread for class java.io.BufferedInputStream

15:01 *in* needs to be a PushbackReader i guess

15:01 hehe

15:02 now I got an error that user$foo_3158 is uninstrumented so i guess it compiled the function

15:02 rhickey: That's what I was wondering about - would TC instrument dynamic classes

15:04 pjstadig: updating my instrumented-classes config

15:06 user=> (defn foo [] 42)

15:06 #'user/foo

15:06 user=> (foo)

15:06 42

15:06 user=>

15:09 cemerick: it's like watching the moon landing or something

15:09 kotarak: cemerick: I had several of these moments with Clojure already. :)

15:09 pjstadig: the first thing i tried to type was "What hath God wrought?"

15:10 rhickey: pjstadig: can you tell if foo is available on another JVM?

15:10 pjstadig: hehe

15:10 there's a slight problem...

15:10 when I try to reconnect from to TC I get an error

15:10 cemerick: I've been very intrigued by terracotta since I learned that it's persistent last week.

15:25 fanda: rhickey: there is a problem with latest Clojure SVN version

15:26 rhickey: try running in clojure-contrib: ant test_clojure

15:26 it generates failures and errors

15:26 there is some confusion between "nil" and "()" by the reader/compiler it seems

15:26 also:

15:27 user=> (pop '(1 2 3))

15:27 java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IPersistentStack (NO_SOURCE_FILE:0)

15:27 user=> (peek '(1 2 3))

15:27 java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IPersistentStack (NO_SOURCE_FILE:0)

15:27 -------

15:27 many tests pass when ran in REPL, but fail when loaded it seems

15:28 Lau_of_DK: ,(format "25 percent is written as %d%" 25)

15:28 clojurebot: java.util.UnknownFormatConversionException: Conversion = '%'

15:28 Lau_of_DK: Am I misunderstanding the javadoc or is format broken % ?

15:29 kotarak: Lau_of_DK: just guessing: %% ?

15:29 jbondeson: nuke the second %

15:29 Lau_of_DK: argh :)

15:29 pappa, youre right

15:29 jbondeson: that too

15:29 heh

15:29 good ole escaping

15:35 forkingYourIO: jbondeson: trie? treap?

15:36 jbondeson: forkingYourIO: http://lampwww.epfl.ch/papers/idealhashtrees.pdf

15:37 that's the paper detailing the underlying data type of the PersistentHashMap

15:44 pjstadig: so, connecting a second JVM i get a ClassNotFoundException

15:44 could not find class clojure.core$ns__1868

15:47 Lau_of_DK: Any docs out there on how to work with GET values in Compojure in a semi intelligent way? :)

15:58 pin?

15:58 g

15:59 WizardofWestmarc: you're coming through

15:59 just no one's talking

15:59 Lau_of_DK: Thanks Marc

16:02 * WizardofWestmarc misses his poor h, shakes fist at Freenode.

16:02 rsynnott: did they shorten the nicknames?

16:03 WizardofWestmarc: the max on freenode is one less then my normal handle :P

16:03 cmvkk: do you ever try write a program to solve a problem, and as you work out the implementation the program becomes so crazy that you have to step back and think

16:03 WizardofWestmarc: cmvkk: all the time

16:03 cmvkk: "this is so complicated, i MUST be approaching this solution all wrong"

16:03 Lau_of_DK: Yea, happend just a few minutes ago :)

16:03 cmvkk: but then you can't think of an easier way?

16:03 WizardofWestmarc: and most of the time I'm right and I end up completely redoing the design

16:04 sometimes

16:04 I usually give it a day or three first to percolate

16:04 so I can have one of those shower Eureka! moments

16:04 jbondeson: at that point i hit google and find some dissertaion written in 1954 or something, but nothing else helpful ;)

16:04 cmvkk: heh

16:05 kotarak: cmvkk: I think, this is the usual process of software development.

16:05 jbondeson: just frame your question as a clojure question and Chouser will invariable solve it for you...

16:05 -e+y

16:05 WizardofWestmarc: jbondeson: hahahaha

16:05 so true!

16:10 pjstadig: rhickey: what can be done about classes?

16:11 my first thought was to make the map field of DynamicClassLoader into a static CHM that can be stored in Terracotta, but the compiler doesn't seem to be giving the classes to the DynamicClassLoader after compilation

16:11 plus i don't really know much about this stuff

16:12 i also thought maybe that i could just let clojure recompile the source files when connecting to TC so that it has the classes for each JVM

16:13 even if I did, the class names would probably be different, plus you wouldn't be able to share anything except core objects

16:32 jwinter: LofDK: I think you can need to specify symbols or wildcards in the path that the route is matching against, then use those symbols or the route map

16:34 Lau_of_DK: Ok guys, simple stuff now, in compojure, if the user navigates to 127.0.0.1/?name="frank"&age=22 I want those arguments passed to a function, what do I do, (GET "/*" (myfunc route)) doesnt seem to fly

16:36 danlarkin: Lau_of_DK: Madison handles that quite well, I like to think :)

16:37 Lau_of_DK: Demo?

16:37 btw, (GET "/:action" (main (route :action)))

16:37 that flies

16:37 jwinter: so what's wrong?

16:38 Lau_of_DK: jwinter: that getting to that conclusion takes more than 10 secs due to missing docs

16:38 jwinter: meh, it's a new project. Look at the tests for documentation for now.

16:38 danlarkin: Lau_of_DK: in Madison your view function would take two extra parameters, name and age

16:39 Lau_of_DK: What do you do when theres an arbitrary number of args?

16:40 jwinter: There's a * wild card, you could parse that

16:41 danlarkin: well for an URL that will always take a name and age you'd probably build it like /dan/24/ -- but for an URL with truly dynamic parameters (those that you can't predict) then you can just pull them out of the request hash-map, which is the first argument passed to all view functions

16:41 Lau_of_DK: k

16:42 danlarkin: Are you an Emacs guy ?

16:42 danlarkin: yep

16:42 Lau_of_DK: So - Youve got some interactive repl development going already ?

16:42 danlarkin: indeed

16:42 do you mean with madison specifically?

16:42 Lau_of_DK: Yea

16:42 Madison Square Clabango

16:43 jwinter: compojure's also got a get-params fn that takes a servlet request

16:44 returns a map

16:45 danlarkin: the django-inspired builtin runserver has autoreload functionality, so saving a file and then refreshing the webpage will use the new version

16:45 jwinter: danlarkin: url?

16:45 Lau_of_DK: cool

16:45 danlarkin: jwinter: /Users/dan/Code/madison/ :)

16:46 it'll be up on github soon

16:46 Lau_of_DK: haha

16:49 danlarkin: Real Soon Now(TM(TM)

16:49 replaca: danlarkin: that autoreload feature is the best thing a web dev framework can have!

16:49 danlarkin: replaca: I agree

16:49 replaca: danlarkin: I'm looking forwad to playing with it

16:49 danlarkin: it was one of the first things I built, because trying to build the framework without it was too annoying

16:50 replaca: :-)

16:51 building developer friendly programs consists of two things: eating your own dog food and being really irritable ablout things that aren't the way you like 'em

17:17 Lau_of_DK: Just need a quick pointer - Im in compojure, and Ive computed some data and I want to return a chart - is there a good clean easy-to-use lib available for that?

17:18 hiredman: google charts?

17:19 Lau_of_DK: Its not something you can use locally on your own server is it?

17:34 clojurebot: svn rev 1323; restore list constants as PersistentLists

19:10 danlarkin: sweet, I've got a nice test-runner framework for madison

19:11 walks a file-seq, turns each File into a Namespace, requires it and runs run-tests on it

19:12 and deals with its own classpath issues, so I don't have to add the tests directory to my classpath

20:06 meredydd: When did "#=" arrive?

20:06 And is there now any way to use the reader to process untrusted data?

20:08 durka42: no, but rhickey said it is necessary and planned

20:08 meredydd: okay.

20:08 hiredman: you could look at clojurebot's sandbox

20:08 meredydd: clojurebot allows execution of code anyway

20:08 (although the sandbox is very clever)

20:09 hiredman: yeah, but in a limited way

20:09 which until we get a safe reader might be enough

20:09 Chouser: #=() has been around since early november.

20:11 gnuvince_: What's #-()?

20:11 #=()

20:11 hiredman: does stuff at read time

20:11 durka42: ,#=(prn "hi")

20:11 clojurebot: DENIED

20:13 durka42: Clojure=> (do (prn "run") #=(prn "read"))

20:13 "read"

20:13 "run"

20:13 nil

20:13 gnuvince_: OK

20:13 It's not mentioned in the reader documentation on the website.

20:14 ayrnieu: <Holcxjo> BTW: Why is #= not mentioned ond http://clojure.org/reader#toc2 ? <Holcxjo> Deliberate or oversight? <rhickey> Holcxjo: Deliberate

20:15 durka42: yeah... why is it a secret

20:16 hiredman: because it is likely to be abused

20:16 ayrnieu: *shrug* you've probably seen how people defend the status-quo. If it isn't known, people won't complain when it gets changed.

20:16 hiredman: speak of the devil

20:16 gnuvince_: the radix syntax is not mentioned either

20:16 Another trade secret?

20:16 durka42: radix?

20:16 as in 0x16?

20:17 gnuvince_: ,2r10100101

20:17 clojurebot: 165

20:17 gnuvince_: ,36rzzzz

20:17 clojurebot: 1679615

20:17 hiredman: Huh

20:17 that is most interesting

20:17 gnuvince_: you give a base followed by r followed by digits for that base

20:17 so you can input numbers in base 2 through 36

20:17 replaca: or the unicode character syntax (at least not last time I looked)

20:18 ,\u01df

20:18 clojurebot: \?

20:19 durka42: at the repl that gives me \� and in gorilla \?

20:20 replaca: Those are rendering issues - but I'm no unicode expert

20:20 durka42: unicode says clojurebot is right and vim and my shell are wrong

20:20 ayrnieu: with an emacs irc client, you can M-x describe-char with the point over the pretenders.

20:23 durka42: in vim apparently it is ga

20:24 hum, it is a gorilla bug - vim can display the character fine

20:25 hiredman: gorilla ist still using ruby right?

20:25 durka42: no

20:25 he's using nails

20:25 hiredman: oh

20:25 what about jline?

20:26 durka42: um i don't know

20:27 iTerm can't handle \u01df

20:28 hiredman: might not be unicode by default

20:28 forkingYourIO: are all nodes on the same level always the same color on a red black tree?

21:34 slashus2: I don't understand what is going on in Issue 85.

21:37 kid_meier: has anybody encountered an issue with slime/swank-clojure where upon connecting to the swank server the *slime-repl* buffer is not opened ?

21:42 lisppaste8: Rayne@acidrayne.net pasted "If you read this you will die in 7 days" at http://paste.lisp.org/display/76441

21:49 cmvkk: yeah that happens to me sometimes kid_meier

21:49 but only sometimes

21:50 kid_meier: any clue how to fix it? it is happening for me consistently on Mac OS X

21:50 i have some suspicion it is emacs/slime/swank compat issue but not a guru to find out what it is.

21:50 cmvkk: nope, i don't know anything about all that slime stuff. since it only happens to me sometimes, i've just been ignoring it.

21:50 at least you know now that it's cross-platform?

21:51 kid_meier: ya... i seem to recall this happening awhile ago before on Linux.. updating to all of the development snapshots of the packages worked.

21:51 but doesn't seem to be so easy to get all of those updated packages on Mac..

21:52 eh well, i'll keep playing with it.

21:52 cmvkk: i don't suppose there's a way to open a new *slime-repl* buffer manually or something

21:54 kid_meier: not that I can figure out.

22:02 was able to get it working by rolling back to more conservative version of slime w/ emacs 22.1.1

22:21 jhawk28: What is the difference between let and binding?

22:22 cmvkk: let creates local 'variables'

22:23 binding creates thread-specific bindings for Vars (which you can then change with 'set!')

22:24 so use let to create locals, and use Var when you want mutable globals, basically.

22:24 binding, not Var

22:25 jhawk28: thanks

22:26 I think I understand

22:26 cmvkk: you should probably go read about it on the site, i can't think of a good way to describe it succintly without it being confusing.

22:26 jhawk28: was trying to find it in the prag book

22:27 durka42: binding can only create thread-local bindings for existing vars

22:27 jhawk28: http://clojure.org/api#binding

22:27 durka42: (binding [does-not-exist 3]) => CompilerException

22:28 arohner: binding changes the value of a var inside the scope of the binding call

22:29 ,(do (def x 1) (println "x is " x) (binding [x 2] (println x) (println "x is " x)) (println "x is " x))

22:29 clojurebot: DENIED

22:30 cmvkk: it's dynamically scoped. i don't know why, but lexical vs. dynamic scoping took me a while to grok when i was first learning CL.

22:31 arohner: cmvkk: no, it's lexically scoped

22:31 lexically scoped means you can look at only that section of code and know what the value is

22:31 cmvkk: oh, really?

22:31 arohner: dynamically scoped means it's necessary to know what code outside of your snippet is doing to understand the value

22:31 ayrnieu: ,(binding [repeat (fn [x] [x])] (repeat 1))

22:31 clojurebot: [1]

22:32 cmvkk: for some reason i assumed binding was analogous to setting special variables in CL

22:32 arohner: so if you pretend my example above works,

22:32 set the root value of x to 1

22:33 ayrnieu: cmvkk - CL's let accomplishes has the role of clojure's let and binding.

22:33 cmvkk: no no, this is definitely dynamic scope.

22:33 ayrnieu: yes, it is.

22:33 cmvkk: try this: (def *x* 2), (defn foo [] (println *x*)), (foo), (binding [*x* 3] (foo))

22:34 Vars bound with binding are dynamically scoped.

22:35 arohner: cmvkk: ok, I read the wikipedia article. you're right

22:35 ayrnieu: it's a common distinction. The scheme name for binding is fluit-let; Perl has 'my' lexical variables vs. 'local' dynamic variables.

22:36 cmvkk: yep.

22:36 i forgot you could do it in perl too. I never used 'local' when i was using perl.

22:38 ayrnieu: it's useful in cases like: my $file_contents = do { local $/ = undef; <$fh> };

22:38 (binding [*compile-files*] (load-file "hello.clj"))

22:38 (binding [*compile-files* true] (load-file "hello.clj"))

23:22 cooldude127: i'm pissed off at myself. i JUST discovered clojure.contrib.math after rewriting a fair amount myself

23:23 slashus2: On issue 85, I am trying to figure out if having something like (defn testing testing2 ([x] x) ([x y] y)) is useful.

23:24 rlb: Hmm, I should check and see where the debian clojure package stands...

23:28 slashus2: Any input?

23:30 Chouser: providing arglist docs?

23:32 slashus2: Chouser: It seems to screw up the arglist metadeta?

23:39 durka42: ~source clojure.core/sigs

23:39 Chouser: oh, I see. the only legal interpretations for 'testing2' is a docstring or attrmap, and a symbol's not a legal value for either

23:40 durka42: defn sees that testing2 is not a string, so it doesn't chop it off before calling sigs

23:40 sigs sees that testing2 is not a seq, so it assumes it is the one and only arglist

Logging service provided by n01se.net