#clojure log - Jan 30 2013

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

0:00 ChongLi: okay flapjax is really cool

0:00 piranha: it is :)

0:00 ChongLi: I made a nice eventstream that simply consists of a set that contains all the keycodes of currently pressed keys

0:01 so much nicer than dealing with annoying repeating events and crap like that

0:09 julienddd: Hi all, getting this exception with clostache: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil

0:10 Any ideas ?

0:10 (im noob)

0:10 xumingmingv: I guess you are passing a nil to the function you are invoking

0:10 (I havn't used clostacheE)

0:12 julienddd: (defroutes admin-routes (GET "/" [] ((render-resource "templates/global.html" {:html "<p>Hey this works??</p>"}))))

0:12 Thats my code, so I'm assuming the file is not found

0:12 xumingmingv: thanks

0:14 Another question: what is the difference between (use 'clostache.parser) and (use clostache.parser)?

0:14 what do those ' do in front of expressions?

0:14 TimMc: Quoting. It suppresses evaluation.

0:15 julienddd: TimMc: what is the difference with :

0:15 TimMc: :something

0:15 ChongLi: : is for keywords

0:15 :hi evaluates to :hi

0:15 julienddd: and 'hi to hi ?

0:16 ChongLi: yeah

0:16 but hi might evaluate to anything

0:16 depends on how you def'd it

0:17 when you say 'hi you're not talking about the value

0:18 you're talking about the symbol hi

0:18 you can use quoted symbols even when they're not bound to anything

0:18 julienddd: ChongLi: Ok, but how is that so much different from :hi ?

0:19 ChongLi: :hi is always :hi

0:19 julienddd: appart from being able to skip the starting ':'

0:19 ChongLi: it never means anything else

0:19 xumingmingv: &(type 'hi)

0:19 lazybot: ⇒ clojure.lang.Symbol

0:19 xumingmingv: &(type :hi)

0:19 lazybot: ⇒ clojure.lang.Keyword

0:19 TimMc: julienddd: The ns macro *could* have been written to take symbols instead of keywords, but it wasn't.

0:19 ChongLi: it's just used for things like as a key in a map

0:19 julienddd: ok I see

0:19 ChongLi: &{:hi "hello"}

0:19 lazybot: ⇒ {:hi "hello"}

0:20 ChongLi: &({:hi "hello"} :hi)

0:20 lazybot: ⇒ "hello"

0:20 julienddd: but I can do &{'hi "hello"}

0:20 ChongLi: yes

0:20 julienddd: &{'hi "hello"}

0:20 lazybot: ⇒ {hi "hello"}

0:20 ChongLi: you can really do anything you want with maps

0:20 julienddd: now if I (def hi ...) somewhere

0:21 ChongLi: &{'(a b c) "hello"}

0:21 lazybot: ⇒ {(a b c) "hello"}

0:21 julienddd: are they potential problems if I use 'hi ?

0:21 ChongLi: no

0:21 you're still only using the symbol

0:21 julienddd: is that the dif between symbol and keyw ?

0:21 ok

0:21 ChongLi: here's the real advantage of keywords

0:21 they can be called like functions

0:21 &(:hi {:hi "h"})

0:21 lazybot: ⇒ "h"

0:21 julienddd: &{'hi "hello"}

0:21 lazybot: ⇒ {hi "hello"}

0:22 julienddd: &({:hi "hello"} :hi)

0:22 lazybot: ⇒ "hello"

0:22 julienddd: that's cool

0:22 TimMc: ,('hi {'hi 4} 5)

0:22 clojurebot: 4

0:22 TimMc: Symbols can do it too. :-P

0:22 ChongLi: haha

0:22 julienddd: ok thanks for the clarification guys

0:23 ChongLi: isn't there a performance gain from using keywords?

0:23 julienddd: so I guess they *could* be interchangeable

0:23 ChongLi: at least on jvm

0:23 TimMc: They have different purposes.

0:23 julienddd: but convention has it that keywords are for maps, etc and symbols for namespaces ??

0:23 lazybot: julienddd: What are you, crazy? Of course not!

0:23 julienddd: is that right ?

0:23 TimMc: julienddd: Symbols are ultimately intended to be used to name things (locals, vars...).

0:23 ChongLi: symbols are usually used when you want to talk about the names of things

0:24 julienddd: TimMc: but what's the advantage of (def 'hi "...")

0:24 over (def hi "...")

0:24 TimMc: One works and the other doesn't.

0:24 ChongLi: &(eval (cons '+ '(1 2 3)))

0:24 lazybot: java.lang.SecurityException: You tripped the alarm! eval is bad!

0:24 ChongLi: ahhh

0:25 anyway, what I typed would return 6

0:25 julienddd: CompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:

0:25 for (def 'hi "...")

0:25 TimMc: Yep.

0:25 That's (def (quote hi) ...)

0:25 julienddd: but:

0:25 &(type 'hi)

0:25 lazybot: ⇒ clojure.lang.Symbol

0:25 julienddd: so it's a symbol ???

0:25 lazybot: julienddd: Yes, 100% for sure.

0:26 ChongLi: haha

0:26 TimMc: julienddd: The difference between what a macro sees and what the evaluator sees.

0:26 ChongLi: &(type '(+ 1 2 3))

0:26 lazybot: ⇒ clojure.lang.PersistentList

0:26 ChongLi: think about it this way

0:26 TimMc: (OK, def isn't actually a macro, but close enouhg for this discussion.)

0:27 ChongLi: an expression in clojure is just a list where the first element is a symbol

0:27 or another expression that evaluates to a symbol

0:27 xumingmingv: <lazybot> julienddd: What are you, crazy? Of course not!

0:28 when will lazybot jump out and say something like this?

0:28 * xumingmingv is curious

0:28 ChongLi: I think when you use more than one ??

0:28 lazybot: ChongLi: What are you, crazy? Of course not!

0:28 Raynes: xumingmingv: Who knows!?!??

0:28 lazybot: Raynes: What are you, crazy? Of course not!

0:28 julienddd: lol

0:28 Raynes: He gets all excited when he sees multiple question marks.

0:28 This is amalloy's doing.

0:29 ls

0:29 lazybot: boot etc mnt proc srv usr

0:29 ChongLi: it's great stuff

0:29 julienddd: cd usr

0:29 no??

0:29 lazybot: julienddd: Definitely not.

0:29 ChongLi: hey howcome lazybot doesn't allow 5 defs?

0:29 you demo'd that in your talk

0:29 (clojail)

0:29 TimMc: julienddd: For now, anytime you see '... read it as (quote ...)

0:30 julienddd: ok, thanks

0:30 Raynes: ChongLi: Because it (for no particular reason) runs everyone's code in the same namespace. The limiting is for memory mostly, it doesn't do any good if people overwrite existing clojure.core vars.

0:30 TimMc: ,''''x

0:30 clojurebot: (quote (quote (quote x)))

0:30 xumingmingv: lazybot, you are interesting??

0:30 lazybot: xumingmingv: What are you, crazy? Of course not!

0:30 julienddd: clojure gets more exciting everytime i learn about it

0:31 ChongLi: Raynes: ah I thought you could prevent people defing over existing vars

0:31 Raynes: It could work exactly like tryclj does, but I haven't bothered because it's pretty rare that people want to def things and if they do they probably should be using their own REPL anyways.

0:31 Naw, not without giving everyone a different namespace like tryclj does.

0:31 ChongLi: ah

0:32 Raynes: Nice that you watched my talk. <3

0:32 Were you there was I gave it?

0:32 ChongLi: no

0:32 I just got into clojure recently

0:32 I've been watching a lot of the talks

0:32 Raynes: It's horribly out of date now, and the testers and such work entirely different now (all function based with serializable functions), but the concept remains the same.

0:33 ChongLi: yours was one of the best talks I think

0:33 Raynes: <3

0:33 ChongLi: some of the other speakers weren't as comfortable

0:33 * Raynes wrangles up his ego.

0:33 Raynes: That was the first and only talk I've ever given.

0:34 ChongLi: yeah, you nailed it with the humor

0:34 xumingmingv: ChongLi: watch on the vimeo?

0:34 ChongLi: youtube

0:34 http://www.youtube.com/user/ClojureTV

0:34 xumingmingv: thanks for the link

0:36 julienddd: Ok, last question I swear: why does (:use clostache.parser) fail and (:use 'clostache.parser) work ?

0:36 and question part b) :P

0:36 what is the diff between (:use ...) and (use ... )

0:36 if any ?

0:36 luoluoluo: hi, how can I re-require a .clj after I modifying it?

0:37 I mean in lein repl

0:37 mybuddymichael: luoluoluo: (require 'my-ns :reload)

0:37 ChongLi: (:use clostache.parser) fails because clostache.parser is undefined at the time

0:37 Raynes: Step one: use stencil

0:37 julienddd: ah, makes sense

0:38 ChongLi: you're telling it to get the value of clostache.parser and :use whatever that is

0:38 for question b

0:38 the difference is that (:use ...) is part of the ns form

0:38 whereas (use ...) is just a function

0:39 julienddd: ok... I need to read up on that ns form thing

0:39 ChongLi: what language did you come from?

0:39 julienddd: java javascript

0:39 luoluoluo: mybuddymichael: thanks, I just tried (use 'my-ns :reload), it seems work, what's the difference

0:39 clojurebot: I'm no man, and she's no lady!

0:39 julienddd: obj C

0:39 ChongLi: the ns form in clojure is for working with namespaces

0:39 xumingmingv: haha clojurebot also jumps out

0:40 ChongLi: a namespace just gives you a separate "batch" of names to work with

0:40 so that you can use the same name multiple times in different files without overlap

0:40 julienddd: sorry, what's a form in cloj?

0:40 anything in () ?

0:40 ChongLi: and it gives you ways of managing those names

0:41 yeah a form is another word for an s-expression

0:41 it usually refers to special forms

0:41 and a special form is anything that's not a function nor a macro

0:42 but everything is used the same way, even if each thing works differently (in terms of semantics)

0:42 julienddd: like def

0:43 ChongLi: &(+ 1 2 3)

0:43 lazybot: ⇒ 6

0:43 ChongLi: so in this case, + is a function applied to 1 2 3

0:43 julienddd: yeah, that much I had grasped

0:44 still confused on macros vs. funcs

0:44 ChongLi: in the case of functions, the values 1 2 3 are evaluated before the function is called

0:44 julienddd: and special forms, why are they special? they're the low level building blocks ?

0:44 ChongLi: &(+ (+ 3 4) 3)

0:44 lazybot: ⇒ 10

0:44 ChongLi: in this case

0:44 it first evaluates to

0:44 &(+ 7 3)

0:44 lazybot: ⇒ 10

0:44 ChongLi: before reaching 10

0:44 TimMc: julienddd: They're what the compiler-writers decided couldn't (or shouldn't) be implemented in terms of other in-language constructs. So... yes. :-)

0:45 ChongLi: special forms and macros don't necessarily have to evaluate their arguments before using them

0:45 julienddd: and macros vs funcs, in a nutshel ?

0:45 ChongLi: (def abc 3)

0:45 julienddd: macros manipulate code ?

0:45 ChongLi: so in this case, abc is NOT evaluated

0:46 cause if it were, it'd be unbound

0:46 julienddd: ok, so that's why (use 'something) needs the '

0:46 get it

0:46 ChongLi: this is why you cannot write a function like def

0:46 TimMc: julienddd: Yes, macros are functions from code -> code. The compiler calls them.

0:46 ChongLi: think of it like this

0:46 all lisp code is made up of lists

0:47 a macro is a function that runs at compile time and it transforms a list to a different list

0:47 TimMc: ChongLi: And "atoms", if we're talking Lisp.

0:47 ChongLi: yeah

0:48 julienddd: another simple way to think about it is this:

0:48 functions evaluate each of their arguments once (and only once) before proceeding

0:49 macros can evaluate their arguments 0, 1 or more than 1 time

0:49 this is what makes macros such as when possible

0:49 &(doc when)

0:49 lazybot: ⇒ "Macro ([test & body]); Evaluates test. If logical true, evaluates body in an implicit do."

0:50 julienddd: yes, if it was a function body would get resolved when called

0:50 thanks for clarifying

0:50 you guys are very helpful

0:51 ChongLi: no problem

0:51 julienddd: Raynes: why stencil over clostache ?

0:52 xumingmingv: ChongLi: macros evaluate their args more than 1 time? can you give an example?

0:52 ChongLi: xumingmingv: let me see here...

0:53 yeah I can't think of one in a library off the top of my head

0:54 xumingmingv: something like this? (defmacro a [b] ~b ~b)

0:54 ChongLi: yeah

0:55 (defmacro multi-eval [b] `(do ~b ~b))

0:55 try calling that with (multi-eval (println "foo"))

0:56 xumingmingv: ok, got the idea

0:56 ChongLi: &(doc dotimes)

0:56 lazybot: ⇒ "Macro ([bindings & body]); bindings => name n Repeatedly executes body (presumably for side-effects) with name bound to integers from 0 through n-1."

0:56 ChongLi: there you go

0:57 multiple evaluation

0:57 in a library function

0:58 library macro, rather

0:58 haha

1:00 xumingmingv: en, never used this macro

1:01 (haha, I didnt write much clojure..)

1:03 amalloy: i'm consistently surprised by how often the ??/??? heuristic is right, Raynes xumingmingv ChongLi

1:03 ChongLi: ???

1:03 lazybot: ChongLi: Oh, absolutely.

1:03 ChongLi: amalloy: doesn't it just match via regex?

1:04 amalloy: ??? always generates a "you're right", and ?? generates a "you're wrong"

1:04 ChongLi: oh, haha

1:04 callenbot: fastest template engine in Clojure: go

1:05 amalloy: go isn't a templating engine in clojure

1:05 callenbot: I meant in the sense that I was asking people to volunteer an answer

1:05 ChongLi: perhaps we should start a new templating engine called go

1:05 mybuddymichael: Hah.

1:06 callenbot: ChongLi: harm it's Google juice even more?

1:06 ChongLi: yeah

1:06 callenbot: I like it.

1:07 ChongLi: I find it a bit annoying how google uses leverage to promote their languages

1:07 they should be promoting clojure!

1:08 callenbot: ChongLi: why?

1:08 ChongLi: because clojure's amazing!

1:08 xumingmingv: for template engine, you might want to take a look at this new engine: http://httl.oskpi.com/design.html#性能

1:08 TimMc: amalloy: Truth is stranger than fiction.

1:08 ChongLi: most of their languages are too conservative

1:08 xumingmingv: (in java)

1:08 seems very fast

1:08 Raynes: callenbot: Probably hiccup, right?

1:09 callenbot: Raynes: I've seen two different answers there

1:09 Raynes: 1. Hiccup is the fastest && 2. Hiccup is the slowest

1:09 Raynes: I shit you not, that's the variance.

1:09 ...I better write my own benchmark, huh?

1:09 bawr: callenbot: are you sure you need great performance, anyway?

1:10 callenbot: bawr: nope, this is purely for my personal edification.

1:10 bawr: I'm curious.

1:10 realistically I'd use hiccup or clabango anyway. I just want to know.

1:11 bawr: Oh, I see. Sorry, pigeon-holed you as a knee-jerk. ;)

1:11 AfroMujahid: Raynes, am I stil your favourite?

1:11 Raynes: callenbot: In my benchmarks laser is faster than Enlive with no purposeful optimizations. So, I'd be interested in seeing a decent benchmark.

1:11 callenbot: bawr: naw I know better than that.

1:11 Raynes: yeah I'm just going to write a benchmarking suite for template engines

1:11 testing various use-cases.

1:12 Raynes: callenbot: Just write it for whatever and I'll fill in the laser blanks.

1:12 bawr: callenbot: yeah, I try to hammer Knuth's advice into people. ;)

1:12 callenbot: bawr: I'm usually the one telling people to fuck off unless they have data

1:12 bawr: I was just wondering if anybody in here had tested recently.

1:12 bawr: callenbot: two rules of optimization: 1. don

1:12 1. don't. 2. (for experts) not yet. ;)

1:13 callenbot: ooh, right. excellent.

1:16 xumingmingv: bawr: http://httl.oskpi.com/design.html#性能

1:16 here is a test result, and with the test code

1:16 (for some java engine)

1:18 bawr: and a moonspeak anchor, I love it already :)

1:18 rclarkson: could i get some help from some pros: https://www.refheap.com/paste/9072

1:19 bawr: woah, those instability/abstractness graphs are weird.

1:21 xumingmingv: haha, why weird?

1:21 callenbot: I'm hammering together statistically significant and self-warming benchmarks for the template engines.

1:21 you'll have data soon my friends!

1:22 bawr: xumingmingv: well, when would you want an instability vs abstractness graphs?

1:22 xD

1:23 *graph

1:23 xumingmingv: maybe to show to users that my library is good, maintainable?

1:23 bawr: but both strike me as a bit hard to measure

1:24 xumingmingv: (Actually I dont understand that graph very much either)

1:25 brehaut: rclarkson: are you trying to generate datalog queries?

1:25 rclarkson: brehaut: yes

1:25 bawr: I've tried translating the comments, and it may not be as silly as it seems.

1:25 rclarkson: brehaut: from a form .. tricky though

1:25 brehaut: rclarkson: where does ?foo come from?

1:26 rclarkson: i presume ?bar comes from :bar ?

1:26 rclarkson: brehaut: yes

1:26 ChongLi: ?foo comes from yes?

1:26 rclarkson: just a variable to have in the other ones

1:27 callenbot: the results on these tests is already interesting :)

1:28 bwahahaha

1:28 rclarkson: ChongLi: no

1:28 bawr: callenbot: don't keep us waiting, you mad scientist, you :)

1:28 rclarkson: any idea how i can convert that one to catalog?

1:28 datalog

1:28 brehaut: rclarkson: ##((fn [[k [low high]]] (let [?k (symbol (str "?" (name k)))] (list ['?foo k ?k] [('> ?k low)] [('< ?k high)]))) [:bar [10 20]])

1:28 lazybot: ⇒ ([?foo :bar ?bar] [10] [20])

1:28 brehaut: rclarkson: but its truely horrible

1:29 ChongLi: yes, truly truly horrible

1:29 brehaut: and i got my quote in the wrong place

1:29 callenbot: bawr: trying to come up with less trivial test cases :)

1:29 brehaut: ((fn [[k [low high]]] (let [?k (symbol (str "?" (name k)))] (list ['?foo k ?k] [(list '> ?k low)] [(list '< ?k high)]))) [:bar [10 20]])

1:29 callenbot: in one test, I've already got a 10x variance in performance among template engines.

1:29 ChongLi: converting keywords to strings and then to symbols is always going to be ugly

1:30 brehaut: rclarkson: you could probably work backwards from goop like that to something with syntax quote and it'd clean it up a bit

1:30 rclarkson: brehaut: goop?

1:30 brehaut: rclarkson: the blob of code i just pasted

1:30 ChongLi: I don't see why you wouldn't store the symbol ?bar instead of a keyword

1:31 brehaut: yeah it does seem questionable

1:32 bawr: callenbot: interesting, though I'm not very surprised, unless the slower ones aren

1:32 't as feature-packed :)

1:34 callenbot: bawr: I can't wait to bring enlive into this...

1:36 bawr: callenbot: I mean, I'd expect most templating engines to be fine with just-acceptable performance and focus on power/ease of use instead.

1:38 callenbot: bawr: depends on the use-case, really.

1:39 bawr: callenbot: but then again, expecting and guessing is a moot point when we can have hard data. :)

1:39 callenbot: bawr: we'll see.

1:39 oh yes, these results are very interesting indeed.

1:43 brehaut: just FYI, david santiago has some templating performance tests because hes obsessive about performance https://github.com/davidsantiago/tinsel

1:44 its at the bottom of that readme

1:44 callenbot: brehaut: not comprehensive enough.

1:44 brehaut: not comprehensive enough at all.

1:45 brehaut: well thats clearly bullshit

1:45 its not comprehensive yes

1:45 but at all?

1:46 callenbot: okay fine, it's comprehensive

1:46 Raynes: brehaut, callenbot: Those are the ones I've been using. If you look at my README and his, our results are completely and wildly different.

1:46 callenbot: it doesn't cover enough template engines

1:46 Raynes: I am writing my own benchmarks for this reason...

1:46 Raynes: I'm using a proper benchmarking engine that hammers out the variance and JIT warmup.

1:46 Raynes: I don't know why are results are so different so I explicitly noted in my README that they are probably bullshit.

1:46 callenbot: Using criterium?

1:47 It is supposed to be really good https://github.com/hugoduncan/criterium

1:47 callenbot: Raynes: yes I am

1:48 rclarkson: brehaut: Thanks for the help. I have cleaned it up a little bit

1:48 callenbot: rclarkson: oh it's you again

1:48 rclarkson: are you from Sweden?

1:49 Raynes: callenbot: Don't know if you saw me say it earlier, but I can add the laser benchmarks when it is ready if you want.

1:49 rclarkson: callenbot: how come?

1:49 callenbot: Raynes: I'll push up a version with just hiccup and clabango momentarily

1:50 Raynes: when it hits my github, you're welcome to fire a pull request at me

1:50 after I push those up, I'll probably do stencil next

1:50 Raynes: callenbot: I'll take a look tomorrow. I'm in Windows for video games at the moment.

1:50 callenbot: Raynes: at your leisure. I'm in no hurry, just glad I'm finally writing this.

1:50 amalloy: hah. the exact opposite of the microsoft project Games for Windows

1:51 callenbot: did you look into forking dsantiago's existing benchmarks rather than starting from scratch? are they unusable for some reason?

1:53 callenbot: amalloy: I don't know what caused the variance in the numbers, I don't want it infecting me

1:53 if it infects me, I'll start tracking down the source of the variance

1:53 I'll be using Raynes to check for htis.

1:53 this*

1:53 Raynes: I read "I'll be using Raynes to check for tits"

1:54 amalloy: The problem is that when I, callen, and David all got entirely different and in some cases wildly different numbers when we ran those benchmarks on our respective systems,.

1:54 The benchmarks also don't seem particularly intensive.

1:54 Not that I know anything about what a benchmark should look like.

1:55 brehaut: Raynes: neither does anyone else. everyone just pretends

1:55 amalloy: well, the idea is that criterium encapsulates "what a benchmark should look like", and you just provide test cases

1:55 whichever ones you think are important

1:55 callenbot: I'll copy david's test cases themselves

1:55 I'm not reusing the harness though

1:56 yeah he's not re-running the benchmarks, that's pretty problematic.

1:57 Raynes: callenbot: Yeah, I always warm up the JIT a bit before I take my results.

1:58 callenbot: it's a reasonably "real world" benchmark (dave's) but they're not being run properly and they aren't well designed to isolating edge cases or variance in behavior between libraries

1:58 for example, mine are designed to see if the differences between the template engines level off as templates increase in complexity, or get further apart.

1:58 amalloy: oh, lord. yes, i assumed he would be using criterium

1:58 callenbot: amalloy: see? my crankiness isn't always unmerited.

1:58 Raynes: amalloy: Yeah, no, he isn't. He just runs the things.

1:59 DISCLAIMER: I am not complaining about anything he has done.

1:59 callenbot: I love dave. he gets my viewpoint on templates. but the viewbenchmarks needs replaced.

1:59 Raynes: I'm moving just a few miles of him. He could kick my ass in person if he wanted. I'm scared.

1:59 callenbot: improved

2:07 I feel like I'm an idiot: IllegalArgumentException No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil clojure.core/-cache-protocol-fn (core_deftype.clj:527)

2:07 what's going on?

2:07 wrong clojure version or what?

2:07 amalloy: &(clojure.java.io/reader nil)

2:07 lazybot: java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil

2:08 amalloy: someone is calling that, probably via slurp or something

2:08 callenbot: amalloy: it's almost certainly slurp, did this get deprecated or something?

2:08 amalloy: no?

2:08 clojurebot: no is tufflax: there was a question somewhere in there, the answer

2:08 amalloy: you're just calling it with dumb args instead of good args

2:09 callenbot: I've used this template engine before and I'm following the --- alright fuck this

2:14 christ that was annoying.

2:14 stupid mistake

2:24 well. str is going to be hard to beat.

2:29 * xumingmingv aggrees

2:37 callenbot: bawr: I have results.

2:37 bawr: published

2:50 bawr: callenbot: where'd you put them?

2:51 callenbot: sorry, just got into the office, didn't follow the whole discussion :)

2:53 dsantiago: callenbot, amalloy, Raynes : Those tests pre-date the existence of criterium.

2:53 For what it's worth, any results I posted were on warmed-up JVMs, having run the test function multiple times, before taking a reading.

2:54 Of course, now that we have criterium, we can do a lot better.

2:56 callenbot: dsantiago: https://github.com/bitemyapp/clojure-template-benchmarks

2:56 dsantiago: check it out!

2:56 dsantiago: stencil is #winning right now.

2:57 dsantiago: help me add stuff! I'm trying to add tinsel right now.

2:57 bawr: https://github.com/bitemyapp/clojure-template-benchmarks

2:57 dsantiago: Nice.

2:57 callenbot: dsantiago: yeah you're winning by quite a bit right now.

2:57 bawr: callenbot: thanks, checking it out

2:58 callenbot: dsantiago: 20-25x difference between stencil and hiccup/clabango

2:58 bawr: "Test results are avg / standard deviation."

2:58 Finally someone does std-dev.

2:58 dsantiago: callenbot: I'm surprised to be faster than hiccup. I don't believe that will hold true for all templates.

2:58 callenbot: bawr: duh.

2:58 dsantiago: come up with test cases and I'll add them!

2:58 bawr: callenbot: I officially like you at this point. :)

2:58 callenbot: I'll take pull requests to that repo, just don't fuck shit up.

2:59 michaelr525: hello

2:59 callenbot: michaelr525: hi

2:59 bawr: callenbot: although you really should use same units all around

2:59 callenbot: bawr: yeah I was pondering that.

2:59 bawr: should I standardize on microseconds?

3:00 bawr: yeah, I'd do that

3:00 callenbot: kk

3:00 hrm, wait what

3:00 dafuq is tinsel doing

3:01 that can't be real.

3:01 bawr: also, that's a neat link to the article about docs

3:01 callenbot: bawr: what link?

3:02 bawr: http://jacobian.org/writing/great-documentation/what-to-write/

3:02 dsantiago: What IS tinsel doing?

3:02 callenbot: dsantiago: I think I'm mis-using it, h/o

3:02 dsantiago: Quite likely. Tinsel is a different beast.

3:03 callenbot: yeah I'm not setting content properly.

3:03 dammit.

3:11 bawr: I fixed the units. refresh.

3:11 dsantiago: why is stencil render-file so much faster than render-string?

3:11 bawr: >20,600 ms / 799 us

3:11 missed one

3:11 dsantiago: Because render-file can cache the parsed template.

3:12 callenbot: ah motherfucker.

3:12 bawr: thank you, pushing.

3:13 dsantiago: help unfuck my tinsel stuff please: https://github.com/bitemyapp/clojure-template-benchmarks/blob/master/src/clojure_template_benchmarks/core.clj#L59

3:13 dsantiago: Yep, this isn't gonna do anything. Hang on.

3:14 callenbot: dsantiago: hanging.

3:18 dsantiago: callenbot: https://gist.github.com/be8f54c948547455cd26

3:18 callenbot: dsantiago: thank you!

3:20 * callenbot sees results, scowls at dsantiago

3:20 callenbot: dsantiago: do I need to (str ...) the result of the deftemplate or is it doing that for me?

3:20 dsantiago: Should be returning a string, no?

3:20 Returns a string for me, as you can see.

3:21 callenbot: dsantiago: well it's...eh...you'll see the results, h/o

3:22 dsantiago: https://github.com/bitemyapp/clojure-template-benchmarks

3:22 dsantiago: callenbot: Should be identical to hiccup, and it is.

3:22 Tinsel is a hairy macro that spits out a function that does what hiccup would do.

3:22 callenbot: dsantiago: the simple data injection numbers are throwing me off.

3:23 dsantiago: Yeah, I'm looking to see what that code is.

3:23 callenbot: rerunning with a slight change

3:23 you put in a string literal, replacing it with the var.

3:23 dsantiago: callenbot: I see.

3:23 That is turning into a string literal.

3:23 So there is no work, it's just a function that returns a string.

3:23 callenbot: yeah there we go.

3:24 updating results, these are more sane

3:24 I replaced the "bar" with bar

3:24 which is (def bar (str "bar"))

3:24 dsantiago: Right, I forgot to unshortcut that.

3:25 callenbot: the behavior makes sense now, pushing.

3:25 dsantiago: refresh if you care to see the new result

3:25 alex_baranosky: anyone know which version of clojure introduced nice-style ns doc strings? And which version intro diced ^:private style metadata?

3:25 callenbot: simple data injection is no longer totally loony.

3:25 dsantiago: Yeah, seems about there with hiccup again.

3:25 callenbot: yeah, but with slightly higher variance.

3:26 dsantiago: you wouldn't happen to understand enlive or laser would you? those are the next two I'd like to get rolled in.

3:26 dsantiago: callenbot: I wrote tinsel becaues I didn't like Enlive, so no. And I haven't seen Laser.

3:26 callenbot: Raynes: stand up and be counted https://github.com/bitemyapp/clojure-template-benchmarks

3:26 dsantiago: I actually like what you're did with tinsel.

3:26 dsantiago: callenbot: You're the first!

3:27 callenbot: dsantiago: it has a logic to it. It's a nice contrast to the...toothlessness of hiccup but it's less totally insane whole-tree-transformation-zipper-omg-wtf like enlive/laser

3:27 although laser is a bit less "roll in ALL the toys!"

3:27 s/like/than/g

3:28 I'm considering using clabango for main/normal templates and stencil for API/partials/pjax

3:29 dsantiago: Is the template rendering performance so severe for you?

3:30 callenbot: dsantiago: not so much, but I like to keep such things in the back of my mind.

3:30 I can't wait to see how enlive and laser do on this

3:30 dsantiago: Enlive is gonna be terrible.

3:30 callenbot: I know, that's the fun part.

3:30 dsantiago: I actually had code for it in my benchmarks, I just never posted the Enlive results.

3:35 callenbot: Ancient results from viewbenchmarks: https://gist.github.com/855872

3:35 * callenbot yawns and rubs chin

3:35 callenbot: yeah, boned.

3:36 that's actually slow enough to be unacceptable, tbqh

3:36 dsantiago: That was my appraisal at the time.

3:36 callenbot: sub-20ms and I'm wont to not really care, but 100-200ms is absurd.

3:36 dsantiago: Actually, at that time, I seem to recall people were getting some pathological templates that were taking many seconds to render just once.

3:36 Though I think they got some of those performance bugs sorted out eventually.

3:36 callenbot: toss that on top of the usual database waits and client network latency and you'll never fulfill a request faster than 500ms.

3:37 bawr: dsantiago: pathological as in "designed to be slow"?

3:37 or real-world stuff?

3:37 dsantiago: bawr: Er, no. I just meant, it was hitting some edge case in the engine that made it have terrible performance.

3:37 callenbot: the reason I don't include type-hinting in the benchmarks is because nobody's ever going to do that IRL

3:37 dsantiago: https://groups.google.com/group/enlive-clj/tree/browse_frm/month/2010-03/fa85686239120122?rnum=21&_done=/group/enlive-clj/browse_frm/month/2010-03?&amp;pli=1

3:38 callenbot: unless you're chuck norris or dsantiago. but I repeat myself.

3:38 bawr: dsantiago: that's terrible, then

3:38 dsantiago: If you scroll down, he had a page that took 6.5 seconds to render with 200 tweets on it.

3:39 callenbot: noice.

3:39 dsantiago: Like I said, I recall faintly that they did some perf work on enlive after this thread.

3:39 I don't know specifics.

3:39 I'd already done my own thing.

3:41 callenbot: dsantiago: how many template engines have you written? 2? 3?

3:42 that's what it looks like

3:42 dsantiago: is quoin what backs stencil?

3:43 dsantiago: quoin is just some utilities that I pulled out of stencil so I can use it in this next engine I'm writing.

3:43 callenbot: dsantiago: the jinja inspired one you queried me?

3:43 dsantiago: I wouldn't say it's that much inspired by jinja, but yes.

3:45 callenbot: dsantiago: what are you planning to do differently? can you relink the gists?

3:46 dsantiago: callenbot: New language, which I believe is more regular and a bit easier to parse. It's based around simple operations that can be combined for expressiveness, in that it lets you transform data before rendering it. And I'm thinking about a new approach to making it render even faster.

4:06 newb: How can traverse a seq two items at a time? I need to compare each item to the previous item.

4:06 Thanks

4:06 foodoo: ,(doc clojure.set/join)

4:06 clojurebot: Pardon?

4:06 foodoo: ,(doc clojure.string/join)

4:06 clojurebot: "([coll] [separator coll]); Returns a string of all elements in coll, as returned by (seq coll), separated by an optional separator."

4:07 foodoo: why doesn't the first command work? Is clojure.string automatically imported while clojure.set is not?

4:13 newb: Was that clojure.set/join for me, foodoo?

4:13 foodoo: newb: no. I've stumbled upon that one myself

4:14 newb: And I just entered the channel

4:17 newb: Found it - partition function

4:24 m_m2: Hi. I am na newbie. Can anyone tell me how i can change value of my local variable ? Like variable=variable+other_var . I know that locals i create by (let [] ) function.

4:26 newb: Hi m_m2, one of the main ideas behind Clojure is that you DON'T modify variables unless you absolutely have to. See http://clojure.org/vars for more

4:27 foodoo: m_m2: What do you actually want to accomplish?

4:29 m_m2: and (let) is not a function but a macro

4:29 m_m2: I have a "while" loop. Where I check some statements. If one of them is true then i need to increase one of my local var by other var.

4:29 clojurebot: In Ordnung

4:30 Sgeo: m_m2, that is generally not the preferred approach, although it is possible

4:30 m_m2: So how i can make this by a right way ?

4:30 foodoo: m_m2: can you post your code on pastebin.com (or somewhere similar)?

4:30 m_m2: because the answer to your question really depends on what you want to achieve

4:31 Sgeo: refheap.com is typically preferred by Clojurists

4:31 foodoo: Sgeo: thanks, I'll try to remember that

4:31 Sgeo: Well, it's by one of our own, so

4:31 (Raynes)

4:36 m_m2: foodoo It will be impossible right now. I am at work and this part of code is on my private comp. But... i tryed to resolve this : http://projecteuler.net/problem=1 . I have "while" loop where first of my locals was increased by 1 each time. Then I've checked (if (or (mod i 3) (mod i 5) )) . This is the moment... where its true I woluld like to add "i" to my sum variable "suma" .

4:38 foodoo: m_m2: that's okay. Do you know the (reduce) function?

4:39 m_m2: foodoo nope. But i will check it on clojuredocs.

4:40 foodoo: m_m2: The following are crucial functions for every functional programmer: map, reduce, apply

4:40 m_m2: and I forgot: filter

4:41 m_m2: Then there are also some variations of the functions just mentioned

4:43 m_m2: Soo i will create a list with my "i" variable and after tha ti will make (reduce + list_of_i) ?

4:43 foodoo: m_m2: that's one way, yes

4:43 m_m2: foodoo Is there any other ?

4:44 foodoo: m_m2: (apply + list_of_i) comes to my mind

4:44 m_m2: roodoo I see that reduce will use my stack right ?

4:45 foodoo: m_m2: you refer to memory consumption?

4:45 m_m2: foodoo yes

4:46 foodoo: m_m2: no, that's not an issue. If you use reduce you don't remember past reductions

4:47 m_m2: foodoo No. I mean is there any other why without use my stack.

4:47 foodoo: m_m2: I don't understand. Maybe you should post your project euler solution on refheap.com

4:48 m_m2: foodoo Hmm...reduce use stack right ?

4:49 foodoo: m_m2: No. It doesn't build up something like (+ 1 (+ 2 (+ 3 4))) but evaluates stuff directly

4:50 m_m2: It's more like a stream of values that are processed

4:51 m_m2: if you have a sequence like '(1 2 3 4) then reduce will take 1 and 2, sum them up and proceed to add 3 and 3 and then 4 afterwards

4:51 m_m2: foodoo how about apply ?

4:54 foodoo: m_m2: afk

4:58 m_m2: the use of apply is best illustrated by an example: The (+) function takes any number of arguments: (+ 1 2 3 4 ...). But if you have a list of values that you want to add you can't do (+ '(1 2 3 4 ...)) because (+) expects single values and not a list as a parameter

4:58 m_m2: what apply does is that it rearranges the arguments to a function for you so that (apply + '(1 2 3 4)) becomes (+ 1 2 3 4)

5:01 m_m2: which should also not result in a linear but a constant stack increase

5:01 Raynes: callenbot: Hrm, why is half of -main commented out?

5:02 Well, more than half.

5:08 josteink: git + heroku + clojure = I'm probably never going to install Visual Studio on my home laptop ever again

5:10 foodoo: josteink: what do you use as an editor?

5:11 josteink: emacs

5:11 I like sublime edit, and emacs is a bit heavy to get going

5:11 but I cant use sublime edit over ssh ;)

5:11 emacs I have everywhere

5:12 Raynes: Sublime is also a massive disaster for Clojure.

5:12 josteink: my biggest complaint there is actually the indentation

5:12 Raynes: Mhm.

5:12 josteink: it seems it cant do it right out of the box, and neither can any third party addin

5:12 Raynes: There is a decent third party add on for it, but it isn't the same as real support.

5:13 And I'd prefer he not pretend to support languages that he isn't going to put any effort into actually supporting.

5:13 He should just take the Clojure support out entirely, it's essentially useless as-is.

5:13 josteink: ah well

5:13 Im back to emacs

5:13 I like it

5:14 it feels good to have a lisp-based editor to do your lisp-y stuff in ;)

5:14 foodoo: I'm a Vim user but maybe LightTable will be the best choice in the future

5:17 josteink: ooh

5:17 a new ide/editor whose first demo/concept video is filled with clojure-code

5:18 lookss promising, but Ill stick to emacs for now ;)

5:20 Foxboron: I was wondering btw. When i was setting up emacs for the very first time. I fetched clojure-mode and then nrepl. That seems to break some keybinds or something (cant remember)

5:20 Is there any known issue doing it that way? The fix for me atleast was too only fetch nrepl, as clojure-mode is a dependency.

5:21 josteink: I jsut used emacs-starter kit

5:21 from technomancy

5:21 and then added yank-indent.el

5:21 that was about it

5:21 anyway. lighttable looks very interesting, and like some refreshing and new

5:21 Foxboron: currently got, nrepl, paredit, starter-kit and eldoc.

5:22 josteink: Ill wait till it proves itself though, until it matures ;)

5:23 daimrod: it's really sad that the author of LightTable has decided to write yet another editor instead of improving one of the existing... I mean, even if you're really good, you can't really expect to catch with Emacs or Vim within a lifetime, not unless you have 50 people working 7/24.

5:24 bawr: daimrod: to be fair, most of the killer features he wants to do wouldn't really work as extensions of other editors.

5:25 Foxboron: daimrod: i think that would just make it less accessable

5:25 maleghast: dalmrod: Haters gotta hate… The person / people behind LightTable are __MAKING SOMETHING__ why do you care enough to beat on them..?

5:25 josteink: daimrod: to be fair

5:25 foodoo: daimrod: The Clojure support in Vim is pretty nice with vimclojure, but I still think that if LT implements the features that are planned, I will probably switch

5:26 bawr: daimrod: besides... I just refuse to believe that Emacs is the pinnacle of Lisp development.

5:26 josteink: daimrod: emacs and those editors has a LOT of baggage which means that doing anything new or radical is hard or impossible

5:26 daimrod: much like firefox

5:26 there is a reason all new development is happening in chrome/webkit

5:26 foodoo: josteink: well spoken

5:26 josteink: someone who "wasted his efforts" on reinventing a wheel

5:26 sometimes it makes sense

5:27 maleghast: Amen - It's never a bad choice to innovate, and LightTable does just that. It may not be what everyone wants from a dev tool for Clojure, but no one can deny that its creators are innovators.

5:28 daimrod: I disagree, look at the xwidget branch, with more man-power I'm sure some awesome stuff could be made.

5:28 but Emacs ain't sexy

5:29 maleghast: daimrod: *raises eyebrow* How Subjective do you wanna get, mon ami? I know plenty of people that think emacs is a sexy tool - try out Sam Aaron's emacs-live configuration if you don't believe me...

5:30 foodoo: maleghast: isn't that mostly the awesomeness that comes from a REPL?

5:33 maleghast: foodoo: That and the Undo Tree, and Paredit and the core key-bindings in emacs that make for a powerful editing environment without taking your gads off the keyboard. I'm predominantly a Vi(m) guy, but even I can concede that emacs got game, and with some configuration magic it can be very powerful and productive as a tool. That's not to ay that I think that everyone should use emacs and only emacs - diversity is a GOOD thing :-)

5:34 foodoo: s/gads/hands - my typing SUCKS!

5:34 foodoo: s/ay/say - see what I mean?

5:35 bawr: a quick question - say I have a bunch of clojure files, and I'd like to basically rename a function and update all references. will the existing emacs/clojure bindings let me do that? and no, straight-up text substitution doesn't count. ;)

5:37 maleghast: bawr: I have no idea, but out of interest, why doesn't text substitution not count?

5:37 aroemers: diversity is a good thing indeed. Me and my development team, for example, get by with Sublime Text just fine for Clojure

5:37 (I am learning emacs on the side though..)

5:37 maleghast: aroemers: ;-) nice!

5:37 daimrod: I don't want to troll or to bash anyone, but I can't stop to try to imagine what a team of emacs hackers could have done with 200k...

5:38 bawr: maleghast: because what I'm *really* interested in is something else. I'm wondering if any clojure editing suites actually actively *use* the fact that clojure is a Lisp, with all the related homoiconicity goodness.

5:38 maleghast: if they do, renaming a function would be the most basic feature I can think of.

5:39 maleghast: bawr: That __is__ a good question; my Clojure-Tools-Fu is way to weak to offer insight, but I wish you success in your quest ;-)

5:39 Raynes: $latest enlive

5:39 lazybot: [enlive "1.0.1"] -- https://clojars.org/enlive

5:39 maleghast: daimrod: Hey, that's cool - why don't you get a bunch of emacs hackers together, do a proof of concept for some cool stuff and go find a backer..?

5:40 bawr: maleghast: for that matter, I wonder if Emacs can do that for ordinary Lisps.

5:40 Because if there's not one editor/plugin/whatever that does that, it's a fucking disgrace.

5:40 maleghast: daimrod: I would, but I'm already over-subscribed with a day-job, being a Dad, being a Photographer and trying to get two other web projects off the ground… ;-)

5:40 bawr: I know Lighttable will, but it's too immature at this point.

5:41 maleghast: bawr: I can't help but agree with you, though I would like to stress that it had never occurred to me before either, so perhaps it's not so much a disgrace as a minor disappointment ;-)

5:41 bawr: not really. I mean...

5:41 the ability to do that is literally the first and foremost selling point of lisp.

5:42 daimrod: bawr: don't know for the Clojure mode, but in SLIME for CL there is `slime-who-calls' (bound to C-c C-w C-c)

5:43 bawr: daimrod: oh, thanks, that's a good starting point.

5:43 m_m2: foodoo Are you using clojure in real world apps ?

5:43 bawr: I guess I'll have to actually understand how the major lisp modes work.

5:44 maleghast: bawr: If you get to the bottom of this question / these questions, PLEASE blog about it..? I'm interested, but have limited time… :-(

5:45 bawr: maleghast: I once toyed with an idea of a lisp-only editor that basically lets you edit sexps, not text. and forces formatting. ;)

5:45 maleghast: that's because it would make it *insanely* easy to operate on your code programatically then.

5:47 maleghast: bawr: That is both hardcore and clever, but I am not sure how useful it would be… I am prepared to be shown to be very wrong, and I am not naysaying, I promise, I'm just not sure my head can handle it and I would need to be "shown around" the idea a bit more I think...

5:47 bawr: heh, I know that feeling, I'll probably need to sacrifice a weekend just to research these questions properly.

5:47 maleghast: bawr: Hehe

5:48 bawr: but well, there's already paren-mode or whatever in emacs, and it seems popular enough.

5:48 this isn't really taking the idea much further. :>

5:49 maleghast: bawr: Fair point - I am going to have to go back to the TDD in (j)Ruby that I am doing at the moment, and consign Clojure to the realm of dreaming, at least for now...

5:50 bawr: for me, the forced-formatting was actually appealing because I know I spend *way* too much time on it. now it would be just a matter of editing the code pretty-printer once. :)

5:51 Well, Enlive looked interesting for about five seconds:

5:51 >No namespaces support (hence unsuitable for most XML)

5:52 p_l: s/most/most interesting/

5:54 bawr: I mean... come on, I know XML namespaces are a mess, but this just hamstrings it. :<

5:56 foodoo: m_m2: No, I'm not (yet)

5:57 maleghast: bawr: It does sound like a problem, for sure...

5:58 foodoo: m_m2: Maybe I'll write an XMPP client if I have the time

5:58 p_l: bawr: no, seriously, *properly* designed XML stuff can be fun

5:58 maleghast: bawr: Do you __have__ to use XML?

5:59 bawr: maleghast: let me put it this way - when I do, it's the tricky kind of XML.

5:59 p_l: true!

5:59 maleghast: bawr: Oh, that's no fun at all… Over my software engineering career I've done more than my fair share (it feels like anyway) of "using" XML and I have almost always regretted it… ;-)

6:00 p_l: unfortunately good XML requires thinking things through, just like good file formats

6:00 .DOC was more thought-through format than a lot of XML out there ;P

6:01 bawr: maleghast: to be fair, most problems with XML have more to do with borderline-retarded way it's generated and used, not the format itself.

6:01 foodoo: <listofattributes><attribute><name>foo</name><value>bar</value></attribute></listofattributes>

6:01 bawr: At least as far as using it programatically goes, we all know it's a mess for human readbility. :)

6:02 p_l: foodoo: that thing is known as Second Normal Form, and should be considered atrocity and crime

6:02 maleghast: bawr: I could not agree more with your last statement.

6:02 bawr: p_l: I can do you one better!

6:02 p_l: bawr: Three Words: Apple .plist XML

6:02 if I ever get the guy responsible for it, he is going to limp

6:03 bawr: <listofmaterials><material name="something".../><material name="foo bar".../></listofmaterials>

6:03 and then later in the file

6:03 <something>...</something>

6:03 <foo_bar>...</foo_bar>

6:03 foodoo: ouch

6:03 bawr: Yeah.

6:04 when I first saw it, I puked a little :<

6:06 maleghast: bawr: Yep, .plist files are hideous, no argument from me on that!

6:08 foodoo: a couple of month ago Rich Hickey introduced something like "clojure data format" something similar to JSON but with Clojure literals. What was the exact name of that again?

6:08 bawr: p_l: oh God

6:08 maleghast: EDN

6:08 bawr: p_l: I just looked those up.

6:08 maleghast: foodoo: https://github.com/edn-format/edn

6:08 bawr: p_l: horrible, horrible.

6:09 maleghast: There is also Fressian, which is the Datomic interchange format, based on Hessian

6:09 foodoo: maleghast: thanks. Did anyone use these yet?

6:11 maleghast: Datomic uses Fressian, so anyone using Datomic is de facto using it… I am considering EDN as a successor to JSON in a system I am working on at the moment, should JSON performance continue to be a problem, as it is implemented in Ruby as well as Clojure.

6:12 foodoo: To answer your question, yes, but it's still early-adopted times… ;-)

6:12 augustl: EDN has what I really miss in JSON: sets

6:12 bawr: Ooh. How did I not know about Datomic for so long?

6:13 maleghast: augustl: Yeah, that is a lovely feature

6:13 augustl: bawr: shame on you! :)

6:14 maleghast: very often my JSON arrays have set semantics, but that needs to be communicated out of bounds..

6:15 josteink: augustl: from what Ive seen lots of (JSONy) people have complained about EDN

6:15 maleghast: augustl: Well indeed, but needs must when the devil (or client) drives… ;-)

6:15 josteink: augustl: mostly because you have 3 ways to define sets/arrays

6:16 bawr: josteink: how so? a cursory read of the spec doesn't suggest that

6:16 maleghast: josteink: Why would anyone complain about a technology - I just don't get that. I mean use it, don't use it, but why expend energy bitching about it?

6:16 augustl: josteink: hmm, what are the 3 ways?

6:16 josteink: augustl: you have seq's/lists, you have vectors, you have setsm you have maps

6:16 etc

6:17 which is a nice distinction in a programming lanaguge with regard to what -implementation- fits best

6:17 for a data interchange format I agree its a bit redundant

6:17 augustl: I see

6:18 maleghast: josteink: Not if you are interchanging between systems written in Clojure, because then it fully supports all of Clojure's fundamental data types.

6:18 josteink: maleghast: sure

6:18 but then its a clojure data serialization format

6:18 augustl: there are more environments than Clojure where it matters whether a list is random access or not

6:18 josteink: and no longer a general purpose data interchange format

6:18 or would you appreciate if clojure had to deal with JS's quirks, in your code, simply because you want to consume JSON data?

6:19 augustl: I'd say JS quirks are a lot less general than data structure semantics :)

6:19 maleghast: josteink: What makes you think that I don't, or rather that the person / people that maintain the various JSON libraries for Clojure don't ..?

6:19 josteink: Im just saying that lots of people have problems with how EDN seems to be tailored for clojure and nothing else

6:20 and thus it will have a hard time to suceed as a general purpose, popular data interchange format

6:20 Im not saying anyone holds absolute truth

6:20 just that popular tide is not leaning towards EDN

6:20 bawr: yeah, I don't see it happening either

6:22 maleghast: josteink: Fair enough; I find myself unmoved by the "popular tide", but I cannot see anything wrong with your point :-)

6:27 m_m2: foodoo Do you know any real world apps written in clojure? Maybe clojure have some part of bussines where it may be usefull.

6:28 bawr: the tags are a nice feature, to be sure

6:30 maleghast: m_m2: Not wishing to butt in (too much) on foodoo but there are lots of real-world apps written in Clojure. The majority are internal applications for large corporations, particularly banks in London and New York, but there are entire companies basing their work entirely in Clojure, like Mastodon-C for example.

6:30 bawr: in fact, one could sensibly omit vectors and sets from the core spec and just implement them as tagged elements

6:30 foodoo: m_m2: maleghast pretty much summarizes it. Have a look at http://planet.clojure.in/ to see some stuff people do with Clojure

6:32 m_m2: But I think we don't have an application yet that has raised a great deal of awareness outside of the Clojure community

6:32 bawr: foodoo: that's not necessarily a bad thing, really.

6:32 m_m2: foodoo Is there any kind of GUI framework for clojure like Gryphon for Groovy ? (easy to use). I know that clojure have web framework called Noir. But I couldnt find any big app written on it.

6:32 foodoo: bawr: Reminds me of Haskell. "Don't be popular" ;)

6:33 bawr: The way I see it, people who want to use Clojure already know about it. ;)

6:34 foodoo: m_m2: There definitely is a Swing wrapper. But I forgot the name. But even if you don't find it, you can still use Swing directly through Java interop

6:34 bawr: I'm with Paul Graham on this - I'm really fine with Lisp being a secret weapon. xD

6:34 maleghast: bawr: *applause*

6:35 bawr: hmm. anyone knows why edn needs a discard sequence?

6:39 foodoo: bawr: maybe to add debugging symbols to edn output?

6:40 bawr: the way I see it, edn really tries too hard to be readable by clojure's eval

6:41 which is a bad idea in any case

6:41 foodoo: Isn't it obvious? Rich Hickey strives for world domination ;)

6:42 bawr: yeah, but it could've been made much more "friendly" with relatively little changes

6:45 foodoo: The github page says "Currently this specification is casual, as we gather feedback from implementors."

6:45 so maybe rich is still open for suggestions

6:46 bawr: eh, I'll try if I get some time over the weekend

6:46 doesn't seem likely, though :)

6:52 clgv: bawr: isnt the whole point of EDN that it is a decent subset of what the Clojure reader can read? thus enabling Clojure-to-Clojure interprocess communication as well as Clojure-2-World since the subset is chosen such that it is easy to implement?

7:24 bosie: how does (ns blah (:import ....)) work? isn't (:import ... ) calling a function called :import?

7:25 augustl: bosie: it's a macro, it ends up calling (import)

7:27 bosie: augustl: is this what macroexpand shows when it shows clojure.core/import ?

7:27 foodoo: okay, since a couple of hours have passed, I'll repeat my question:

7:27 augustl: bosie: yes

7:27 foodoo: ,(doc clojure.set/join)

7:28 clojurebot: Titim gan éirí ort.

7:28 foodoo: ,(doc clojure.string/join)

7:28 clojurebot: "([coll] [separator coll]); Returns a string of all elements in coll, as returned by (seq coll), separated by an optional separator."

7:28 foodoo: why doesn't the first thing work? Is clojure.string imported by default and clojure.set isn't?

7:29 augustl: foodoo: for all I know it's bot specific behaviour

7:29 foodoo: augustl: it's reproducible in the REPL

7:29 Raynes: It's also REPL-specific behavior.

7:29 augustl: perhaps the REPL requires clojure.string

7:30 Raynes: Nothing but clojure.core is automatically included IIRC.

7:30 foodoo: augustl: good theory

7:30 augustl: seconding the iirc :)

7:30 Raynes: You can test this theory by doing the following: java -cp `lein classpath` clojure.main

7:31 foodoo: theory falsifie: (println (clojure.string/split "foo and bar and baz" #"and"))

7:31 this programs works fine when saved in a file and invoked through "clj testprogram.clj"

7:31 Raynes: Yup, I was wrong.

7:31 I've been known to be wrong.

7:32 foodoo: Raynes: still, was a good theory :)

7:32 augustl: what's "clj"? Never used that

7:32 Raynes: Ugh, why do you have a 'clj'?

7:32 augustl: perhaps whatever clj is requires clojure.string ;)

7:32 Raynes: Delete it and forget it exists. There is no official 'clj' thing for Clojure.

7:32 foodoo: but ...

7:32 Raynes: augustl: No, I just used clojure.jar directly.

7:33 Surprisingly it is automatically required.

7:33 foodoo: clj is a shell script that contains: java -jar ~/lib/clj/clojure-1.4.0.jar $@

7:33 bosie: augustl: whats the point of writing :import when it gets translated into import anyway?

7:33 Raynes: bosie: Because one looks like a function call and the other looks like what it is which is a directive.

7:34 bosie: Raynes: it just looks illogical to me to have a keyword as a function call

7:34 Raynes: It isn't a function call.

7:34 Has nothing to do with a function call.

7:34 bosie: if ns wasn't a macro, wouldn't it be a function call?

7:35 Raynes: Yes. And keywords actually are functions.

7:35 &(:foo {:foo 1})

7:35 lazybot: ⇒ 1

7:35 bosie: hm

7:35 i thought only in context of a hash or other sequences?

7:35 Raynes: Yes.

7:36 bosie: which isn't the case for :import/:use

7:36 Raynes: So?

7:37 It isn't a function call, it is a directive. It could behave differently to 'import', 'require'.

7:37 bosie: so its another special usage case to remember

7:37 Raynes: It would be a special case regardless of how it looks.

7:37 Keyword, symbol, whatever, it is still in a macro where the rules of evaluation are changed.

7:37 bosie: true

7:45 clgv: bosie: no it is the namespace default case ;)

7:48 bosie: clgv: which just showcases why clj is confusing to learn

8:03 clgv: bosie: humm why? all material I read that introduces namespaces uses the keywords in the ns-form

8:03 bosie: just get one of the recent books.

8:03 foodoo: clgv: But it's still confusing

8:04 magnars: why is the ns form of require/use not [:require [...]] instead of (:require [...]) ? I know both work, but the second one seems more commonly used.

8:05 that would maybe alleviate some of the confusion?

8:05 clgv: foodoo: well the rule is in normal clojure dont use import- require- refer- directly but use keywords in the ns-form

8:05 bosie: clgv: it is confusing because of the mental overhead due to inconsistency that clojure introduces

8:05 clgv: bosie: which inconsistency?

8:06 bosie: clgv: (:import...)

8:06 clgv: (for [x [...] :let [...] :when ....]

8:06 clgv: why not use '(ns foo [...])' like for?

8:07 clgv: introducing new rules for every macro seems incosistent to me

8:08 clgv: bosie: it makes no difference whether you use a list or vector in an ns-form

8:08 bosie: there is some rule which should be preferred but I dont know if I am following that one myself currently

8:09 bosie: clgv: wait, (:import ) is a list?

8:10 clgv: bosie: yes. code-is-data data-is-code ;)

8:11 ,(type '(:import ))

8:11 clojurebot: clojure.lang.PersistentList

8:11 bosie: ,(type (:import))

8:11 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :import>

8:11 foodoo: they are both seqs, that is all that matters

8:11 bosie: now i am even more confused, ha.

8:11 foodoo: ,(type '(:import))

8:11 clgv: bosie: that does not work since you call the keyword :import as function on zero args

8:11 clojurebot: clojure.lang.PersistentList

8:11 bosie: clgv: ofc

8:12 clgv: hence its not a list

8:12 clgv: you dont do '(:import...), you do (:import...). i don't see how this is a list

8:12 clgv: bosie: you have to quote lists to tell clojure it is data. you dont have to for vectors

8:12 bosie: it is see below

8:13 ,(type (read-string "(:import...)"))

8:13 clojurebot: clojure.lang.PersistentList

8:13 Bodil: bosie: Parentheses make lists. And lists are used to represent code - the quite just says "please don't evaluate this list as code."

8:13 The quote*

8:14 clgv: bosie: (:import) fails since the repl or clojurebot try to evaluate it since it is an unquoted list evaluation means function call

8:14 bosie: get one of the good books to help you with the basics quickly

8:15 bosie: clgv: i already have

8:16 clgv: (ns foo '(:import...)) doesn't seem to work

8:17 Bodil: yes. which was my point. its incosistent

8:18 magnars: any reason to not just use [:require] instead in the macro? It behaves the same from what I can see.

8:18 clgv: bosie: no. you must not quote it there. `ns` is a macro, that means its content isnt neccessarily evaluated literally

8:19 Bodil: bosie: Not unless you assume lists are _only_ used to represent code. Lists are just lists. :)

8:19 bosie: clgv: you said the macro requires a list. i gave it a list. instead i must give it 'code' that doesn't exist

8:19 clgv: clgv: the ns-macro parses the given that and uses require/refer as needed "internally"

8:19 Bodil: magnars: imo, using lists reads better. Like using vectors to declare function arguments. Breaks up the syntax a bit.

8:20 bosie: Bodil: so the for syntax bothers you?

8:20 clgv: bosie: if you want to grasp the reason of that behavior read the macro section of your book

8:20 Bodil: bosie: No, why would it?

8:20 bosie: clgv: i will. thanks

8:22 Bodil: figured (for [..]...) reads worse, not using lists and all.

8:22 magnars: Bodil: sounds like an argument based on familiarity, while bosie has a point about similar things behaving similarly.

8:23 bosie: magnars: thanks

8:23 Bodil: bosie: That wasn't my point at all. I meant the idea behind (fn []) and (for []) was to avoid the "omg too many parentheses" argument, and make the code more visually identifiable.

8:24 bosie: ok

8:24 Bodil: magnars: Lists and vectors are both seqs. They do behave similarly. :)

8:25 magnars: Bodil: yeah, I just don't understand the seeming idiomatic use of lists for ns declarations

8:25 noidi: there's a good rule of thumb for choosing between vectors and lists: lists imply that their first argument is special somehow

8:25 magnars: noidi: that is an interesting thought. That way it makes more sense. Thanks.

8:26 Bodil: magnars: No reason except it avoids syntactic clutter, I guess. :)

8:26 noidi: in `(:require foo :refer [bar baz xyz])` `:require` is special, but `bar` has no special meaning in the vector

8:27 magnars: I liked the reason noidi gave, actually. Gives me a nice mental image of the difference.

8:27 Bodil: noidi: That makes a remarkable amount of sense. :)

8:28 clgv: noidi: right. cheap sequential versus cheap random access^^

8:28 noidi: it also affects indentation: in `(:import (foo.bar Baz <linebreak> Blah <linebreak> Xyz))` the class names `Blah` and `Xyz` would line up under the class name `Baz`

8:29 clgv: noidi: wasnt that the argument in one of the style guides?

8:29 noidi: whereas they would line up under the package name if you used a vector

8:29 clgv: noidi: thats IDE dependent ;)

8:30 noidi: sure, but that's the default for paredit and CCW's structured editing mode

8:30 Bodil: noidi: That's a very Emacs centred argument, though. Which I like. :)

8:30 Though those indentation rules have been idiomatic for Lisp for a VERY long time...

8:30 noidi: I think VimClojure (or whatever it's called) follows the same indentation rules

8:31 bosie: noidi: lemme check

8:31 noidi: (whatever it's called now, since I recall it being split up into several packages)

8:32 apparently the packages are vim-clojure-static and foreplay: https://groups.google.com/forum/?fromgroups=#!topic/vimclojure/B-UU8qctd5A

8:32 bosie: noidi: [asdf Baz<LB>Blah<LB>] puts the Blah under asdf

8:33 noidi: with () it puts it under baz

8:34 noidi: bosie, right, so the indentation is consistent among three of the most popular Clojure editing environments

8:35 so it's hardly an Emacs-specific argument :)

8:35 clgv: ah well, I'd store clojure code in sexpression datastructure in databases instead of textfiles. that way identation is only a viewer setting which one might store in a style-part of the database as well when it differs from the viewer rules...

8:37 noidi: clgv, and then write a fork of git/mercurial to handle semantic changesets instead of diffing files... :)

8:38 clgv: noidi: yeah versioning could be a lot better if it had s-expr info. wasnt there the git+clojure-parser from rich?

8:49 michaelr525: A services manager where services can be stopped/started and reloaded from updated code. Is something like this exists for clojure?

8:54 clgv: michaelr525: you can use tools.namespace to do a complete reload

8:54 michaelr525: damn, bad connection did i miss something?

8:54 clgv: michaelr525: you can use tools.namespace to do a complete reload

8:55 michaelr525: but you meant something like a distributed system?

8:56 michaelr525: clgv: actually distributed is not a requirement.. I have two small programs where each program reads from a message queue. One downloads stuff the other posts stuff to facebook, they both run on the same server. So I started thinking that it's wastefull to run two jvms for such small programs..

8:57 clgv: you suggest that i can maybe write something simple myself..

8:58 clgv: michaelr525: well then I do not understand the "service start/stop requirement" if you want to use a single JVM anyway

8:59 Dark_Temple: hello :)

8:59 michaelr525: clgv: suppose that i would like to update the code for one of the services without shutting down the others..

9:00 Dark_Temple: is there a way to (partial function_name arg2) ,i mean to partial evaluate but with argument 2 first

9:00 the-kenny: I can't remember any function swapping the args

9:01 Use #(function-name % arg2)

9:02 Dark_Temple: thx kenny i will try

9:05 clgv: michaelr525: do use lein in the deployed setup or do you run a uberjar?

9:07 michaelr525: clgv: right now i just 'lein run'

9:08 clgv: it's my project so i can do whatever i wish :)

9:10 clgv: michaelr525: well using tools.namespace to reload one namespace and its transitive dependencies should work then to reload new code

9:12 michaelr525: clgv: using an embedded repl?

9:14 clgv: michaelr525: not necessarily. if you want one anyway, then you can do it like that. but you could also access it via http to trigger the reload

9:14 website style or webservice style. as you wish

9:21 michaelr525: clgv: oh

9:22 gmc_: \q

10:49 qerub: How would you check if all elements in a seq are equal? (apply = [1 1]) works fine except for the empty-seq case which gives ArityException. Spontaneously, I think that all elements of an empty seq should be considered equal; is this sane?

10:50 nDuff: qerub: you could reduce

10:51 ...though that's going to also not handle the empty-seq case

10:56 qerub: nDuff: I just noticed that the reduce function is called with zero args if the seq to reduce is empty. Interesting!

10:57 Ah, well, suppose I'll just branch and handle the empty-seq case separately.

10:59 clgv: qerub: how about (every? #(= % (first coll)) (rest coll)) ?

11:00 qerub: clgv: Good call!

11:00 I'm a bit tempted to do (every? (partial = (first coll)) (rest coll)) though.

11:00 I think we have a winner. Thank you.

11:04 TimMc: I vaguely recall a JIRA asking for (=) to return true.

11:22 gfredericks: what does embedding objects in code have to do with print-dup?

11:22 hyPiRion: ,(=)

11:22 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$-EQ->

11:23 hyPiRion: hrm, I was sure it returned true.

11:23 gfredericks: hyPiRion: do you think it should?

11:24 I can't decide if it makes sense or not

11:24 bawr: ,(= 1)

11:24 clojurebot: true

11:24 bawr: yeah, if it works for one argument

11:24 gfredericks: hyPiRion: it kind of gives you two base cases

11:25 hyPiRion: gfredericks: I consider (= x1 x2 x3 x4) as a reduction

11:25 gfredericks: some reductions don't make sense on an empty list

11:25 ,(reduce = [])

11:25 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core$-EQ->

11:25 hyPiRion: ,(reduce = true [])

11:25 clojurebot: true

11:26 hyPiRion: But it shouldn't be = anyway, it has to be wrapped somehow.

11:26 gfredericks: that still feels weird; the essense of the computation is checking if anything in that list (not= true)

11:26 ,(reduce = false [])

11:26 clojurebot: false

11:26 gfredericks: o_O

11:26 ,(reduce = 42 [])

11:26 clojurebot: 42

11:26 gfredericks: oh sure

11:26 ,(reduce = true [1 2 3])

11:26 clojurebot: false

11:26 hyPiRion: ,(reduce hash-map true [])

11:26 clojurebot: true

11:27 gfredericks: ,(reduce = true [1 1 1])

11:27 clojurebot: false

11:27 hyPiRion: gfredericks: You have to wrap it, sure

11:27 gfredericks: hyPiRion: I don't think you can make it work as reduce with any default value

11:29 hyPiRion: ,(let [foo [1 2 3]] (second (reduce (fn [[a x] b] [a (and x (= a b))]) [true (first foo)] (rest foo))))

11:29 clojurebot: false

11:29 hyPiRion: ,(let [foo [1 1 1]] (second (reduce (fn [[a x] b] [a (and x (= a b))]) [true (first foo)] (rest foo))))

11:29 clojurebot: false

11:29 hyPiRion: whaps

11:29 ,(let [foo [1 1 1]] (second (reduce (fn [[a x] b] [a (and x (= a b))]) [(first foo) true] (rest foo))))

11:29 clojurebot: true

11:29 hyPiRion: ,(let [foo []] (second (reduce (fn [[a x] b] [a (and x (= a b))]) [(first foo) true] (rest foo))))

11:29 clojurebot: true

11:30 hyPiRion: It's nil punning though, so I get your concern.

11:31 And Common Lisp treats is as an error.

11:32 gfredericks: print-dup is really weird.

11:59 callenbot: Raynes: speed, laziness

12:09 actsasgeek: I use slimv for my local repl needs. Is there a way to talk to a remote nRepl process? Is there an alternative for vim?

12:10 Apage43: actsasgeek: https://github.com/tpope/vim-foreplay

12:10 tomoj: Raynes: consider the "always 2 spaces" rule from the perspective of a gedit user

12:10 does it seem more attractive? :(

12:11 I don't want to litter every repo with M-q commits

12:11 actsasgeek: apage43 thanks.

12:11 tomoj: maybe I can write a git post-commit that automatically launches emacs and goes through and M-q's

12:12 hiredman: tomoj: have you see https://github.com/dakrone/lein-bikeshed ?

12:13 it doesn't have a check for 2 spaces, but if you can figure out a way to add one..

12:14 tomoj: well, the problem is emacs needs to be involved

12:14 or I need to defect to cemerick's side

12:14 technomancy: magnars: the [:require] thing is because of indentation

12:14 gfredericks: if you're not shelling out to emacs you must be doing something wrong

12:14 technomancy: magnars: using () means the first element is "special", using [] means all elements are peers

12:15 gfredericks: technomancy: we could also use #{} for all elements are peers and unordered :)

12:15 TimMc: technomancy: or pairs

12:15 gfredericks: e.g., (letfn #{(...) (...)} ...) :)

12:16 * TimMc votes for (let {foo 4, bar 6} (+ foo bar))

12:16 TimMc: (except that doesn't allow repeats, oh well)

12:16 tomoj: oh, nice

12:16 gfredericks: TimMc: and kills the ordering

12:16 TimMc: sshhhh

12:16 tomoj: I was hoping not to have to add a letrec

12:16 technomancy: yeah, it would work nicely for CL-style let though

12:16 S11001001: gfredericks: is a positive

12:16 gfredericks: S11001001: but what about all my imperative code?

12:17 tomoj: don't use a map

12:17 gfredericks: oh supporting both? that's interesting

12:17 S11001001: untagged unions &c

12:17 gfredericks: so vector let is available but smelly

12:17 S11001001: warn on vector let

12:18 warn on loop, warn on recur, warn on vec, warn on everything

12:18 tomoj: oh, you were discussing alternative let syntax, not an extended let?

12:19 ToBeReplaced: Today is excellent... coming back to clojure after a rage quit a few months ago to find the first conversation be a style conversation is the best! :)

12:19 S11001001: tomoj: you can just stick {} into let without breaking code, so w/e

12:19 except for code walkers

12:19 and macros that claim to work like let

12:20 TimMc: ,(let {a b, 5 6} (+ a b))

12:20 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: let requires a vector for its binding in sandbox:>

12:20 S11001001: but that's just the usual

12:20 TimMc: Worth a try.

12:20 tomoj: stick {} into let?

12:20 S11001001: yeah

12:20 like, supporting let in common lisp is actually pretty hard

12:20 someone, I think Gary King, wrote a library so that you could do it right

12:21 seangrove: Supporting let?

12:21 S11001001: writing a macro and saying "this part works like let"

12:21 that is, inheriting all let's features

12:22 gfredericks: (defmacro let's [& args] (cons 'do args))

12:22 S11001001: except not "inheriting" because what would be the point if you weren't doing special processing?

12:26 hyPiRion: How is that hard? You just do some lambda magic and voilà.

12:26 (let [a 10] (+ a 23)) => ((fn [a] (+ a 23)) 10)

12:27 seangrove: S11001001: Ah, got it

12:27 egghead: what do you guys think of prismatic's graph lib

12:27 seangrove: Emulating let then

12:28 egghead: https://github.com/Prismatic/plumbing

12:28 callenbot: https://github.com/bitemyapp/clojure-template-benchmarks does anyone have a benchmark idea or template library they'd like to pitch in?

12:28 S11001001: it's easy to implement let in your own macros, just expand to let. That's not the hard part. The hard part is when you want to say "this is like let, but..."

12:28 hyPiRion: S11001001: but what?

12:28 gfredericks: but lazy!

12:28 S11001001: but whatever your macro is for

12:28 seangrove: egghead: Looking to watch the talk today, not 100% sure about the use cases for it yet

12:28 gfredericks: but only allows destructuring up to 4 levels deep

12:29 egghead: seangrove: what talk is that?

12:29 hyPiRion: gfredericks: but lazy? Psh, that's easy

12:29 gfredericks: hyPiRion: is it?

12:30 hyPiRion: gfredericks: Fire up delays and wrap all names within derefs

12:30 gfredericks: hyPiRion: that second part has some edge cases I think

12:30 hyPiRion: After you macroexpand the whole shait, since you have to avoid overshadowing etc.

12:30 gfredericks: yeha

12:30 *yeah

12:30 S11001001: hyPiRion: also what's names?

12:31 gfredericks: hyPiRion: oh yeah destructuring would be difficult

12:31 S11001001: hyPiRion: now you've declared that your macro is sensitive to the exact specification of the destructuring language.

12:31 hyPiRion: S11001001: I am using common lisp, go away

12:32 seangrove: egghead: Can't seem to find the strangeloop conference talk

12:32 S11001001: hyPiRion: So instead of the let destructuring problem, you have the DECLARE problem. That's even harder.

12:32 hyPiRion: S11001001: declare problem? Elaborate

12:33 S11001001: (let (a b c d) (declare some-stuff-about-a-b-c-or-d some-other-stuff) (declare yet-again) ...)

12:33 Now you want to do special processing on a, b, c, d that splits up the let

12:33 egghead: seangrove: ah, you mean the 'going faster with clojure' talk cross did?

12:33 http://www.infoq.com/presentations/Why-Prismatic-Goes-Faster-With-Clojure ?

12:33 S11001001: First, you have to cut up the DECLAREs into what talks about a, what talks about b, etc

12:34 and that's CL implementation specific, never mind that you have to parse every standard DECLARE form

12:34 seangrove: No, I think "Graph: composable production systems in clojure"

12:34 S11001001: a single declare can talk about multiple bindings so you have to distribute and duplicate in the right places

12:34 gfredericks: egghead: that talk was at clojure/west

12:35 S11001001: then if you introduce gensyms, say to simulate parallel let, you have to rewrite all the declares to talk about those, e.g. DYNAMIC-EXTENT

12:35 seangrove: Apparently the talk should have been made available a few days ago

12:35 hyPiRion: S11001001: Argh, you make my life frustrating

12:35 S11001001: hyPiRion: no, that would be X3J13 :P

12:36 seangrove: But I'll definitely check out that talk as well

12:37 hyPiRion: in hindsight though, making an e.g. lazy let would be very much in compiler land

12:37 You've got to do semantic analysis, IR and error handling

12:38 gfredericks: hyPiRion: I tried to make an eager version of fn; that was also hard

12:38 hyPiRion: gfredericks: eager version of fn?

12:38 Are you trying to implement let?

12:39 gfredericks: hyPiRion: it was to support currying; so if you have (curried-fn [a b c] ...) and you call it with two args, it precomputes anything not dependent on c

12:39 hyPiRion: gfredericks: Good luck on that.

12:40 gfredericks: hyPiRion: it pretty-much works: https://github.com/fredericksgary/currj

12:40 hyPiRion: currj, hahah. Sounds like curje.

12:41 but spoken like courage, hm.

12:42 gfredericks: Tell me whenever you want to make a haskell compiler in Clojure, I'll be up for it.

12:42 gfredericks: I always want to do that.

12:44 hyPiRion: you mean compiling haskell src to assembly?

12:44 hyPiRion: gfredericks: to Clojure.

12:44 It'd be Haskell on top of Clojure on top of JVM on top of Assembly.

12:44 tomoj: why not a liskell in clojure?

12:44 gfredericks: yeah that's something I've thought of more often

12:45 is apply impossible?

12:45 I feel like you couldn't implement update functions like update-in

12:48 SegFaultAX: hyPiRion: That's actually not possible.

12:49 hyPiRion: SegFaultAX: What's not possible?

12:55 I can't see any reason why a Haskell-to-Clojure compiler isn't doable.

12:56 * gfredericks seconds that

13:13 technomancy: anyone got opinions about configuration of the repl task in leiningen? got a particularly tricky decision around :init-ns discussed here: https://github.com/technomancy/leiningen/pull/963

13:14 trying to decide how much of Leiningen it makes sense to expose to the project and wondering what kind of configuration changes you might want to make that would need to be visible at runtime rather than just at repl launch.

13:37 patchwork: Hey all, anyone have a clue what is going on here? http://stackoverflow.com/questions/14611033/clojure-leiningen-project-suddenly-broken-what-would-cause-this-maven-error

13:37 I am having a dependency issue with jackson-core-asl

13:37 just suddenly stopped working!

13:37 something about a bad checksum?

13:37 technomancy: patchwork: typically a botched deploy to maven central or possibly a corrupt mirror

13:38 patchwork: technomancy: What can I do about it?

13:38 technomancy: patchwork: first suggestion would be to try an older version. if that doesn't work, you can update :repositories to set the :checksum setting for central to :ignore

13:39 patchwork: technomancy: But I am not including it directly in my project, some other dependency depends on it

13:39 Also, it seems it is downloading every pom jackson has. I'm certain I don't need all these

13:40 hyPiRion: :exclude then

13:40 and reinclude

13:40 llasram: Sounds like someone setting a version-range to me

13:40 patchwork: I will try setting the :checksum to :ignore

13:40 crazy!

13:40 llasram: ("someone" being a dependency library, not you yourself patchwork)

13:41 hyPiRion: e.g. [ other deps here [foo "1.0.1" :exclude [bar baz]][bar "2.0.0"] [baz "0.4.0"]]

13:41 technomancy: unfortunately currently you can't get a deps tree to identify the offender when resolution fails. (there's an open ticket for that)

13:42 I don't recommend keeping :checksum at :ignore, but it can be useful to debug

14:02 ChongLi: version-ranges are one of the big reasons for cabal hell, right?

14:03 TimMc: "cabal hell"?

14:03 ChongLi: in haskell

14:03 TimMc: That's a new one for me.

14:03 hyPiRion: cabal hell is funny

14:04 ChongLi: it's very easy to get into a situation where dependency resolution always fails

14:04 hyPiRion: `cabal install cabal-install`

14:04 ivaraasen: hyPiRion: just got accepted into KOMTEK btw :)

14:04 pretty psyched

14:05 hyPiRion: ivaraasen: oh, grats!

14:05 You're one of us now, muha.

14:05 technomancy: if you've been skeptical of the requirement to sign jars you release, please read https://news.ycombinator.com/item?id=5139583 kthxbai

14:06 joegallo: phil, i never agreed with you until now. now i get it.

14:08 hyPiRion: joegallo: you've never agreed with technomancy ever until now, or on signing jars?

14:10 joegallo: lacking a witty response, just on the jars things

14:11 technomancy: heh

14:16 pgmcgee: \quit

14:18 hyPiRion: /quit

14:19 technomancy: clojurebot: alioth is http://www.ro-che.info/ccc/02.html

14:19 clojurebot: 'Sea, mhuise.

14:20 brehaut: technomancy: lol

14:25 hyPiRion: Uh..

14:25 ,[(+) (+ 1) (+ 1 2) (+ 1 2 3)]

14:25 clojurebot: [1 1 3 6]

14:26 TimMc: *Someone* has done something naughty.

14:26 * hyPiRion walks away

14:27 TimMc: ~suddenly

14:27 clojurebot: suddenly is !

14:27 TimMc: clojurebot: forget suddenly |is| !

14:27 clojurebot: I forgot that suddenly is !

14:27 TimMc: ~suddenly

14:27 clojurebot: CLABANGO!

14:28 anars: (1)

14:40 TimMc: ,(class +)

14:40 clojurebot: clojure.core$_PLUS_

14:40 TimMc: ,(+)

14:40 clojurebot: 0

14:40 hyPiRion: ,(class +)

14:40 clojurebot: sandbox$eval128$fn__129

14:40 hyPiRion: *shrug*

14:40 gfredericks: repeat question: what do objects embedded in code have to do with print-dup?

14:41 hiredman: well, one way to embed objects in bytecode is to print dup them and then read them back in

14:41 TimMc: gfredericks: Records, originally, I think.

14:45 gfredericks: hmmm

14:46 hiredman: that makes a striking amount of sense.

14:46 how are vars referenced in bytecode?

14:46 hiredman: not like that

14:46 gfredericks: I figured not :)

14:48 hiredman: all the vars reference in a function actually go in to the functions constant pool (just a set of static final fields)

14:48 and there is a static init method for functions that sets the value for the constant pool fields

14:48 gfredericks: ah

14:48 hiredman: which for each var does something like constant_pool_field = RT.var("clojure.core", "+")

14:49 and where vars are used in the function, the bytecode reads from the fields instead of looked up via the namespace map over and over

14:50 gfredericks: that makes sense; so it has the strings to reference the var but they're only used on class init

14:50 so similarly to embed an arbitrary object you need a string representation and then to reconstruct it

14:50 hiredman: hotspot is unlikely (unable?) to inline across a map lookup, but the map lookup is removed from the execution path this way

14:51 gfredericks: that sort of depends

14:51 gfredericks: so I had previously concluded that arbitrary data readers couldn't be used in code because of these issues, but it sounds like you would just define print-dup for the offending type and then it would be okay

14:53 hiredman: I have some patches to the compiler that make it easier for classes that know how to do their own constant pool thing to embed themselves in the bytecode

14:54 https://github.com/hiredman/clojure/commit/9c3d863f5c5701f5bfb0cf669b7a0362391ce5b6

14:54 https://github.com/hiredman/clojure/commits/reflection-method-caching

14:56 when pjstadig brings up invokedynamic for clojure rich has mentioned he is interested in using invoke dynamic for vars

14:56 ChongLi: technomancy: what's the best way to (repeatably) install an emacs package that's not in a repo?

14:56 hiredman: which would, I think, replace the constant pool mechanism with an invokedynamic switchpoint

14:56 technomancy: ChongLi: you can do M-x package-install-file

14:57 that will do byte-compilation and autoloads

14:57 ChongLi: ah ok

14:58 I wish there was some way to pull stuff down from github the way vim has vundle and pathogen

14:58 I guess pathogen doesn't

14:58 technomancy: ChongLi: there is also el-get and marmalade

14:58 err--melpa

14:58 ChongLi: yeah I have melpa

14:58 technomancy: I don't like melpa because it's not selective though; there's no way to say "only get package X from git and use stable releases for the rest"

14:58 ChongLi: it's almost always best to just get a lib into marmalade

14:59 ChongLi: So to remedy this there is a melpa.el package–available in MELPA–that will allow you to enable only certain packages or exclude certain packages. You can install the package manually by pasting this into yoru *scratch* buffer and evaluating it.

14:59 technomancy: it's so easy to do, provided you can contact the maintainer

14:59 ChongLi: huh; interesting

14:59 ChongLi: well in this case it's just a color theme

14:59 technomancy: ChongLi: I'd be more interested in a melpa that only built from tags instead of git master

14:59 ChongLi: I don't think the maintainer is around

14:59 that would be sweet

15:00 technomancy: yeah, in that case something like el-get may be the right choice

15:00 gfredericks: can we make emacs run on nix?

15:00 technomancy: I don't like el-get as a default because it discourages proper release hygiene

15:00 gfredericks: port nix to elisp, or package elisp with nix?

15:00 gfredericks: technomancy: the latter

15:01 technomancy: gfredericks: most of nix works in terms of PATH and LD_LIBRARY_PATH, you'd have to teach load-path how to be nix-savvy

15:02 definitely doable

15:02 but getting community buy-in would be more difficult

15:03 if elisp had a module system you could do some amazing things with in-process checksum-scoped packages, but alas.

15:05 gfredericks: let's just stop making software for a decade and instead just make everything work with everything else

15:05 the business people can wait.

15:06 technomancy: I'm for it

15:07 gfredericks: at the end of the exercise we will have "X works with Y" and "X compiles to Y" are always true

15:07 TimMc: Excel compiles to irssi.

15:07 Sounds legit.

15:08 hyPiRion: gfredericks: for any value of X and Y?

15:08 seangrove: irc is just a strange machine. No problem.

15:08 TimMc: heh

15:08 gfredericks: hyPiRion: only statements that could reasonably be said to be false

15:08 hiredman: weird machine

15:09 hyPiRion: Irssi compiles to Excel.

15:09 I wouldn't be surprised if there were some excelbot.

15:09 seangrove: hiredman: You're right, my bad.

15:09 hiredman: invokedynamic might also be a way to bring omops to the jvm, which would be kind of neat

15:11 melipone: hello! How can I tell if a number is Infinity in clojure?

15:12 hiredman: http://soft.vub.ac.be/~smarr/research/omop/

15:12 TimMc: &(Double/isInfinite Double/POSITIVE_INFINITY)

15:12 lazybot: ⇒ true

15:13 TimMc: &(Double/isInfinite 6)

15:13 lazybot: ⇒ false

15:13 TimMc: &(Double/isInfinite (Long. 6))

15:13 lazybot: ⇒ false

15:13 melipone: TimMc: thanks!

15:16 gfredericks: &(Double/isFinite 7)

15:16 lazybot: java.lang.IllegalArgumentException: No matching method: isFinite

15:24 callenbot: weavejester: https://github.com/bitemyapp/clojure-template-benchmarks Is there anything particularly pathological about the hiccup code here?

15:24 TimMc: gfredericks: Apparently *someone* at Sun thought there was an excluded middle.

15:25 What am I gonna do with these transfinite numbers?

15:26 lerkbot: howdy

15:26 hmm

15:26 weavejester: callenbot: The hiccup code isn't optimised at all in those benchmarks

15:27 gfredericks: am I evil for using user.clj to setup print-method stuff for joda DateTimes?

15:27 ibdknox: also, for whom is templating the bottleneck?

15:29 headshot: ah, much better

15:29 anyway: http://skillsmatter.com/podcast/home-27/clojure-at-nokia-entertainment/mh-6531

15:29 interesting preso

15:30 weavejester: ibdknox: That's one of the reasons I've been meaning to change Hiccup to write to DOM structures instead. Slower, but more flexible.

15:30 brehaut: ibdknox: people with uninteresting sites

15:31 ibdknox: weavejester: DOM structures?

15:31 weavejester: ibdknox: Like clojure.xml

15:31 ibdknox: brehaut: haha

15:31 ah

15:32 brehaut: (ibdknox which is to say its a bottleneck on my site i think ;)

15:32 ibdknox: lol

15:32 brehaut: of course uninteresting sites are trivially cachable

15:34 augustl: with clojure.java.jdbc, how do I insert records for multiple tables in one transaction?

15:35 hmm, seems I can just wrap it in a transaction, that will absorb the inner-most ones

15:45 weavejester: callenbot: Is bitemyapp your Github login?

15:52 rboyd: how I feel when the team keeps cranking out more ruby http://www.youtube.com/watch?v=0eBrb00pdGw

16:19 N8Dawg: Hi room, I've been looking through the Clojure source code, Compiler.java is a monster, anyone know of any plans to rewrite in Clojure?

16:19 brehaut: many plans, little action

16:20 N8Dawg: brehaut: any idea on who to collaborate with?

16:20 brehaut: N8Dawg: i fear you may need to dive into the jira for that

16:21 cemerick: N8Dawg: A couple of people have forked and done exactly that, though they've dribbled out into experiments rather than maintained alternatives.

16:21 SegFaultAX: There are a few key classes in clojure that have attained beastly proportion.

16:21 augustl: does mysql have anything like datomic tempids..?

16:21 gfredericks: is rich not terribly interested?

16:21 SegFaultAX: RT.java is another that comes to mind.

16:21 cemerick: kanaka's clojurescript self-hosting work is the furthest anyone's driven this sort of work

16:22 brehaut: N8Dawg, cemerick: i recall that clojurescript was a sort of proof of concept / step along the way?

16:22 cemerick: brehaut: my vague speculation is that it's far beyond that in terms of projected scope

16:23 N8Dawg: cemerick, brehaut: I'm thinking it doesn't actually have to be so complex, lets assume macro expansion is done prior, what am I not getting?

16:24 cemerick: any re-think of Clojure must bootstrap up to protocols and types to make it worthwhile

16:24 (IMO)

16:25 N8Dawg: cemerick: surely its just a function: (compile-to-bytecode form) => byte-array

16:26 cemerick: I'm trying to get a handle on the complexities i must be missing

16:27 kanaka: N8Dawg, brehaut, cemerick: my port is almost self-hosting. It has macros, protocols, types, etc. Using it to compile core.cljs (including what lives in core.clj in the upstream ClojureScript) is in-progress and tricky because of the multi-level interaction between namespaces, macros and the analyzer/compiler state.

16:28 N8Dawg: kanaka: sounds like you've had first-hand experience of this! whats the multi-level interaction between macros and compiler?

16:29 cemerick: N8Dawg: I am by no means the resident expert on Clojure compiler bootstrapping, but yes, you're missing a range of complexities.

16:29 gfredericks: keep reading Compiler.java and you'll probably get a feel for it :)

16:30 * gfredericks is turning into hiredman

16:30 kanaka: N8Dawg: just the compiler/emitter part without macro expansion isn't too hard to port. There is some trickiness around namespaces/var but it's not too bad (i.e. you have to keep the namespace/var information around for execution time).

16:32 N8Dawg: kanaka: right i get the namespace var stuff, thats for thread local bindings, defs which are declared *dynamic*

16:32 cemerick: kanaka: BTW, those hearing news of your work at the FP meetup last night were duly impressed by the concept :-)

16:32 That is to say, carry on.

16:32 kanaka: N8Dawg: hold on, let me find you a diff.

16:32 N8Dawg: cemerick: sounds interesting… what is it?

16:33 kanaka: cemerick: cool, I'll be talking about it at Clojure/West if there interested enough to spend money ;-)

16:34 cemerick: kanaka: spend money?

16:34 Commercial cljs fork FTW! ;-P

16:34 N8Dawg: what's what?

16:34 N8Dawg: kanaka, cemerick: whats the concept, i'm being nosey…

16:34 kanaka: cemerick: no no. I mean if they want to buy tickets to Clojure/West then can hear me talk about it. Or they can wait until the video is published too.

16:35 callenbot: weavejester: yes it is

16:35 weavejester: you are welcome to fixxit.

16:35 cemerick: N8Dawg: https://github.com/kanaka/clojurescript/

16:35 weavejester: callenbot: Sent you a pull request

16:35 callenbot: With type hints, Hiccup should only be a little slower than "str"

16:36 TimMc: Man, I should publish *my* poorly optimized templating code as a benchmark.

16:36 callenbot: hrm, okay. I usually don't let type hints slide.

16:36 TimMc: That'll get it fixed for free! :-D

16:36 callenbot: weavejester: I'm going to reject the PR, but integrate a separate type-hinted version of the hiccup benchmark.

16:36 weavejester: callenbot: Sure thing

16:37 kanaka: N8Dawg: clojurescript.net is the online version of that. Basically a ClojureScript REPL entirely client-side (no JVM behind the scenes).

16:38 N8Dawg: kanaka: sweet, i can't help but thinking, that for Clojure, 90% of the compiler pipeline should be able to be shared between host platforms, with just the emiter being different

16:39 callenbot: weavejester: thanks for submitting the improvement!

16:40 weavejester: callenbot: Comb is another templating engine that should have near-str performance: https://github.com/weavejester/comb

16:41 callenbot: weavejester: note stencil's results - is it possible to add caching/memoization to hiccup?

16:41 kanaka: N8Dawg: https://github.com/kanaka/clojurescript/compare/master...cljs_in_cljs The November commits are basically the analyzer (without macro expansion) and the compiler ported to Cljs. The work since is fixes to that and everything else.

16:41 callenbot: weavejester: like what stencil has that is. I don't think most template writers are going to type-hint their views so I'm seeking a "practical" way to close the gap with partial compilation and caching.

16:42 weavejester: callenbot: Type hints are really only there for when you need performance, in both Clojure and Hiccup.

16:42 Usually the performance of templating engines is not your bottleneck.

16:43 kanaka: N8Dawg: a good chunk of the Clojure compiler is Java of which the compiler/emitter is a fairly small part. A good chunk of the ClojureScript compiler relies on that. Some of what I've been doing in cljs-in-cljs is porting the Java code in the Clojure compiler to ClojureScript.

16:43 callenbot: weavejester: usually, yes. but I enjoy this stuff. I'd still like to know what it would take to speed up hiccup absent type-hints.

16:46 kanaka: N8Dawg: but really, the complex part is namespaces and vars. Those two things are Java concepts/objects. They are _mutable_ data structures. There are a lot of subtle assumptions about how namespaces and vars and implemented and interact that have no analog in running ClojureScript programs (because they are gone by that point).

16:47 weavejester: callenbot: Might be tricky to speed it up much further. The type of a variable depends on how it's interpretted by Hiccup, and reflection in Java is much slower than pre-compiled types.

16:49 kanaka: N8Dawg, cemerick: one example of changes required for cljs-in-cljs (not related to namespaces/vars): symbols in ClojureScript are special prefixed strings which mean they can't hold metadata. The type/protocol code relies on passing around metadata on symbols. I re-implemented symbols as first class objects.

16:51 N8Dawg: I have to get back to my real job now, but just as another example, ClojureScript relies on Clojure's reader. There is a partial reader implemented in ClojureScript. I had to expand that by porting from Clojure's Java reader code (syntax quote/unquote, anonymous functions, etc).

16:52 hiredman: syntax quote is nuts

16:53 I tried to graph the flow control through the syntax quote code in the reader a few years ago http://www.thelastcitadel.com/images/syntax.png

16:53 kalizga: i keep wondering what :tag ; :dynamic, :static etc. do in context of DEFN forms .. especially in clojure.core fns .. i can't find any documentation on these things .. ?

16:54 N8Dawg: kanaka: thanks for that! I'll have more of a dig through

16:54 kanaka: N8Dawg: read through that changeset I sent. Once you somewhat grok that, and if you're still interested, jump on #cljs-in-cljs.

16:55 kalizga: it's metadata that gets set on the var that the def* form creates that affects the behavior of the analyzer (for the most part).

16:55 cemerick: hiredman: bizarrely, that image won't open in FF

16:55 Bronsa: it did on mine

16:56 hiredman: huh, opens in my firefox

16:56 I'm on 19.0

16:56 kanaka: hiredman: here is the initial port I did (there are bugs in it fixed in later commits): https://github.com/kanaka/clojurescript/commit/0345cadd2d3e3edda65d1f8616da8d4c55bce38e

16:56 cemerick: 18 here; "the image ... cannot be displayed because it contains errors" *shrug*

16:57 kanaka: hiredman: it's not particularly idiomatic because it's a fairly one-to-one port of the Java code.

16:57 cemerick: hiredman: quite a stunning diagram

16:57 hiredman: kanaka: you might look in to using some of the syntax-quote as a macro stuff

16:58 kanaka: hiredman: I'm missing the reference.

16:58 hiredman: kanaka: https://github.com/brandonbloom/backtick

16:59 I have a simpler version with less features (maybe more bugs?) that might be easier to get running in cljs https://github.com/hiredman/syntax-quote/blob/master/src/syntax_quote/core.clj

16:59 kanaka: hiredman: oh right, yeah. I saw that a few weeks after I did the initial port. It's on my list to circle back around to see if it would be cleaner to incorporate that.

16:59 hiredman: having it in the reader is gross

16:59 Bronsa: you can consider also blind's implementation https://github.com/Bronsa/blind/blob/master/src/blind/reader.clj#L762

17:00 bbloom's implementation is actually really nice, but it depends on clojure's syntax-quote implementation rather than completely re-implementing it

17:02 kanaka: hiredman, Bronsa: cool. I've noted these so I won't forget: https://github.com/kanaka/clojurescript/issues/25

17:06 Bronsa: also kanaka, have a look at blid's StringPushbackReader, it should be faster than the one clojurescript was using

17:09 kanaka: Bronsa: you have a link?

17:10 Bronsa: you might be interested in https://github.com/Bronsa/blind/blob/78b64980d19c91df904dcf90b01c42b15beeaeae/src/blind/reader.clj#L42-L148

17:10 except the InputStreamReader

17:11 meh. I can open a pull request tomorrow if you want anyway

17:13 kanaka: Bronsa: sure. It's Clojure so there will be some adjustment needed, but it looks like it might be straight forwards to port.

17:16 Bronsa: I have a half done implementation of a line numbered reader for error reporting, but that one has column reporting too, so bonus.

17:17 Bronsa: right, do you want the peek-char stuff too?

17:17 it's used in some places to avoid the read-char && unread pattern

17:18 kanaka: Bronsa: yeah, definitely.

17:29 Raynes: callenbot: Type hinting the laser code speeds it up a bit too. Not sure if it's worth adding a test for, but you should try it and see what your results are.

18:21 headshot: asdf

18:35 seangrove: Has anyone used ClojureCheck and found it to be worthwhile?

18:55 Rich_Morin: I'm filling in the "Rich Hickey Contributor Agreement" for clojure and clojure-contrib. However, I'm not sure exactly what what to put in Project name. Help?

19:10 hyPiRion: Rich_Morin: Clojure should do

19:11 Rich_Morin: tnx

19:14 rplaca: I was just playing with endorsements on LinkenIn and it asked me "Does Rich Hickey know about Clojure?" Talk about a "we are not worthy!" moment :)

19:18 hyPiRion: rplaca: Yeah, someone else mentioned that

19:18 It's funny

19:18 TimMc: "Does the Pope know about beanies?"

19:20 Rich_Morin: A couple of decades ago, a "suit" was standing in line behind a pony-tailed graybeard at a USENIX conference. To make conversation, he asked "So, have you been using Unix very long?". Dennis said yes.

19:22 amphtrox: anyone know were i can find a good explanation on macros?

19:28 patchwork: amphtrox: http://www.paulgraham.com/onlisp.html

19:32 bawr: Rich_Morin: Ritchie had a ponytail at some point?

19:32 Rich_Morin: Other than that, it's a great story. ^^

19:35 TimMc: bawr: Of *course* he did, he wouldn't be an Elder if he didn't.

19:35 Sheesh.

19:37 Rich_Morin: "He's probably best known for his long palindromes. Those of you in science fiction fandom may know him as chair of Disclave '95, as a member of WSFA and PRSFS, and as the guy with a beard and ponytail who was always playing with variants of Rubik's Cube at conventions."

19:37 bawr: TimMc: Photographic evidence suggests that dmr was the beard guy, but even that was well-kept.

19:37 Think Dijkstra.

19:37 Rich_Morin: http://alt.folklore.computers.narkive.com/RTG3MWCL/dennis-ritchie.2

19:38 bawr: Ken was the wild hair one.

19:38 amphtrox: patchwork i assume lisp and clojure macros are very much alike? anyway, looks helpful, thank you :)

19:39 bawr: Aren't Clojure macros hygienic by default, making them more like Scheme?

19:40 technomancy: clojure macros solve the same flaws of CL macros as scheme macros do, but in a much simpler way

19:40 TimMc: Right, I don't think you can accidentally make an unhygienic macro in Clojure.

19:40 bawr: technomancy: is there an article / blog post somewhere that does a compare and contrast?

19:41 technomancy: bawr: there are some overviews written by extremely ranty scheme fanatics, but I couldn't point you to that in good faith

19:41 bawr: Yeah, I see.

19:41 technomancy: if you just read stuff about CL macros and ignore everwhere it talks about symbol capture and needing to call gensym, you'd be good

19:42 bawr: Why don't you need genym in Clojure, though?

19:43 technomancy: because ` auto-qualifies all symbols

19:44 bawr: I'm not sure if I understand. Is it sort of like a namespace thing?

19:46 amalloy: &`(let [x 1] x) is a class of error you can't make in clojure: in CL, that x might shadow a user's x

19:46 lazybot: ⇒ (clojure.core/let [clojure.core/x 1] clojure.core/x)

19:46 TimMc: ,[`foo 'foo]

19:46 clojurebot: [sandbox/foo foo]

19:46 amalloy: &`(let [x# 1] x#) solves the problem by asking the compiler (really, the reader) to do all the gensym fiddly bits for you

19:46 lazybot: ⇒ (clojure.core/let [x__85869__auto__ 1] x__85869__auto__)

19:47 bawr: Oh, I see.

19:47 Neat.

19:48 TimMc: Mind you, x# is only consistent inside a single syntax-quote -- if you want consistency across several, you need to call gensym yourself and unquote the symbol into the code.

19:48 &`[x# ~`x#]

19:48 lazybot: ⇒ [x__85903__auto__ x__85902__auto__]

19:48 bawr: ,[`foo `foo 'foo `[foo foo]]

19:48 clojurebot: [sandbox/foo sandbox/foo foo [sandbox/foo sandbox/foo]]

19:50 bawr: ,[`x# `x# 'x# x# `[x# x#]]

19:50 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: x# in this context, compiling:(NO_SOURCE_PATH:0)>

19:50 bawr: ,[`x# `x# 'x# `[x# x#]]

19:50 clojurebot: [x__107__auto__ x__108__auto__ x# [x__109__auto__ x__109__auto__]]

19:50 bawr: Oh, now I see.

19:50 patchwork: All in all, Graham's On Lisp has the best discussion of macros I've found in general, as long as you are mindful of the (minor) differences

19:50 bawr: Did you guys read Let Over Lambda?

19:50 clojurebot: let* is ##(let [[x y] [1 2]] (+ x y))

19:51 patchwork: bawr: Yeah! Great book, the guy wrote it as kind of a sequel to On Lisp

19:51 even though they are two different authors

19:52 bawr: Aye.

19:52 patchwork: it goes more in depth into some things graham introduces, and has some crazy macro acrobatics as well

19:52 amalloy: let over lambda is...okay. there's some instructive stuff in there, but you have to (a) put up with his contempt for any lisp but CL, and (b) not mind the fact that most of the macros are about mutating things

19:52 bawr: I skimmed it, but I'd really need to read On Lisp first, I guess.

19:54 patchwork: amalloy: Forgot about the non-CL hate, he is kind of ridiculous at times

19:55 but the book has a giant LOL on the cover, I took a lot of it with a grain of salt

19:56 Mainly, the stuff I saw him do with macros I haven't seen anywhere else, kind of a tour de force to show to what ridiculous extremes you can take it

19:57 But not necessarily practical. More for mind opening than for day to day use

19:59 bawr: I don't remember seeing non-CL hate, actually. Guess I didn't skim deep enough. :>

20:07 ChongLi: technomancy: hey, vivid-chalk.el has your name on it

20:08 technomancy: you're all over the place!

20:08 hiredman: ls

20:08 lazybot: data dev etc home lost+found media proc sbin srv swap sys usr

20:28 gfredericks: clojurebot: cd data

20:28 clojurebot: datatype is see datatypes

20:28 amalloy: gfredericks: ITYM lazybot

20:29 callenbot: Raynes: I'm not opposed to adding it. More data is more data.

20:49 gfredericks: amalloy: oh. I did didn't I.

20:50 I saw hiredman talking to a bot and just assumed it had to be clojurebot.

20:58 ppppaul: what is the accepted way of converting a string to an int/long in clojure?

20:58 i've been using (Long. "234")

21:00 hiredman: Long/parseLong

21:00 ppppaul: &(Long "123")

21:00 lazybot: java.lang.RuntimeException: Expecting var, but Long is mapped to class java.lang.Long

21:01 ppppaul: &(parseLong"123")

21:01 lazybot: java.lang.RuntimeException: Unable to resolve symbol: parseLong in this context

21:01 ppppaul: example?

21:01 clojurebot: api examples is http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples

21:01 brehaut: last edited july 2010

21:01 good work clojurebot

21:02 xeqi: &(Long/parseLong "123")

21:02 lazybot: ⇒ 123

21:02 ppppaul: i want to do a when-let, but with 2 + symbols defined

21:02 is that possible without nesting?

21:02 thanks brehaut

21:02 brehaut: ppppaul: ?

21:03 xumingmingv: &(Long. "123")

21:03 lazybot: ⇒ 123

21:03 ppppaul: i find myself doing a lot of (when (and ....

21:03 xumingmingv: &(do (Long. "123") (System/exit 0))

21:03 lazybot: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)

21:03 ppppaul: i want to do (when-let [a (something) b (something)])

21:03 gfredericks: ppppaul: you can write a macro to do it

21:03 ppppaul: and execute only when both a & b are true

21:04 gfredericks: ppppaul: should the second something be evaluated if a is false?

21:04 ppppaul: no

21:04 or yes... don't matter to me actually

21:04 i'm wondering if this is done already (i assume it is)

21:06 gfredericks: (defmacro when-lets [pairs & body] `(let [~@pairs] (when (and ~@(->> pairs (partition 2) (map first))) ~@body)))

21:06 ppppaul: oh sexy

21:06 gfredericks: doesn't work with destructuring

21:06 ppppaul: i'm going to try that

21:06 wish i could write macros that fast

21:06 gfredericks: I wish I got paid to write macros that fast

21:07 ppppaul: i get paid to do clojure :)

21:07 gfredericks: I do too but it's always build stuff never "write macros that fast"

21:07 amalloy: ppppaul: don't be too hard on yourself, his looks a bit rubbish

21:07 ppppaul: lol

21:07 gfredericks: also when you write macros like me you have to put up with amalloy coming behind you to point out why it's crap

21:07 ppppaul: amalloy, will that macro work? i haven't tried

21:07 amalloy: since it evaluates b even if a is nil

21:07 gfredericks: amalloy: he specifically said that was okay

21:07 I asked

21:08 xeqi: previous discussion on if-let/multiple bindings: https://groups.google.com/forum/?fromgroups=#!searchin/clojure/let-else/clojure/1g5dEvIvGYY/EWjwFGnS-rYJ

21:08 ppppaul: oh thanks xeqi

21:08 amalloy: then it looks like it would work, yes

21:08 gfredericks: amalloy: but also (when-lets [[a b] nil] ...) should behave wrong

21:08 amalloy: that too

21:09 ppppaul: abstract macro makes me cry

21:09 gfredericks: abstract macro?

21:09 ppppaul: i consider it a bit abstract

21:10 though, maybe all macros to me would be abstract

21:10 gfredericks: come to clojure/west

21:10 ppppaul: i've only written a few for dealing with testing with datomic and ring

21:11 gfredericks: http://clojurewest.org/sessions#fredericks

21:11 ppppaul: ^_^

21:14 amalloy: anyway, when-lets is actually easier to write without those wrinkles than with them: https://www.refheap.com/paste/9120

21:16 gfredericks: amalloy: I will be disappointed if you don't come to the talk and heckle

21:16 amalloy: brace yourself for disappointment then, i'm afraid

21:16 * gfredericks plans to prace

21:16 * gfredericks brace

21:18 ppppaul: holy shit xeqi thanks for the google group thread. it was a very interesting read

21:24 i will prace too

21:25 that's a pretty sexy macro amalloy

21:32 TimMc: Speaking of recursive macros, I wonder if that ->> bug is going to get fixed for 1.5.

21:33 amalloy: TimMc: did the patch not get applied? i thought it was going to

21:34 TimMc: amalloy: I don't know, you tell me: http://dev.clojure.org/jira/browse/CLJ-1121

21:35 amalloy: wait, what the hell is the format of the "Created" field in jira? i tried to sort by it

21:35 but the entries include "12/Jul/20" and "17/Jul/20"

21:35 that first one could be july 20th 2012, but the second????

21:36 TimMc: amalloy: It uses the Mayan calendar, actually.

21:36 tomoj: some of the dates are in fact in 2020

21:36 both of those, presumably

21:37 amalloy: so time travel is the only explanation

21:37 TimMc: yeah, looks like it wasn't. i thought http://dev.clojure.org/jira/browse/CLJ-1086 had been, since it was simpler and earlier

21:37 brehaut: its most significant digit year format

21:38 tomoj: that's why the chart is all fucked up at http://dev.clojure.org/jira/browse/CLJS

21:38 brehaut: who needs to know more than a millennium and century anyway

21:38 amalloy: hahaha

21:39 nice chart

21:40 TimMc: brehaut: That's distressingly believable.

21:40 tomoj: I never thought to post about it because I assumed people had noticed the chart and didn't care enough

21:40 brehaut: TimMc: it wouldnt be the most messed up date formating ive seen

21:40 TimMc: I don't think you can even get that from a standard formatter.

21:41 gfredericks: yay for CLJ-1153

21:41 brehaut: TimMc: people do like to work at making dates hard

21:43 amalloy: guys the comments in http://dev.clojure.org/jira/browse/CLJS-4 are especially good

21:45 just chouser, stopping by from nine years in the future to let us know that, as expected, it's Later

21:45 brehaut: ha

21:46 tomoj: "ordinary macros can act as compiler macros in cljs. Just define a macro with the same name as the function" huh?

21:46 brehaut: its remarkable that it was created on 17/jun/20 but fixed on 23/sep/11

21:46 tomoj: oh

21:46 TimMc: Oh, is this a result of the importer?

21:46 tomoj: does it break if the ns with the fn and the ns with the macro have the same name?

21:47 gfredericks: tomoj: probably not

21:47 tomoj: brehaut: sql constraints in action?

21:47 amalloy: tomoj: (defmacro + [x y] `(fast-javascript-addition ~x ~y)) (defn + [x y] (slow-whatever x y))

21:47 TimMc: It's not just formatting: "Wednesday, June 24, 2020"

21:47 tomoj: s/in action/inaction/

21:47 gfredericks: tomoj: the interesting part is that (foo 1) uses the macro and (map foo []) uses the function

21:47 tomoj: amalloy: right, in separate ns's

21:47 amalloy: then if you write (+ x y) you get the fast version, but if you write (map + xs ys) you get the function

21:47 gfredericks: tomoj: based on whether or not it is at the front of the form

21:48 TimMc: This is like inlining.

21:48 amalloy: tomoj: the macro must necessarily be in a different ns, because cljs doesn't have macros?

21:48 so that's not really a relevant constraint

21:48 ajn: I'm wondering if I can do a comparison inside a doseq to populate a vector? This is what I have. https://gist.github.com/4679523

21:48 gfredericks: amalloy: you could have a clj ns with the same name though, right?

21:48 tomoj: but, what if they have the same name? :)

21:48 amalloy: don't populate a vector from a doseq. doseq is for side effects

21:48 gfredericks: (ns foo.bar (:require-macros [foo.bar :as fb]))

21:48 ajn: amalloy doall instead?

21:49 amalloy: no, just for

21:49 ajn: how do i populate to a vector inside the for?

21:49 cons?

21:49 clojurebot: unlink: and constantly is just a function that takes any arguments and returns whatever argument is given

21:49 amalloy: or whatever other sequence-producing function

21:49 you seem to be looking for ##(doc filter)

21:49 lazybot: ⇒ "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

21:50 ajn: i tried the filter approach but was having issues appending to the vector

21:51 amalloy: don't try to do it inside the filter. it's just (map some-functon (filter #(= whatever %)))

21:52 ajn: could i inline the function (map (fn [x] (filter #(= whatever %)))) ?

21:53 amalloy: *shrug* sure

21:53 that does something different, but if it's what you want nobody is stopping you

21:54 ajn: i guess i might be missing the purpose of the function

21:59 TimMc: &(let [[a b] false] a nil)

21:59 lazybot: java.lang.UnsupportedOperationException: nth not supported on this type: Boolean

21:59 ajn: amalloy something like (def config-values (map (filter #(= (:value %) config-name)) (doall results)))

22:08 zappps: Hi all, can someone clarify the clojure repository situation ?

22:08 clojars vs. maven? where should stuff be published??

22:08 lazybot: zappps: Definitely not.

22:10 xumingmingv: haha, lazybot sometimes is very hilarious

22:11 amalloy: yeah, -1 for heuristics this time

22:12 xumingmingv: zappps: Seems most clojure open source jars are published at clojars

22:12 xeqi: zappps: clojure libraries usually end up in clojars because its easier then central

22:13 TimMc: Is this a reasonable multi-clause if-let? https://www.refheap.com/paste/9122

22:13 xeqi: though if something would be of interest to the wider jvm community putting it in central would be better

22:13 TimMc: I delayed evaluation of the else-expr by wrapping it up as a thunk.

22:14 amalloy: well, you could delay evaluation of it by just expanding it in-place N times

22:14 by making it a thunk, you made sure it doesn't have access to intermediate bindings

22:15 TimMc: I wouldn't want it to anyhow.

22:15 amalloy: sure, i wasn't saying that was an error

22:15 TimMc: In fact, I'm pretty sure that wouldn't be useful anyhow.

22:15 amalloy: just that your claim about why you made it a thunk is nonsense

22:15 TimMc: Hmm, right -- clojure.core/if is going to do that anyway.

22:16 Is there anything to be said for output code size, or debugging friendliness?

22:16 That is, I see benefits to using a thunk, but no downsides.

22:16 amalloy: well, calling a function isn't free :P

22:16 it's damn near free, of course

22:16 TimMc: True.

22:19 zappps: xeqi: lein finds in either regardless ?

22:19 TimMc: Dammit, if I call it if-let+ or expect the user to use it with a prefix (h/if-let), then the indentation is all wrong.

22:20 amalloy: TimMc: tell your users to get used to M-x customize-variable RET clojure-defun-indents RET

22:20 zappps: also does clojar timeout/slows down for everyone or just for me ?

22:21 xeqi: zappps: correct, clojars and central are the default repos for lein

22:21 TimMc: amalloy: :-(

22:22 with-just-kidding-its-actually-if-let

22:22 amalloy: with-iflets

22:22 brilliant

22:23 with-sincere-apologies-iflet

22:25 frozenlock: Oh nice, relative links in readmes at github.

22:26 gfredericks: the maybe macro

22:27 TimMc: the macro monad

22:27 gfredericks: the burrito macro

22:28 any portmanteau of "macro" and "monad" just sounds stupid

22:28 except for "monacro"

22:28 DigitalJack: MacNads

22:28 gfredericks: brb I need to go start a band

22:29 warz: so would you say clojure is capable of being used for the same kind of programming that maybe like C# or any other language could be used for? this is kind a crappy question, but i dont know how else to phrase it.

22:29 like is clojure sort of domain specific

22:29 TimMc: It's certainly not domain specific.

22:30 warz: and i dont really mean any other language, thats not fair

22:30 TimMc: There are certain domains where I *wouldn't* use Clojure, but it is a general purpose language.

22:30 warz: i mean like your typical languages

22:30 ok

22:30 TimMc: For instance, I'd be hard-pressed to write a kernel in Clojure. :-)

22:30 warz: ya :p

22:31 TimMc: (That's what Rust is for.)

22:31 I'd probably prefer OCaml (or perhaps Racket?) for heavy-duty numerics, but I haven't really investigated.

22:31 For scripting... Python.

22:32 gfredericks: TimMc: by the end of this you will have convinced me that no specific domain is good for clojure

22:32 warz: my brain always explodes when i try to define "scripting"

22:32 when i think of scripting i think of like, mirc scripting, php

22:32 TimMc: warz: I mean little shell scripts.

22:33 warz: things that cant really exist outside of their domain

22:33 ttimvisher: is there any meta information attached to namespaces by which i could look up the file they were declared in?

22:33 i'm trying to enhance nrepl to support `M-.`ing into namespaces.

22:34 TimMc: warz: "PHP scripting" is a bit of a misnomer, since web server code doesn't have to be implemented as an interpreted language.

22:34 By script I mean small, fast-start, short-run, no-compile programs.

22:34 warz: i just think of php as really suited for web scripting

22:34 Sgeo: "no compile"?

22:34 TimMc: "web scripting" isn't a thing

22:35 Sgeo: sshhhh

22:35 Sgeo: Why does that matter to the usability of a language for a purpose

22:35 Except needing to transport interpreter around I guess

22:35 And self-hosting

22:35 TimMc: no-AOT-compile, I guess

22:35 I want to edit and go.

22:35 Sgeo: SBCL is compiled but can feel scripting-ish

22:35 (Common Lisp)

22:38 ttimvisher: is an inspector on the roadmap for nrepl?

22:39 amalloy: gfredericks: isn't that true, though? lisp is a terrible language for any problem, but a great language for *building* the perfect language for any problem

22:39 warz: im just pretty excited to be learning clojure for some reason. i like picking up new languages and i picked up ruby, python and js/node really fast. i used each for about a year or so, on each.

22:39 but with clojure my mind is like

22:39 gfredericks: amalloy: I'm not wise enough to argue with that

22:40 warz: really stretching haha

22:40 TimMc: That's a good thing.

22:40 warz: so its exciting to me

22:41 i just find that i do a lot more staring deep into the pixels of my screen while i think about what im writing, haha.

22:41 gfredericks: think more type less

22:54 zappps: I get errors like: WARNING: get already refers to: #'clojure.core/get

22:54 is get a reserved word? Anyway I can get around this ??

22:54 lazybot: zappps: What are you, crazy? Of course not!

22:54 zappps: great

22:55 headshot: use the namespace of your get impl

22:55 Sgeo: refer-clojure

22:56 http://clojuredocs.org/clojure_core/clojure.core/refer-clojure

22:56 zappps: headshot: can you show me an example ?

22:56 headshot: nifty

22:56 zappps: Sgeo: thanks

22:56 Sgeo: zaphar_ps, yw

23:08 warz: ibdknox, on light table, if you make a new file and accidentally use the same name as existing file, it doesnt have any prompt or anything. would be easy to save over it.

23:18 Raynes: I like that feature. Sick of prompts.

23:18 I want my editor to laugh at me when I overwrite an important file.

23:18 desertmonad: Does anyone know license info for the clojure logo? (yin-yang lambda thing)

23:19 Raynes: desertmonad: IIRC, it's under the ask-Rich-for-permission-first license.

23:20 desertmonad: couldn't hurt :)

23:20 Raynes: There is this https://groups.google.com/forum/?fromgroups=#!topic/clojure/fxecefDQuz4

23:20 But Rich nor Tom ever actually decide on what it is licensed under.

23:22 TimMc: In the case of logos, trademark may be the more important question.

23:23 Raynes: I use the logo on http://tryclj.com/ and have for years. I never asked permission, and Rich hasn't subpoenaed yet.

23:23 desertmonad: I was just thinking about using it on a blog, which likely would talk about clojure at least some. But I wouldn't want to dilute anything. Maybe I'll just futz around with a lambda for a while and see what happens.

23:24 Raynes: I *may* have asked for permission and never received a response. Not sure.

23:24 TimMc: Raynes: s/bpoena//

23:24 ivan: subpoena: we demand to know... if you are really using that logo

23:24 Raynes: I was also like 15 at the time and not smart enough to worry about legalities.

23:25 I know what that word means, fwiw.

23:25 I guess sarcasm doesn't work well on the internet.

23:25 desertmonad: now you are getting recursive

23:32 ominen1: Why not tell me what you want? I can help. All I have is time

Logging service provided by n01se.net