#clojure log - Sep 23 2011

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

0:00 ibdknox: unless they assume that no one will use it for more than a few times

0:00 livingston: ibdknox: maybe

1:08 ,(doc partial)

1:08 clojurebot: "([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & ...]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."

1:40 MayDaniel: kkkqwejl;+

1:40 lkxd][

1:40 +

1:41 b

1:41 cb

1:41 #

1:41 companion_cube: so true

1:41 livingston: MayDaniel: your cat may be walking on your keyboard

1:42 companion_cube: or maybe it's his domestic cthulhu

1:42 livingston: companion_cube: lol

3:46 patchwork: hey all, I have a lein project and I want to load some .clj files that live in a wholly unrelated dir. the classpath seems abstracted away, what is the best way to do this?

3:47 when I do (load "/absolute/path/to/file.clj") it fails to find it

3:48 amalloy: probably load-file

3:48 &(doc load-file)

3:48 lazybot: ⇒ "([name]); Sequentially read and evaluate the set of forms contained in the file."

3:51 patchwork: amalloy: that was it!

3:51 thank you

3:51 amalloy: that said, don't do that :P

3:52 patchwork: ha, I thought someone might say that

3:52 I have the path in a config file

3:53 there is a real reason, I am building something that supports building other projects. I want the actual project in an autonomous dir from the framework itself

3:53 but I appreciate the concern : )

3:54 it still may be misguided

4:01 khaliG: &(prn "test")

4:01 lazybot: ⇒ "test" nil

4:02 khaliG: never noticed that it returns a string ..weird

4:05 raek: khaliG: the call returns nil

4:05 but that might not be what you meant

4:05 khaliG: raek, oh. i meant the output in the repl

4:06 patchwork: I took it to mean that it prints out the string with quotes

4:06 yeah

4:06 which is weird

4:06 khaliG: i cant see any reason to use prn then, i'll just use println now

4:07 raek: this is the difference between println and prn

4:07 prn prints clojure data in a form that can be read back by the reader

4:08 patchwork: raek: ah, that could be useful

4:08 raek: so in this case it prints a string literal that can be used in clojure code

4:08 ,(pr-str "foo\"bar")

4:08 clojurebot: "\"foo\\\"bar\""

4:08 raek: ,(prn "foo\"bar")

4:08 clojurebot: "foo\"bar"

4:09 raek: (str should almost never be used to stringify clojure data structures)

4:09 robermann: is read-string's usage related to this topic?

4:10 raek: yes. read-string is the reverse of pr-str

4:10 robermann: ah ok

4:10 khaliG: that's interesting that they're inverses

4:10 robermann: yesterday I stumbled upon: ,(read-string (str \[ "a,b" \]))

4:10 ,(read-string (str \[ "a,b" \]))

4:10 clojurebot: [a b]

4:11 raek: robermann: on 4clojure? :)

4:11 robermann: yes :)

4:11 khaliG: raek, i dont know enough to disagree but i'm curious why it should never be used to stringify

4:11 raek: I happened to stumble on that way of solving the problem yesterday too

4:12 let's assume you want to turn ["foo bar" "baz"] into a string

4:12 ,(str ["foo bar" "baz"])

4:12 clojurebot: "[\"foo bar\" \"baz\"]"

4:12 khaliG: btw doing silly euler problems is a good way to get practice learning clojure.. i learnt a bit more bout lazy seqs after attempting some problems the last coupla days. the only downside is it wastes too much time on pointless exercises

4:12 robermann: raek: darren's solution of problem 74

4:13 raek: ok, that didn't really work as I expected it to

4:13 but if you want to stringify arbitrary data, it won't work for strings

4:13 since they will become something that looks like symbols

4:14 and lazy-seqs just become this mess:

4:14 ,(str (range 3))

4:14 clojurebot: "clojure.lang.LazySeq@7480"

4:14 raek: ,(pr-str (range 3))

4:14 clojurebot: "(0 1 2)"

4:14 khaliG: raek, interesting.. i haven't run into that problem yet. often use something like (str "boom" foo bar " another string) to concatenate bits together

4:15 missing " at the end there

4:15 raek: yes, str works perfectly well to concatenate strings

4:15 robermann: read-string doc: "Reads one object from the string s"

4:15 raek: but not to turn an arbitrary clojure data structure into a string that can later be read

4:16 robermann: not a so useful doc :)

4:16 khaliG: oooh i understand now

4:17 raek: if you want to serialize data, a string should be wrapped in quotes so that it becomes a literal. str does nothing with the string and is the wrong function to use for clojure data serialization

4:18 khaliG: raek, sure that makes sense :)

4:18 raek: ,( 123 "123")

4:18 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn>

4:18 raek: gah.

4:18 ,(println 123 "123")

4:18 clojurebot: 123 123

4:18 raek: ,(prn 123 "123")

4:18 clojurebot: 123 "123"

4:20 robermann: ,(eval (read-string "(+ 1 1)"))

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

4:20 robermann: ops

4:22 khaliG: raek, thanks for explaining

4:23 robermann: thank you

4:25 khaliG: i might just start doing 4clojure too since everyone else is :P

4:30 amalloy: $sed khaliG s/everyone else is :P/it's AWESOME/

4:30 lazybot: <khaliG> i might just start doing 4clojure too since it's AWESOME

4:30 pisketti: haha

4:31 I'd say, don't do it because everyone else is doing it. Do it because it's the most fun you'll ever have programming.

4:32 khaliG: pisketti, true but I do need the practice, half of the time i dont know how to do stuff in the language and i'll be sitting there helplessly

4:34 pisketti: of course you'll need google

4:34 khaliG: to look up docs?

4:36 pisketti: yeah

4:37 khaliG: clojuredocs is pretty nice i must admit

4:44 robermann: khaliG: I'm learning by solving 4clojure problems with 10 lines and comparing them with the 1-line others's solutions :D

4:46 amalloy: of course you can solve the problems however you want, but i usually like the 10-line solution better

4:47 robermann: I noted that I'm using too much loop/recur, maybe I'm thinking still in an procedural/object-oriented way

4:48 amalloy: i learn a lot less writing (comp first reverse) than i do writing (fn my-last [coll] (if-let [xs (next coll)] (recur xs) (first coll)))

4:49 robermann: I see your point

4:49 amalloy: but that's because i know most of the builtins pretty well, and enjoy practice with recursive thinking. if you're learning the builtins but are pretty confident about your low-level problem-solving, (comp first reverse) is a "better" solution for you to find

4:50 (and (comp peek vec) is arguably better)

4:51 robermann: yes, I'm trying to study the API stuff (I was forgetting stuff like interpose, interleave etc!)

4:51 amalloy: anyway, enjoy 4clojure. i'm going to bed

4:51 robermann: ok :)

4:52 goodnight

4:52 have a recursive dream

6:00 pyr: is it feasible to build a clojurescript app and do without the ugly closure look&feel ?

6:17 morphling: pyr: you don't need to use the closure library

6:18 pyr: ok

6:35 michaelr525: hello

6:35 manutter: hey

7:03 r0man: hi, what are people using to replace clojure.contrib.mock in clojure 1.3?

7:05 jaju: I wish to use "case" on the class of an argument (class x) - what should the test expression look like?

7:05 For example - x is a string - java.lang.String does not match

7:05 although (class "x") - say - prints java.lang.String

7:13 raek: jaju: the case constants are not evaluated so you end up comparing with symbols instead of classes

7:13 jaju: you can work around it by having classes instead of symbols in the code: https://gist.github.com/997652

7:15 jaju: another workaround is to do something like (case (symbol (.getName (class "x"))) java.lang.String "It's a string")

7:17 manutter: ,(apropos "map")

7:17 clojurebot: (sorted-map ns-unmap zipmap map mapcat ...)

7:18 manutter: wow, how did I miss that before?

7:18 * manutter is flipping through Stuart Sierra's slides from strangeloop

7:19 manutter: It's embarrassing how much stuff you can learn from Clojure Intro slides

7:22 is # not allowed in Clojure var names? Just saw "#t and #f" as examples of scheme booleans and realized I've never seen # in clj vars

7:22 simonj: manutter: it's reserved by the reader IIRC

7:23 manutter: yeah, sound right now you mention it

7:25 wow, did he really present 214 slides at strangeloop? I'm impressed

7:34 jaju: raek: Thanks, let me try that!

7:37 kij: ,(source pr-on)

7:37 clojurebot: Source not found

7:38 kij: is there any tool to "easy" find the source for pr-on, and other java? defined functions ?

7:39 pyr: kij: your trying to find a source for pron ? on the internet ? surely you should find one :)

7:41 kij: pyr: lol ;) yea gonna macroexpand it.

7:43 pyr: kij: otherwise, it's in core.clj

7:44 (https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj)

7:44 kij: yea line 2014, so source is only for public ?

7:44 jaju: raek: Thanks for the gist snippet. That seems like the better way.

7:47 pyr: kij: or autodoc doesn't pickup everything

7:48 kij: uhh http://clojuredocs.org/

8:12 michael_campbell: Morning all. As a complete #clojure neophyte, would you recommend Programming Clojure or the Joy Of Clojure as a first book? I've got a smattering of dynamic language, FP, and Lisp in my background, but not much. The lispy syntax doesn't bother me. Looking for something that goes over the paradigms and idioms more so than "this is a program" type of instruction.

8:12 Or some other book too; those 2 seem to have the buzz is why I mention them.

8:14 manutter: I had a little trouble following JoC when I first read it, but I was too much of a neophyte back then.

8:14 I went back to it after reading Clojure in Action (MEAP) and then JoC was awesome.

8:15 michael_campbell: Ah, thanks; forgotten about the In Action book. Worth it?

8:16 manutter: I'd say so, I really liked it.

8:17 michael_campbell: much appreciated; I'll check it out.

8:19 meta question (and reply offchannel if appropriate); why do some channels start with ## but most with #?

8:19 robermann: +1 for Joy Of Clojure

8:20 dhm: +1 for Joy Of Clojure

8:22 opqdonut: michael_campbell: freenode policy

8:22 clgv: +1 for Joy of Clojure on the condition that it's not ones first clojure/lisp book ;)

8:22 opqdonut: http://freenode.net/policy.shtml#channelnaming

8:22 michael_campbell: ^

8:23 michael_campbell: THanks.

8:23 robermann: as a first lisp book I'd advice the SICP

8:23 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%_toc_start

8:24 michael_campbell: robermann: I've considered that; I have SICP and have made some stabs at it over the last 15 or so years.

8:24 And Siebel's CL book.

8:24 equally stabbed, although in a shorter time period

8:25 just wondered if the syntax differences between clojure and scheme would be another barrier to entry that I'd prefer not be in my way

8:25 I guess nothing worth doing is easy though.

8:28 * algernon found JoC to be awesome, and it was his first clojure/lisp book (though, I did use various lips dialects before, just never read a book about any of them :P)

8:28 ambrosebs: I'd say PragPub's clojure book would be more appropriate than SICP

8:28 fdaoud: ambrosebs: second edition on the way, btw

8:29 ambrosebs: 1st ed. is fine too

8:30 don't use SICP to learn clojure, unless you know scheme already

8:30 michael_campbell: I know enough to recognize it as Scheme, but that's about it.

8:32 looks like pragpub has a beta e-book program like MEAP, too.

8:32 (or other way around; didn't mean to imply Manning's came first)

8:33 ambrosebs: Scheme is pretty different to Clojure

8:34 fdaoud: michael_campbell: yes, except that pragpub won't let their beta e-books stay unreleased for 3+ years :/

8:34 fhd: I could need a hand debugging a ClojureScript problem, anyone willing to help?

8:34 michael_campbell: are any of you guys seeing clojure "in the wild", or are you doing it more for your own projects? If you ARE doing it for more than that, are you getting ok's from companies to do so or is it a more subversive "put it in there, it's just a jar, no one will know" type of thing?

8:34 fdaoud: *chuckle* I didn't know Manning had that reputation =)

8:35 Anyone got a discount code for PragPub? (Sorry, I'm old, have to ask)

8:35 ambrosebs: I'm a student, just use it for projects and personal research

8:36 joegallo: i use it professionally, totally in the open

8:36 (that is, no "it's just a jar" stuff -- which I hope people are usually just joking about)

8:36 fhd: michael_campbell: I'm working on a small Clojure+ClojureScript project at work with a colleague. Wouldn't be able to get many more on board for Clojure projects here though.

8:36 fdaoud: michael_campbell: I've purchased many Manning MEAPs and it was good, but now I stopped after having 3-4 books that weren't getting finished. The worst are JavaScript Ninja and Spring in Practice: both were started in 2008!

8:36 fhd: michael_campbell: Otherwise private stuff.

8:37 michael_campbell: I have a perverse desire to make a jar of a half dozen classes where every .class file comes from a different source language.

8:37 fhd: michael_campbell: My bosses think it's fine if it makes us productive, but I think they are not regarding it as a "serious" language. But they know not to interfere :)

8:38 michael_campbell: fhd: That's fortunate. My background is financial applications (yeah, I know), so @ work there is nothing even remotely close to "modern", much less cutting edge, so I am doing my "fun" stuff totally off book, by necessity.

8:39 fdaoud: michael_campbell: java clojure jruby groovy scala mirah fantom ceylon gosu ...?

8:40 michael_campbell: fdaoud: At least java clojure jruby and groovy. Probably scala would be next, then perhaps mirah or fantom. That ordering based on my very limited experience with them.

8:42 there's a lot more languages on the JVM than I would have guessed, but of course many are just experiments, half baked and incomplete, etc. I ran across a Modula-2 impl not too long ago. When someone does APL (or J)... that'll be fun.

8:44 fdaoud: michael_campbell: I've tried many but always come back to clojure

8:45 michael_campbell: I guess it'll come with time, but I spent so many years on HP RPN calcs that prefix notation is a real chore for me. Postfix flows from my brain like I was born that way, but prefix... it's a mechanical parsing exercise for me still.

8:47 ambrosebs: michael_campbell: I'm still working on postfix :)

8:47 michael_campbell: It's all what we're used to I suppose.

8:55 fhd: michael_campbell: I used to be in financial services, same problem. Java 6 was pretty much bleeding edge for those guys... Now I'm in logistics, better :)

9:46 robermann: an off-topic question: anyone using Eclipse's GIT plugin (EGit )? Is it stable?

9:51 fdaoud: -> is my new best friend

9:51 thank you JoC for explaining it

9:53 clgv: why does this work? ##('bla 'x)

9:53 lazybot: ⇒ nil

9:53 mdeboard`: clgv: What do you expect it to do?

9:54 clgv: It's just (fn 'bla 'x)

9:54 #(fan 'bla 'x)

9:54 #(fn 'bla 'x)

9:54 isn't it?

9:55 ##('bla 'x)

9:55 lazybot: ⇒ nil

9:55 mdeboard`: ,('bla 'x)

9:55 clojurebot: nil

9:55 mdeboard`: (1 2 )

9:55 ##(1,2)

9:55 lazybot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

9:55 mdeboard`: ##('1 '2)

9:55 lazybot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

9:56 mdeboard`: ##('(bla))

9:56 lazybot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

9:56 mdeboard`: Dunno.

9:56 clgv: no it's a symbol called as function that returns nil

9:56 &('bla 'x)

9:56 lazybot: ⇒ nil

9:56 clgv: &('bla)

9:56 lazybot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: Symbol

9:57 mdeboard`: Yeah didn't know double-hash was the symbol to activate lazybot

9:57 soz m8

9:57 clgv: yeah it's for in-text usage

9:57 raek: clgv: symbols look them selves up in maps like keywords when then are called as functions

9:57 ,('foo {'foo 1})

9:57 clojurebot: 1

9:58 raek: ,(get {'foo 1} 'foo) ; equivalent to this

9:58 clojurebot: 1

9:58 clgv: raek: ah ok. I did not know that

9:58 (:bla 'x)

9:59 &(:bla 'x)

9:59 lazybot: ⇒ nil

9:59 clgv: maybe an exception indicating that there is no map involved would be good...

9:59 raek: yeah, I would prefer that too

10:01 michaelr525: hey

10:01 is there video recordings from strangeloop?

10:02 manutter: I've seen slides but no video so far

10:02 (http://goo.gl/MqF9Q)

10:11 `fogus: ClojureScript Atoms now have watchers and validators

10:11 manutter: nice

10:16 michaelr525: `fogus: it's probably a good thing ;)

10:24 lnostdal: anyone know how to get enlive to not wrap templates in html+body? .. i currently strip that away using subs, but, yeah

10:26 raek: lnostdal: maybe 'html-snippet'?

10:28 lnostdal: raek, thanks .. hm, i guess i can't get deftemplate to use that behind the scenes?

10:28 raek: I think you can also insert "<bogon>" in the beginning of the text to tell tagsoup to not insert the extra tags in the tree

10:29 lnostdal: ok, well i'm reading from a file our designer has created .. i can't change that file without breaking what he's working on

10:30 perhaps deftemplate accepts something not a filename though .. i can wrap that up i guess

10:31 hm, nah, it calls get-resource only AFICT

10:31 ..or it'll actually take an inputstream, yeah

10:33 raek: I don't know how to do it. tagsoup has options for this, but maybe enlive doesn't expose them...

10:35 stuarthalloway: good morning. Anybody want a Clojure 1.3 release?

10:36 * manutter raises his hand.

10:37 dakrone: stuarthalloway: please

10:37 stuarthalloway: Anybody want to read https://github.com/clojure/clojure/blob/master/changes.txt and let me know if there are any dumb spelling errors?

10:38 di-csuehs: the bad part about having the bots is that I can't make smart-ass comments like slurp changes.txt

10:39 Reading it now

10:42 fliebel: stuarthalloway: So... "1.3 Disallow recur across try" means that this is no longer allowed, or that this disallowance is removed?

10:42 stuarthalloway: fliebel: it always was wrong to do it

10:42 now you get an error at compilation time

10:42 fliebel: Oh, sweet :)

10:43 Something with dynamic binding, right?

10:43 di-csuehs: How nit-picky do you want? Should Operations be captialized in 1.4 Removed Bit Operation[s]

10:44 stuarthalloway: hrm, seems that capitalization is a bit inconsistent in the sections headings all the way

10:44 let's ignore that

10:44 or should I say "let's Ignore That"

10:44 di-csuehs: np

10:44 fliebel: I've never been quite able to tell what "2.3 Better Exception Reporting" was all about.

10:44 ambrosebs: stuarthalloway: section 2.17 "the following code with throw an example"

10:44 should be "exception"

10:45 stuarthalloway: ambrosebs: fixed, thanks

10:45 di-csuehs: I would consider breaking line 84 to separate lines, allowing easier access to the URL's in the narrow confines of browser's layout.

10:45 stuarthalloway: will push in a few minutes when you guys are done

10:45 raek: "Disallow recur across try" should perhaps be replace with something like "Recur across try is now properly rejected by the compiler" to clarify the intention of the change

10:45 stuarthalloway: di-csuehs: agreed, but won't hold release for that

10:46 mdeboard`: Anyone have a link to dnolen's preso to the NY Clojure group about predicate matching

10:46 from august

10:47 manutter: I can't quite parse 1.2 -- "This allows ... from being in the equality partition" ?

10:47 fliebel: 2.5 clojure.data/diff - huh, where does that live? http://clojure.github.com/clojure/branch-master/clojure.core-api.html

10:47 mdeboard`: s;predicate matching;predicate dispatch/(match)/g

10:49 di-csuehs: there some neat stuff in here

10:49 manutter: mdeboard: This one? http://vimeo.com/27860102

10:49 stuarthalloway: I moved recur-across-try into bug fixes, as well as repairing the language. Pushed.

10:51 di-csuehs: I'm not sure if it is markdown mangling or what is emitting weird glyphs at line 290,291

10:51 stuarthalloway: proposed revision to 1.2 "This allows ISeq implementers to be in the map or set equality partition."

10:53 ambrosebs: stuarthalloway: line 416, probably want to delete the period on the end of the line

10:53 412

10:54 after http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go

11:00 stuarthalloway: fliebel : I have posted on the dev list requesting a doc update to include data.diff

11:01 di-csuehs: Done reading. Nothing else jumps out. Looks like some fun stuff.

11:08 kzar: Which couchdb library for Clojure should I use?

11:10 mdeboard`: kzar: Wouldn't any HTTP library work?

11:12 kzar: mdeboard`: I could use a HTTP library and code my own couchDB layer, I could try out some of the different couchDB libraries too but I'd rather just use whatever's best - if there's a clear winner anyway

11:15 `fogus: stuarthalloway: The defrecord improvements link should probably just be http://dev.clojure.org/display/design/defrecord+improvements

11:16 zerokarmaleft: kzar: https://github.com/ashafa/clutch is quite popular

11:21 kzar: zerokarmaleft: Thanks OK

11:25 arohner: stuarthalloway: section 5, "Then, in a separate step, upgrare to Clojure 1.3"

12:04 TimMc: What's wrong with upgraring?

12:09 "Please either indicate ^:dynamic ** or change the name."

12:10 Should that be *fred* instead of **?

12:25 tsdh: Is there something like CL's atomp function?

12:28 bhenry: tsdh: what does it do?

12:28 tsdh: bhenry: Return true for anything that evaluates to itself.

12:30 hiredman: tsdh: are you sure? what about (atomp 'foo) ?

12:30 surely (eval 'foo) doesn't eval to foo

12:33 tsdh: hiredman: Yeah, the definition wasn't that good. :-)

12:33 hiredman: The real def is "Returns true if object is of type atom; otherwise, returns false."

12:33 hiredman: And an atom is anything that is not a cons.

12:34 I'll go with (not (or (number? x) (string? x) (symbol? x) (keyword? x)))

12:34 hiredman: clojure doesn't have cons cells, so everything is an atom in that sense, so atomp is useless

12:39 manutter: it does have atoms, tho ;)

12:46 churib: tsdh: perhaps you mean not sequable?

12:48 tsdh: churib: My intention was to filter out anything that cannot have side-effects when being evaluated.

12:49 arohner: tsdh: that's not build-in

12:50 tsdh: sounds interesting though. Why do you need it?

12:52 tsdh: arohner: I wrote a variant of defmacro that expands into a normal defmacro with the guarantee that all arguments are evaluated once only.

12:53 arohner: Now the idea was that one could skip some gensyms for args that cannot have side-effects anyway.

12:53 arohner: But that seem to have a benefit, so I'll let it as is.

13:05 TimMc: tsdh: Sounds like you basically just want literals.

13:09 tsdh: TimMc: Yep

13:13 manutter: Ok, that's a weird lein/swank bug

13:14 I could not do clojure-jack-in because I had a ~/.lein/init.clj file that did (println "Loaded init.clj")

13:14 Somehow the "Loaded init.clj" line got embedded in the elisp that swank was trying to evaluate, and it was dying with "Symbol's value as a var is void: Loaded"

13:15 I changed my init.clj file to print ";;; Loaded init.clj" and now clojure-jack-in works again.

13:15 technomancy: is that a bug?

13:15 jjido: println may be a macro?

13:17 manutter: hmm, don't think so

13:17 ,(macroexpand '(println "foo"))

13:17 clojurebot: (println "foo")

13:23 technomancy: manutter: yeah, I guess it is. jack-in should probably be more specific about what it accepts as elisp. maybe it could search for a pair of markers and eval-region in between them.

13:23 can you open an issue so I don't forget?

13:23 or pull request? =)

13:24 manutter: ok, will do

13:24 issue, that is...it'll be a while before my elisp skills are up to a bug-fixing level

13:55 * `fogus downloads Shen

13:57 dnolen: `fogus: I played around w/ it a bit, seems fun.

13:58 `fogus: Qi was [this] close to being my Lisp of choice

13:59 gfredericks: is there a simple way to take a ring request and forward over HTTP to another server? (does that even make sense?) I was trying to think of a simple way to set up a little proxy server for development that mucks with the headers...

14:00 the sticky point seems to be how to get the ring clojure-map back out onto the http wires...

14:02 amalloy: gfredericks: you'd have to issue a new request to the other server on behalf of the client

14:02 to act as a real proxy

14:03 gfredericks: amalloy: right -- I just don't know if there's code to do that easily given a ring map, or if I'd have to assemple a raw HTTP request myself

14:04 assemple...I've been noticing a lot of these typos lately. That means I'm old now, right?

14:04 manutter: gfredericks: have you looked at clj-http?

14:04 gfredericks: nope!

14:04 * gfredericks has hisself a looksie

14:05 manutter: dakrone is the new maintainer, go to the dakrone one

14:05 gfredericks: noted

14:06 manutter: thanks

14:07 manutter: anytime

14:11 tcrawley: does anyone know of a lib that provides simple zip file extraction in clojure?

14:13 zerokarmaleft: java.util.zip?

14:13 clojurebot: amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

14:13 TimMc: clojurebot: forget that

14:13 clojurebot: Titim gan éirí ort.

14:13 TimMc: (Oops, wrong bot...)

14:14 tcrawley: zerokarmaleft: I was hoping for something that wraps all the crap there and gives me (unzip my-zip-file output-dir)

14:30 khalig: i'm looking for a nice way to do the java equivalent of listeners in clojure. was thinking some kind of lightweight messaging system kinda like erlang.

14:45 manutter: when clojure complains that PersistentArrayMap cannot be cast to [B, it's trying to build an array of bytes, yes? or booleans?

14:46 symbole: It's trying to pass PersistentArrayMap to byte[], I believe.

14:46 TimMc: clojurebot, what happened to clojure.contrib?

14:46 clojurebot: Cool story bro.

14:47 TimMc: (Is there a factoid for http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go ?)

14:47 zerokarmaleft: khalig: add-watch isn't sufficient?

14:48 manutter: Ah, there we go -- clj-http wants a string as the body of a post, not the actual map

14:49 cemerick: mmm, Clojure 1.3.0 has been released

14:49 * manutter cheers

14:49 cemerick: stuarthalloway: The real question is, why did the promotion of the second release build of that other project succeed? #rhetorical

14:49 symbole: manutter: I believe it accepts a string or byte[].

14:50 manutter: symbole: makes sense

14:50 TimMc: ,((juxt byte-array boolean-array) [])

14:50 clojurebot: [#<byte[] [B@1842264> #<boolean[] [Z@1ede158>]

14:50 stuarthalloway: I would respond but the use of the #rhetorical tag prohibits it ...

14:51 TimMc: stuarthalloway: Still taking typos?

14:51 zerokarmaleft: khalig: wb...is add-watch sufficient?

14:51 stuarthalloway: TimMc: as patches now :-)

14:51 TimMc: grr

14:51 I should sign that stupid form...

14:51 manutter: TimMc: saw that, tks

14:51 `fogus: Anyone have a pet example where the use of GClosure's extern facility is needed in ClojureScript?

14:52 TimMc: stuarthalloway: "now effects" is the only one that makes me rage

14:52 stuarthalloway: TimMc: impacts?

14:52 affects?

14:53 TimMc: affects

14:53 unless the internet really has finished ruining my sense of spelling

14:53 stuarthalloway: if that bothers you, what about the horrendous title capitalization

14:53 patch to fix that also welcome :-

14:54 TimMc: I'm too used to style guides for that to bother me.

14:54 cemerick: stuarthalloway: if you know, do share :-)

14:54 stuarthalloway: cemerick: kidding, I don't know

14:54 busy working on 1.4 features :-)

14:55 stuartsierra claims to have just posted an explanation to clojure-dev

14:55 cemerick: I've always been leery of the promotion operation in the nexus plugin; the semantics seem ill-defined.

14:56 dnolen: `fogus: jQuery?

14:56 `fogus: Right, but wonder if anyone had a small example.

14:58 CRICKEY! The session timeout on Clojure's Jira is 8 seconds!

14:58 dnolen: `fogus: ah no, but pretty much anything would do. most common activities are selecting things in the DOM, attaching events, ajax requests.

14:58 technomancy: why is "-master" in the version strings for clojure snapshots?

14:59 TimMc: `fogus: Did someone forget to multiply by 60?

14:59 `fogus: dnolen: I'll play around. Thanks

15:00 TimMc: It's not really 8, but it feels like it. :-(

15:00 stuarthalloway: technomancy: habit?

15:00 TimMc: At least Jira knows how to re-post.

15:00 technomancy: stuarthalloway: ok, fair enough

15:00 stuarthalloway: technomancy: assume it would break things to change it

15:01 technomancy: but if there is benefit to it I certainly don't care

15:01 * arohner thinks c.c.except needs to be in new contrib or something

15:01 technomancy: just an onion then

15:14 ibdknox: `fogus: if you're just looking for an externs file to play with, there's the d3 externs: https://github.com/shripadk/d3-externs

15:25 pauldoo: is there a technical name for built in functions which aren't special forms?

15:25 livingston: ,(seq? [1 2])

15:25 clojurebot: false

15:25 gfredericks: so if a take a response from http-clj and return it directly to jetty, everything seems to work like I want it to except images, which get cut off after 3774 bytes.

15:26 (by "jetty" I mean ring-jetty of course)

15:26 symbole: pauldoo: Special form doesn't mean "built in". It just means the evaluation rules are different.

15:26 pauldoo: (ie, things with funciton-like semantics (args evald left to right), but which are provided by the runtime.. Not special in the sense of "if" or "def" which have semantics totally unlike functions)

15:26 gfredericks: pauldoo: ...functions?

15:27 rbranson: how are people doing data persistence with an RDBMS'? are there any patterns? ClojureQL? clj-record seems like more of the same thing I'm trying to get away from :/

15:27 pauldoo: symbole: yes indeed. special forms are generally built in however, (is that not true)?

15:27 gfredericks: pauldoo: things that are not functions or special forms are usually macros, which can have arbitrary "semantics"

15:27 aside from the fact that the first symbol denotes the macro

15:27 livingston: I really thought vectors were seq able and responded to seq? clearly not. if want to test for vectors,lists etc. but exclude strings I want what sequential? ?

15:27 gfredericks: livingston: yes

15:27 pauldoo: okidoke, so is there a special names for functions provided by the runtime.. ? (with regular function-like semantics)

15:27 raek: seq? does not mean seqable

15:28 ibdknox: livingston: ,(doc coll?)

15:28 gfredericks: pauldoo: I guess you're thinking of the functions in the clojure.core namespace particularly then?

15:28 which you could call "core functions" or some such thing

15:28 ibdknox: &(doc coll?)

15:28 lazybot: ⇒ "([x]); Returns true if x implements IPersistentCollection"

15:28 pauldoo: gfredericks: I'm not thinking of clojure specifically. I've been reading SICP and am now implementing a lisp.. want to make sure I've got my terminology correct.

15:29 livingston: gfredericks: ibdknox: is coll? better?

15:29 gfredericks: livingston: I think they will differ for sets and maps, so it depends what you want

15:29 pauldoo: gfredericks: I think my runtime provides special forms, and built in funcitons.. the rest is all implemented in the guest language (or "standard library")

15:29 raek: pauldoo: primitive functions, maybe

15:29 in constrast to compound functions

15:30 livingston: I guess I need order in this case so sequential? it is.

15:30 ibdknox: &(map coll? [ [] '() {} #{}])

15:30 lazybot: ⇒ (true true true true)

15:30 ibdknox: &(map coll? [ [] '() {} #{} "hey"])

15:30 lazybot: ⇒ (true true true true false)

15:30 stuarthalloway: ,(clojure.data/equality-partition [1 2])

15:30 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.data>

15:30 pauldoo: gfredericks: yep ok- that name would also work. does the distinction have value though..? Is it important to label the difference between a special, primitive, or compound?

15:30 (I imagine it does)

15:30 gfredericks: pauldoo: that was raek's comment

15:30 stuarthalloway: ,(use 'clojure.data)

15:30 clojurebot: nil

15:31 gfredericks: and I don't know what he meant

15:31 ibdknox: livingston: that's what you wanted right?

15:31 stuarthalloway: ,(equality-partition [1 2])

15:31 clojurebot: :sequential

15:31 stuarthalloway: ,(equality-partition "foo")

15:31 clojurebot: :atom

15:31 gfredericks: ,(doc equality-partition)

15:31 clojurebot: "([x]); Implementation detail. Subject to change."

15:31 ibdknox: ,(doc equality-partition)

15:31 clojurebot: "([x]); Implementation detail. Subject to change."

15:31 pauldoo: gfredericks, raek: it sounds like I'm on the right track naming these things then. thanks :)

15:31 ibdknox: lol

15:31 stuarthalloway: awesome docstring :-p

15:32 stuarthalloway: ibdknox: I wrote it myself :-)

15:32 gfredericks: stuarthalloway: which is subject to change? the implementation, or the docstring?

15:32 technomancy: is this the first time the term "equality partition" has appeared outside JoC?

15:32 stuarthalloway: technomancy: no idea. the code has been there for a while

15:32 livingston: I was unaware of equality partition .. I was about to doc it, but we see.. what's it supposed to do exactly?

15:33 technomancy: livingston: things from different equality partitions can never be equal

15:33 stuarthalloway: livingston: the grouping implied by the baker paper

15:33 livingston: oh ok.

15:33 ibdknox: ,(map equality-partition [ [] '() #{} "hey" ])

15:33 clojurebot: (:sequential :sequential :set :atom)

15:33 stuarthalloway: but, more tactically, the grouping used to support data/diff

15:34 livingston: I see. thanks.

15:34 technomancy: a lot of people get confused about (= [1 2 3] '(1 2 3)), but since they are in the same partition and contain the same values it evaluates to true

15:34 stuarthalloway: .(diff {:a 1 :b2} {:b 2 :c 3})

15:34 gfredericks: I assume :atom is unrelated to clojure.core/atom?

15:34 stuarthalloway: gfredericks: yes. Atom as in non-collection

15:34 another possible word is scalar

15:34 technomancy: there was a CLer in here earlier asking about atomp; if I had known about this function I would have pointed him there

15:34 stuarthalloway: good thing it's marked as subject to change =)

15:34 gfredericks: stuarthalloway: maybe for clarity it should be changed to return :atom-but-not-the-concurrency-primitive-this-just-means-not-a-collection

15:35 livingston: I'm now wondering how many places I've erroneously used seq? assuming that'd pick up vectors and lists ...

15:35 stuarthalloway: I don't think many people use the data API besides me :-)

15:35 but they should

15:35 gfredericks: livingston: seventeen places

15:35 ibdknox: livingston: seq? only tests whether the current thing is a seq

15:36 ,(map seq? [ [] (seq [])])

15:36 clojurebot: (false false)

15:36 ibdknox: huh

15:36 ,(doc seq?)

15:36 clojurebot: "([x]); Return true if x implements ISeq"

15:36 gfredericks: stuarthalloway: after mulling it over I think I prefer 'scalar' to 'atom' maybe

15:36 at the very least it gets unambiguity bonus points

15:36 ibdknox: ,(map seq? [ [] (seq [1])])

15:36 clojurebot: (false true)

15:37 livingston: for some reason I was assuming seq? tested for suitability to shove into seq -- obviously it does not.

15:37 gfredericks: livingston: such a function could be called seqable?

15:37 which I'm sure exists somewhere

15:37 livingston: :p

15:38 ibdknox: gfredericks: used to be part of contrib

15:38 gfredericks: yep

15:38 cemerick: FYI: Now just $300 from reaching the fundraising goal to help send Ambrose to the Conj… http://wp.me/p10OJi-aX

15:38 Still time to slip in there and nab a free signed copy of Clojure Programming ;-)

15:38 (back to your regularly scheduled discussion)

15:39 TimMc: cemerick: awesome

15:39 livingston: did seq? used to behave differently (I'm assuming not, but I don't know how I came to misusing it)

15:39 ibdknox: livingston: gfredericks: but really, coll? is probably what you want

15:40 pauldoo: gfredericks, raek: I've realised I named my atoms/scalars as primitives. So I think I'll name primitive procedures "builtins" to avoid the clash..

15:40 ibdknox: livingston: not since I've been using Clojure. That's what it's always done

15:40 cemerick: TimMc: Yes, it absolutely is. I'm again stunned by the response.

15:41 livingston: actually in this particular case I need things where the order of the first two things in specified. in generally though, you are right, 9/10 I want to know "can I map this thing?"

15:42 michaelr525: i wonder what makes clojure too "heavy" for android? is it the dynamic generation of code that forces the compiler to be included in the app?

15:43 ibdknox: livingston: how about (sequential?)

15:44 ,(doc sequential?)

15:44 clojurebot: "([coll]); Returns true if coll implements Sequential"

15:44 livingston: ibdknox: yes sorry I wasn't clear. for my current use that is exactly what I need.

15:44 TimMc: Someone should write a blog post called "ISeq, Sequential, seq?, coll? and seqable"

15:44 ibdknox: yeah

15:44 livingston: ha

15:45 ibdknox: we should fix the docstrings for them too

15:45 TimMc: I don't know enough to do so.

15:45 gfredericks: TimMc: then everybody would link to it and laugh at clojure for complecting everything

15:45 TimMc: good

15:45 livingston: gfredericks: fine let them

15:45 TimMc: A little mockery is not a bad thing.

15:45 ibdknox: ideally that would be a forcing function to improve over the complication

15:46 livingston: gfredericks: if they want a LCD language use java ;)

15:46 ibdknox: livingston: I dare you to say that on #java ;)

15:46 TimMc: I'd rather people mocked a little bit than newcomers got confused and ran away.

15:47 gfredericks: well I for one think we should hide our flaws under the bed and pretend they're not there.

15:47 livingston: TimMc: yes. being explicit about what happens is good.

15:47 TimMc: gfredericks: :-)

15:48 gfredericks: now why does jetty close the connection after exactly 95% of the image has been transferred?

15:48 livingston: ibdknox: I know plenty of java programmers I joke with about java being the new cobol (sometimes they say it) yes I've programmed both - I prefer cobol - it may be less verbose (error messages are worthless though)

15:48 TimMc: gfredericks: Solution: Use a smaller image.

15:49 gfredericks: TimMc: tried that, still 95%

15:49 ibdknox: gfredericks: at that point it has enough information to determine what the image is of, and stops on moral grounds

15:49 gfredericks: how dare my http server judge me

15:53 dnolen: chouser: re, CLJS-39. I don't suppose you added have test cases for the :when :while :let syntax.

15:57 ballpark: What is the best way to close down slime-swank?

15:58 * rmarianski goes to the repl, and then hits comma, sayonara

15:58 gfredericks: is there an easy way to slurp an input stream into a byte-array rather than a string?

16:00 ballpark: @rmarianski- Cool. Thanks1

16:00 *Thanks!

16:01 rmarianski: gfredericks: you can try using make-input-stream from java.io

16:01 ballpark: In case anyone wants to make fun of some clojure code: http://codereview.stackexchange.com/questions/4956/a-crude-clojure-progress-reporting-function

16:02 gfredericks: rmarianski: I have an input stream...

16:02 ibdknox: gfredericks: (byte-array (slurp stuff))

16:02 gfredericks: rmarianski: it'll be fine, I stole and am modifying the code for c.c/slurp

16:02 ibdknox: I'm paranoid about it ever being a string

16:02 ibdknox: ah

16:02 gfredericks: given that everything's acting goofy at the moment...

16:03 dnolen: ibdknox: pushed a bunch of numeric fixes. should be good to at least write low-level loop/recur math that's competitive with plain JS.

16:03 gfredericks: but this slurp-bytes function I'm writing should do the trick

16:03 ibdknox: dnolen: I saw that, I'll try it out later. Is that in master?

16:03 amalloy: yikes. def inside a function is pretty vile, ballpark

16:03 dnolen: ibdknox: yup

16:03 ibdknox: dnolen: sweet. I'll let you know.

16:04 amalloy: ballpark: but this function is so huge and doing so many things that i can't really rewrite it for you in a better way

16:04 ballpark: amalloy: ok

16:04 gfredericks: amalloy: ooh, that reminds me: if a function needs helper functions, is it more idiomatic to (let [...helpers...] (defn ...)) or (defn _ (let [...helpers...] ...))?

16:05 hiredman: letfn!!

16:05 gfredericks: the second one seems cleaner to me, but I don't think I see it very often

16:05 amalloy: gfredericks: i favor the former, and anyone who doesn't is a lunatic, but there are lots of people who favor the latter and don't appear to be lunatics

16:05 ibdknox: dnolen: I did some more thinking about the arrays vs. seqs performance stuff. I really do think we need something that has near array level performance that can participate in all the seq stuff.

16:05 gfredericks: hiredman: isn't that just sugar, when the functions are independent?

16:05 hiredman: I have half of a patch to λ lift letfns into static methods

16:05 gfredericks: amalloy: okay, former it is then

16:06 amalloy: gfredericks: i use the latter form when the helper functions can usefully be closures, of course

16:06 dnolen: ibdknox: like I said Pods :)

16:06 gfredericks: amalloy: of course

16:06 hiredman: the half left is the most difficult part, so unlikely it will see the light of day

16:06 ibdknox: dnolen: Is there somewhere I can see that work? I don't think I was around when that was being discussed

16:06 gfredericks: hiredman: static methods on what class?

16:06 dnolen: ibdknox: https://gist.github.com/306174 pretty dense stuff but you can see the thinking.

16:06 hiredman: the enclosing class

16:07 gfredericks: hiredman: the function-class?

16:07 hiredman: so at the highest level they would end up on the class of the namespace

16:07 gfredericks: ah

16:07 hiredman: inside a fn the end up on the class of the fn

16:07 they

16:07 gfredericks: hiredman: does that give a performance advantage?

16:07 ibdknox: dnolen: well, for CLJS the impl should be much simpler given we only have one thread.

16:08 hiredman: gfredericks: actually I haven't checked, but I can't imagine it wouldn't

16:08 dnolen: ibdknox: I've done quite a bit of low level stuff in Clojure proper, so the slightly different style of coding doesn't bother me much, and low-level perf stuff tends to almost always be isolatable.

16:08 hiredman: you avoid object allocation+virtual call

16:08 dnolen: ibdknox: but I agree, moving forward with the Pods idea since we're single threaded seems like a good approach to me.

16:08 gfredericks: hiredman: and it would still be dynamic?

16:09 hiredman: dynamic in what sense?

16:09 gfredericks: hiredman: can be redefined, e.g. at the repl

16:09 hiredman: it would be as dynamic as letfns currently are

16:09 gfredericks: hiredman: oh would the static methods not have canonical names?

16:09 hiredman: oh they would, but it doesn't matter

16:09 gfredericks: e.g. if I do (letfn [(foo ...)] ...) (letfn [(foo ...)] ...), there'd be no naming conflict?

16:10 I suppose there'd have to not be

16:10 hiredman: yeah, the static method name would be something like (gensym 'foo)

16:10 gfredericks: can you add static methods to a class after it's been defined?

16:10 hiredman: no

16:11 gfredericks: so what would happen when I letfn at the repl?

16:11 since the NS class already exists

16:11 (does each ns have its own class?? :/)

16:11 hiredman: I suggest reading Compiler.java

16:11 it would speed this discussion up

16:12 it does, but the repl is a separate code path

16:12 gfredericks: hiredman: I pride myself in the fact that this is the longest conversation I've had with you before being asked to read a large piece of code :)

16:12 I must be getting better at something

16:13 hiredman: for most cases (eval 'x) gets turned into (eval '((fn [] x)))

16:13 gfredericks: fascinating

16:13 hiredman: because, you know how do you emit bytecode without a method to put it in?

16:14 amalloy: hiredman: yeah, i was wondering what the wrap-in-a-function was for

16:14 gfredericks: that makes sense. I always imagine that the code gets evaled directly instead of compiled, even though another part of my brain knows that's not true

16:15 hiredman: well, actually for simple expressions there is an eval path

16:15 but once you have a let or fn or letfn, or loop, etc it has to be compiled

16:15 gfredericks: hiredman: is that repl-specific?

16:15 (the eval path)

16:15 hiredman: yes

16:16 * gfredericks notices that Compiler.java is 8262 lines long

16:17 hiredman: yes, and emacs will spend a few minutes reidenting all of it if you are not careful

16:17 indenting

16:17 gfredericks: so for once I'm doing the right thing by not using emacs

16:18 hiredman: nah, you should be using emacs with care

16:18 gfredericks: :)

16:19 semperos: I can't access the Google group for some reason, but can I assume 1.3.0 is on its way out now, with the commits on Github from an hour ago?

16:19 * gfredericks oh boy oh boy oh boy oh boy

16:20 livingston: semperos: google has been a little flaky the past 12 hours or so... refresh?

16:20 semperos: livingston: got it working, thanks; took a few refreshes

16:23 gfredericks: finally I can start using ^dynamic

16:23 and 12345N

16:25 amalloy: gfredericks: you've finished porting all the libraries you use to 1.3 also?

16:26 ibdknox: heh

16:26 * ibdknox sighs

16:26 gfredericks: amalloy: nope. But once it's released I wouldn't mind putting the effort in.

16:27 amalloy: sigh. i've made two efforts to get 4clojure using 1.3, and it's just overwhelming

16:27 TimMc: contrib stuff?

16:27 amalloy: yes

16:28 hiredman: https://github.com/hiredman/clojure/blob/what-I-know-about-clojure/src/jvm/clojure/lang/Compiler.java#L6463

16:28 TimMc: You saw the 1.3-compat lib, yeah?

16:29 amalloy: TimMc: i don't think so

16:29 TimMc: https://github.com/arohner/clojure-contrib/tree/1.3-compat

16:29 amalloy: but i'm dubious about its usefulness anyway; we don't use any contrib ourselves, but dependencies do

16:30 gfredericks: amalloy: eh, maven will fix it. she always does.

16:30 ibdknox: amalloy: you should just write everything in house ;)

16:30 gfredericks: hiredman: is that branch full of little comments like that?

16:31 amalloy: ibdknox: i did that, but everyone said i was hurting the economy by not buying american-made code

16:31 ibdknox: damnit. I knew you had something to do with the recession.

16:32 gfredericks: hiredman: nevermind, I figured out how to use github myselfs :)

16:32 hiredman: gfredericks: that is the plan, there are only 3-4 currently

16:32 I will be taking pull requests (no code, just comments please)

16:32 gfredericks: hiredman: the point being for it to eventually be merged into the main branch?

16:33 hiredman: nope

16:33 just a reference

16:34 gfredericks: well ok

16:35 hiredman: Clojure/core is kind of strict about licensing and copyright, etc, which I can't fault them for, I just can't be bothered to keep that level of strictness

16:35 gfredericks: hiredman: oooooh right

16:39 speaking of which, having sent in a CA, is there some kind of follow-up I need to do?

16:39 or do I just start flinging patches?

16:39 is clojure.org/contributing kept up to date?

16:40 hiredman: more or less, it can take sometime for your name to appear there

16:40 gfredericks: okay

16:50 `fogus: Using an extern file in ClojureScript. https://github.com/clojure/clojurescript/tree/master/samples/hello-js

16:50 stuarthalloway: gfredericks: just poked redinger, he has your CA in his backpack

16:50 will be updated shortly

16:50 TimMc: haha

16:50 gfredericks: stuarthalloway: thanks!

17:02 arohner: there really needs to be a built in fn for applying maps to fns that take (fn [ & {:keys []])

17:04 kharrington: well, my complaint about that is that i think you should be able to ignore the :keys if you have supplied an :or

17:06 arohner: kharrington: sure, but what if I have fn A defined that takes [& {:keys}], and calls fn B that takes [& {:keys}]?

17:10 kharrington: aha

17:11 devn: the more concise way to say not-nil? when it's used a predicate for a filter... I'm forgetting

17:11 err, to avoid defining your own not-nil?

17:11 kharrington: ,(let [f (fn f [& params] (apply hash-map params))] (:b (f :a 3 :b 32)))

17:11 clojurebot: 32

17:11 hiredman: (comp not nil?)

17:11 TimMc: devn: identity

17:11 kharrington: arohner: there you go

17:12 devn: ,(filter identity [nil nil nil 1 2 3 nil])

17:12 clojurebot: (1 2 3)

17:12 devn: Thanks hiredman and TimMc

17:12 hiredman: or identity if you don't care about false values

17:12 TimMc: devn: Depending on what you think of booleans.

17:12 devn: *nod* -- identity will work in this case

17:12 arohner: kharrington: I know how to do it, I just think it should be built-in

17:12 devn: thanks

17:12 kharrington: ah

17:12 amalloy: TimMc: that's a polarized issue. everyone loves or hates them; nobody is on the fence

17:13 TimMc: amalloy: An excluded middle, eh?

17:13 kharrington: amalloy: har har

17:14 TimMc: Using identity as a predicate squicks me out a little. It is yet another idiom that a Clojure (or other logical-booleans language) programmer must learn.

17:21 technomancy: there's an issue open for making it optional with filter, remove, &c

17:22 sritchie: (complement nil?) too, right?

17:22 I guess that's the same as (comp not nil?)

17:35 TimMc: technomancy: What would that look like?

17:36 amalloy: TimMc: (filter foo) => (filter identity foo)

17:37 which i think is pretty common in ruby, for example

17:37 TimMc: ,(filter = [1 2 3] [0 2 4])

17:37 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core$filter>

17:38 TimMc: I guess filter isn't n-ary, so that works.

18:18 jli: amalloy: hm, what needs to be done to be able to use data.xml with 1.3? can I help with anything?

18:18 amalloy: jli: i don't know, really; it's mostly chouser's and i'm helping out

18:19 it seems like the builds are failing because the indentation tests don't pass, but when i run them locally they pas

18:27 jli: amalloy: hum, okay. I'll try looking at it tonight.

18:28 amalloy: jli: you can also release a copy of data.xml to your own clojars account, and damn the non-passing tests. flatland has that already, in fact

18:28 i thought. maybe not

18:29 http://clojars.org/org.clojars.ninjudd/data.xml

18:33 bayesian: tell me everything about clojure

18:34 hiredman: ~rationale

18:34 clojurebot: rationale is http://clojure.org/rationale

18:34 hiredman: go forth and syntax no more

18:48 dnolen: ClojureScripters, anyone got any opinions on inlining truth and remote truth_, https://github.com/clojure/clojurescript/compare/80-inline-truth

18:48 remote -> removing

18:52 ibdknox: would also like to hear how perf compares with this patch applied.

18:53 ibdknox: dnolen: that seems like it would be a big win, since truth_ is called all over the place, but I'm not so sure the numbers will actually show much of a difference

18:54 dnolen: ibdknox: after the macro ops and this change I see more than a 10X speed up on a simple loop.

18:54 macro arith ops

18:54 ibdknox: dnolen: that's encouraging :D

18:55 dnolen: I'll run a few profiles in about 10 minutes and let you know

18:55 dnolen: ibdknox: great thx

19:03 ibdknox: dnolen: it's looking good. with the latest master, standard loop-recur is down to 52 (about 2x native) and seqs are less than half what they were yesterday

19:04 dnolen: ibdknox: can you try with the inline truth branch?

19:04 ibdknox: dnolen: yep

19:04 dnolen: thx

19:09 ibdknox: dnolen: weird. That's showing better numbers for the seqs (shaved about 100ms) but worse numbers for the loop/recur case

19:10 dnolen: ibdknox: do you have a gist of the code you're testing?

19:11 ibdknox: https://gist.github.com/1238693

19:12 dnolen: hm I switched back to master and am now getting back up to 120ish for loop/recur

19:12 dnolen: not sure what the difference could've been

19:13 dnolen: ibdknox: you probably need to wipe out your js, remove out

19:13 ibdknox: dnolen: k. Consistently at 50ms for loop/recur

19:13 dnolen: on master

19:14 dnolen: ibdknox: k

19:15 ibdknox: dnolen: hm. but still getting 110 +- 10 in the inline-truth branch

19:15 dnolen: I'll do a couple of real profiles, see if I can track the difference down

19:16 dnolen: ibdknox: that would be helpful

19:16 ibdknox: btw, which browser?

19:17 ibdknox: dnolen: chrome

19:18 dnolen: ibdknox: hm I see 15ms in Chrome/Safari for loop/recur case

19:19 ibdknox: dnolen: interesting. I wonder if I have too much crap open. Let me close everything

19:21 dnolen: k, I get that now

19:21 dnolen: cool

19:22 ibdknox: so one problem w/ patch is the expression case. it emits something like ((G_XXX = (test)) || (G_XXX != null && G_XXX !== false))?then:else;

19:22 this will create a lot of global variables

19:23 ibdknox: hm

19:23 dnolen: but a better way doesn't come to mind beyond creating a function and calling it with the value of (test)

19:23 JS scope rule suck

19:24 CoffeeScript tends find expression like this and lift vars up into the surrounding context outside the expression.

19:24 ibdknox: yesh

19:24 yeah*

19:25 dnolen: would be kinda tricky given the recursive-descent nature of ClojureScript compiler

19:25 ibdknox: wrapping it in a function kind of negates the point of the patch

19:25 dnolen: ibdknox: yup

19:25 hiredman: is the clojurescript compiler really single pass?

19:25 jli: wow, what a pain

19:26 ibdknox: dnolen: could we create a tmp namespace in the context of the current one?

19:26 jli: dnolen: so, coffeescript would lift the temp var up just 1 level, but cljs is making it global?

19:27 dnolen: jli: cljs isn't doing anything, that's just my naive solution doing that

19:27 ibdknox: dnolen: the other option is to delete the var after the block

19:27 jli: dnolen: oh, you're inlining truth, gotcha

19:27 dnolen: hiredman: looks like it to me, not sure why it would need to be multipass.

19:28 hiredman: well, then you could do things like have the analysis pass notice the need for the vars and set them up for the code gen pass

19:29 dnolen: hiredman: yeah that's true. though it's current simplicity is a big win too.

19:29 hiredman: sure

19:30 (dec Compiler.java)

19:30 lazybot: ⟹ -1

19:30 ibdknox: dnolen: btw, the speed difference we were seeing was between having debugging enabled or not

19:30 dnolen: without debugging, I get 20ish ms consistently

19:31 dnolen: so what about a tmp namespace?

19:32 jli: ibdknox: would gc be able to reclaim if you put vars into a tmp namespace?

19:32 ibdknox: jli: good point

19:32 dnolen: ibdknox: seems yucky. we really want locals here

19:32 ibdknox: dnolen: I agree it's gross

19:33 the only other thing I can think of is to delete the vars after they're out of scope

19:34 dnolen: k I gotta run, will ruminate some more, open to ideas!

19:35 jli: hm, is this all because clojure's truth test needs to do multiple tests against the expression, so needs a local var?

19:37 ibdknox: jli: it's to handle an expression

19:38 jli: whoops, misread. Yes.

19:40 another terrible solution would be to wrap it in another block of some kind

19:40 jli: hm, why does it need to test against null and false? are those truthy in js?

19:41 ibdknox: don't blocks not help because there's no block scope?

19:42 ibdknox: jli: with

19:42 jli: sorry, I don't understand

19:42 amalloy: ah, with. a js construct that's only useful when it's misused

19:42 ibdknox: haha

19:42 brehaut: amalloy: its not even useful then :P

19:42 jli: oh, js/with

19:42 ibdknox: jli: there are with blocks

19:42 yeah

19:43 as I said, a terrible solution :-p

19:44 jli: the reason it has to check against those two is because those are the only two false values in *clojure*, but there are lots of false values in JS. So you have to explicitly test for one of those two and no others.

19:45 amalloy: if ((a = myexpr()) === null || a === false)?

19:46 jli: oh, right. NaN and such.

19:46 ibdknox: and 0

19:46 lol

19:46 brehaut: and ""

19:46 and undefined

19:46 but not new Boolean(false)

19:46 ibdknox: amalloy: that doesn't prevent it from leaking

19:46 jli: oh christ, really? I thought it was better than that. bah.

19:47 hiredman: can't you just have if emit the set of var xN = … it needs before emiting the if?

19:48 ibdknox: hiredman: I don't follow

19:48 hiredman: I guess that would still be global at the top level

19:48 ibdknox: yeah

19:49 jli: that seems pretty low impact, given how clojure code is typically written

19:49 hiredman: (if a b c) would emit something like "var x1 = a; if test(a) then b else c;

19:49 jli: is it a correctness problem? or more of a style problem?

19:50 hiredman: https://twitter.com/#!/djspiewak/status/117385222491865088 haha

19:51 ibdknox: jli: cljs shouldn't be polluting the global namespace

19:52 at the very least, we could wrap all the output in a function to prevent it from leaking out of the cljs scope

19:53 that should probably happen anyways

19:53 amalloy: ibdknox: gensym it

19:53 brehaut: does cljs use $ vars for generated symbols?

19:54 ibdknox: brehaut: the closure compiler will

19:54 amalloy: it already is, I think dnolen's issue is more of a correctness one. The likelihood that these globals would ever cause issue is very low

19:55 amalloy: I could imagine a couple instances where their presence is undesirable though. If it's a particularly large value, it would stick around and eat memory

19:55 jli: how much of a speedup did inlining truth give?

19:55 ibdknox: in the seq-case, as much as 10%

19:56 jli: hm :/

19:56 ibdknox: it's definitely something we want to do

19:56 those functions are used all over the place in tight-loops

19:57 jli: so, all these function calls are expensive, but the only (obvious) way to not leak memory and trash global is to use function scope

19:58 would it be hard to special-case uses that would pollute global, reverting back to a function call?

19:59 ibdknox: jli: I don't know how the compiler works well enough to comment on the difficulty of that. I suspect it wouldn't be too bad, since it already has to know scope at some level. The only case where this matters is when you call code directly.

20:00 which means I'm not sure we actually care that much

20:00 jli: what did your last sentence mean?

20:00 oh, you mean when you have a top-level expression?

20:00 ibdknox: yeah

20:00 jli: yeah, exactly

20:01 ibdknox: so at worst, we're keeping a var around slightly longer than we probably intend

20:01 but it wouldn't leak, which is the important part

20:03 jli: ibdknox: you mean in the non-top-level case?

20:03 ibdknox: jli: yep

20:03 jli: the only case I'm worried about is (def x ...)

20:03 let's see what that emits

20:04 jli: actually, doesn't hooking into closure and using goog.provides prevent the global trashing?

20:04 er, nevermind.

20:05 ibdknox: def seems to be safe

20:05 jli: I assumed ns did the top-level function thing

20:05 ibdknox: it doesn't

20:05 but I think it probably should

20:05 jli: seems closer to clojure semantics

20:07 ibdknox: I think that's probably the best solution

20:08 just wrap ns's in the function call

20:08 and leave things as they are

20:11 jli: doesn't that still leak memory?

20:12 ibdknox: no

20:12 (function(window) { ... })(window) prevents anything from getting attached to the global js namespace

20:13 so those created vars can be gc'd

20:14 jli: but wouldn't they be top-level defs inside the object? I guess I don't see how the runtime can know that it's safe to gc

20:15 ibdknox: it can mark and sweep them, but if you define something outside of the context of a function, it's equivalent to writing window.myvar

20:16 JS can't deterministically remove that var, since it has no idea what may happen with it

20:16 by wrapping it in a function, you ensure that only things that you explicitly attach to the window object will ever leave that scope

20:17 once the function is finished running, the gc can check for things that weren't closed over and remove them

20:18 amalloy: ibdknox: except of course js eval has access to named locals

20:19 ibdknox: amalloy: hm?

20:19 jli: if you had (def mything (if hugeobject ...)), a var would be declared at the top-level of your object, right? isn't that just like "mything"? can the GC see that it was only used for defining mything and get rid of it after mything is defined?

20:19 amalloy: (function() {var y=1; var z=2; return function(name) {return eval(name);};})() // y and z are closed over even though not named

20:19 jli: clearly I need to review mark and sweep :/

20:21 amalloy: ibdknox: so certainly *some* things can be gc'ed if you do it this way, but not as many as you might like

20:21 ibdknox: amalloy: I assume it checks for eval, but maybe not?

20:21 amalloy: that's the only case where that's true, right?

20:21 amalloy: ibdknox: i don't know

20:22 probably not, in retrospect?

20:22 ibdknox: time for some heap snapshots :-p

20:22 amalloy: ibdknox: i just tried (function() {var y=1; var z=2; return function(f, name) {return f(name);};})()

20:23 figured you could call this with eval, 'z', but it doesn't let you

20:23 which is a bit weird to me

20:24 ibdknox: never try to apply logic to JS

20:26 amalloy: yeah, I can't actually prove that eval captures them

20:28 amalloy: (function() {var y=1; var z=2; return function(name) {return eval(name);};})()('z') // 2

20:28 is that what you meant?

20:32 ibdknox: hrm

20:32 I'm not sure how to look into exactly how that works

20:34 amalloy: ibdknox: i'm not sure what you would be looking into. javascript makes locals available to eval, so if there's an eval then (and here i'm guessing) everything is implicitly captured

20:35 ibdknox: amalloy: yeah, I guess it's that simple.

20:36 in terms of the problem at hand, I think I'm ok with that being the one case these could escape

20:39 td123: is there a reason why clojure contrib is in the old releases on this page http://www.clojure.org/downloads but isn't listed on the stable release?

20:40 hiredman: there is no single single download for contrib anymore

21:12 gary_poster: Hi. Is there a way to introspect a module in the repl? example use case: I (require 'clojure.math) and want to just remind myself what the function names are in it.

21:13 amalloy: ns-publics is one way

21:13 ,(take 3 (keys (ns-publics (the-ns clojure.set))))

21:13 clojurebot: #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0)>

21:13 amalloy: ,(require 'clojure.set)

21:14 clojurebot: nil

21:14 amalloy: ,(take 3 (keys (ns-publics (the-ns clojure.set))))

21:14 clojurebot: #<CompilerException java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0)>

21:14 amalloy: hmph

21:15 ,(take 3 (keys (ns-publics *ns*)))

21:15 clojurebot: (sandbox.proxy$java.util.ArrayList$0)

21:15 gary_poster: amalloy, cool, got it working locally, thanks. I was able to use (ns-publics 'clojure.repl) and it was fine

21:15 Is (the-ns ...) better?

21:15 amalloy: good enough, then

21:15 no, i probably just don't remember what args ns-publics takes

21:16 (doc ns-publics)

21:16 clojurebot: "([ns]); Returns a map of the public intern mappings for the namespace."

21:16 jeremyheiler: ,(take 3 (keys (ns-publics (the-ns 'clojure.set))))

21:16 clojurebot: (rename-keys union select)

21:16 gary_poster: cool. thanks again amalloy :-)

21:16 amalloy: hm. i thought the-ns was a macro, but maybe not?

21:16 (doc the-ns)

21:16 clojurebot: "([x]); If passed a namespace, returns it. Else, when passed a symbol, returns the namespace named by it, throwing an exception if not found."

21:16 jeremyheiler: I thought so too

21:17 what would be a "namespace" here? Given that 'clojure.set is a symobl.

21:18 amalloy: ,*ns*

21:18 clojurebot: #<Namespace sandbox>

21:18 amalloy: ,(the-ns 'clojure.set)

21:18 clojurebot: #<Namespace clojure.set>

21:19 jeremyheiler: cool

21:24 jli: ,(the-ns *ns*)

21:24 clojurebot: #<Namespace sandbox>

21:25 amalloy: ,(apply = (iterate the-ns *ns*))

21:25 clojurebot: Execution Timed Out

21:25 ibdknox: ,(take 3 (keys (ns-publics 'clojure.set)))

21:25 clojurebot: (rename-keys union select)

21:26 ibdknox: why do you need the-ns?

21:29 jeremyheiler: ibdknox: Good catch.

21:30 td123: hiredman: ah ok, thanks

21:32 duck1123: does anyone happen to know why lein complains that it can't find the ant jar in my dev dependencies when I do lein deps?

21:32 If I do it again, it works

21:38 hiredman: duck1123: consider upgrading lein

21:38 what version are you running?

21:39 duck1123: 1.6.1

21:39 hiredman: from a checkout?

21:40 duck1123: no, it was just the standard lein install

21:40 just installed, we'll see

21:42 no, it's still doing it. I think it's related to my patched copy of Midje

22:19 simard: is there a function that I could use that would print a message to a relevant place when sending a form for evaluation from emacs through slime ?

22:20 a relevant place could be, a popup message box, or better, an emacs buffer

22:23 jli: simard: isn't it already in the minibuffer?

22:25 simard: actually, nevermind, I was in the *Message* buffer and not in the *slime-events* buffer.. a println works well

22:25 jli: the minibuffer only displays the end result though

22:25 jli: oh, you want something you can get at

22:26 yeah, *slime-events* seems to have everything :)

22:27 duck1123: doesn't output show up in the slime repl?

22:28 jli: duck1123: simard is evaling things from a source file

22:29 the repl only prints things you eval in the repl

22:29 duck1123: right, I thought the output would still show up in the repl window

22:29 jli: nope

22:29 duck1123: ok

22:30 to be honest, I set everything to log and have my app up in Guake

22:30 jli: guake? is that like yakuake?

22:30 sliding terminal thing?

22:30 duck1123: yep, I like it a little better than yakuake

22:31 F12 is firmly part of my muscle memory

22:31 you can do the same thing with iTerm2

22:49 pdk: ,(* 21 12)

22:49 clojurebot: 252

22:55 jeremyheiler: Is there a complete markdown parser written in Clojure?

22:56 brehaut: I've been porting some code to 1.3 and new contrib; i can't find a release in maven for the new clojure.algo.monads. Am i blind or is it just not available yet?

22:56 jli: is there something in core for (comp first (filter <pred> <coll>))?

22:57 brehaut: jeremyheiler: i believe people are use java markdown implementations

22:57 amalloy: jli: no

22:57 contrib has something like find-first, but (comp first filter) is at least as readable

22:58 jeremyheiler: brehaut: I figured as much. Thanks.

22:58 amalloy: and you can use (some pred coll) if the predicate doesn't "destroy" information

22:58 &(some #{4 5 6} (range))

22:58 lazybot: ⇒ 4

23:03 jli: whoo, ((comp first (partial filter #(= (:tag %) :title))) xmljunk)

23:03 amalloy: jli: #(= (:foo %) bar) always makes me sad

23:03 (comp #{bar} :foo)

23:03 jli: yeah, was just trying to replace it

23:04 sweet. point-free!

23:06 this is probably excessive

23:07 ((comp first :content first (partial filter (comp #{tag} :tag))) xmljunk)

23:09 brehaut: jli: you might find clojure.contrib.zip-filter.xml (particular xml-> ) and clojure.zip useful

23:11 jli: brehaut: thanks. yeah, I figured this has been done dozens of times before

23:12 brehaut: jli: xml-> and xml zippers a really nice little api for consuming xml too

23:13 jli: have a look at https://github.com/clojure/data.zip/blob/master/src/test/clojure/clojure/data/zip/xml_test.clj

23:16 amalloy: technomancy: the lein README has a "download the script" link, which works but involves a redirect from github.com/.../raw/... to raw.github.com/... - can't you just link to the canonical location?

23:19 * gfredericks just discovered clojure.pprint/print-table

23:25 amalloy: there must be something about project.clj, :main, or uberjar that i just don't get. with a project.clj that looks like https://github.com/4clojure/4clojure/blob/develop/project.clj - lein run works perfectly, running my :main class, but lein uberjar && java -jar the-jar.jar gives NoClassDefFoundError: foreclojure/core

23:28 jli: amalloy: don't you need :gen-class in core.clj's ns?

23:29 amalloy: do i? if so that makes me sad; can't the jar be hooked up to run clojure.main pointed at my ns?

23:30 jli: I think early on I associated "core.clj having :gen-class" with "working", and it's stuck :/

23:30 amalloy: i mean, i rarely try to produce uberjars, because i don't really need to work on machines that don't have lein or cake installed

23:30 but i'm disappointed that i can't produce one without AOT-compiling my whole damn program transitively

23:33 jli: If :gen-class is not supplied, when compiled only an

23:33 nsname__init.class will be generated.

23:33 amalloy: jli: well, marking main as gen-classed seems to resolve the issue

23:33 jli: whoot

23:34 or maybe :(

23:34 srid: has a version of clojure.contrib to fix "IllegalStateException: Can't dynamically bind non-dynamic var: clojure.contrib.pprint/*format-str*" in Clojure 1.3 been released?

23:34 amalloy: some of both

23:35 duck1123: just use clojure.pprint

23:35 * srid so I need to replace clojure-contrib with the respective sub-libraries

23:35 srid: how did /me get in there?

23:36 apparently it is one of the modules (lamina, aleph, compojure) that I am using which is relying on clojure.contrib.

23:36 * srid goes back to 1.2

23:36 amalloy: srsly. 1.3 is hard

23:36 duck1123: What I do is I place a global exclusions in my project for org.clojure/contrib and org.clojure/clojure-contrib and then go from there

23:36 srid: i hope it is not as bad as python3

23:37 amalloy: that's an interesting approach, duck1123

23:37 brehaut: srid: it seems unlikely that it will be that bad ;)

23:38 duck1123: it's a lot better than it used to be

23:38 The number of libraries I had to fix to get working has gone down a lot

23:40 brehaut: it looks like I'm just waiting for algo.monads 0.1.1 to appear in the mavens and necessary-evil should be 1.3 ready

23:42 duck1123: ok, I know technically you're not supposed to change anything after a release, but I released 0.1.0 of one of my libraries tonight before I realized that 1.3 was out. Since no one but me uses this library that I know of, do you think it's safe to fix it real quick, or should I do it right?

23:42 amalloy: duck1123: is that an exclusive-or? because i think it's safe to fix it, but you should do it right

23:43 duck1123: I'm going to fix it, I think. It's been like 4 hours

23:51 jli: clojure.set/union works on all collections

23:51 huh

23:53 gfredericks: yeah I found that really strange

23:53 jli: (reduce conj s1 s2), of course.

23:53 my ocaml brain reels

Logging service provided by n01se.net