#clojure log - Aug 26 2013

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

0:02 SegFaultAX: Ugh I'm so close on #89. Passing all but 1 test. :(

0:03 callen: okay, no more owning things.

0:03 owning things sucks.

0:04 TEttinger: callen, stealing is bad, mm kay?

0:09 callen: TEttinger: in the process of moving, I'm reflecting on how much I hate owning stuff.

0:13 SegFaultAX: I'm all out of brain juice to make this work: https://gist.github.com/SegFaultAX/42ed69e7d8c479a59792

0:13 It's almost definitely something really obvious.

0:17 TEttinger: SegFaultAX, graph theory and really obvious are not concepts that I understand being together

0:18 ToxicFrog: What is the best way to call a function by name?

0:18 I have a namespace containing functions to handle various user commands and I'd rather not just have a huge (case)

0:19 SegFaultAX: Actually, the problem is obvious. I mentally ignored undirected edges as the last constraint.

0:19 I just need to figure out how to make my algorithm work with undirected edges instead of directed ones.

0:19 TEttinger: ToxicFrog, like the name as a string?

0:20 ToxicFrog: TEttinger: yes

0:20 TEttinger: this is the time I wish I knew how macros worked

0:21 ToxicFrog: Macros own but I'm not sure they'd help here, I have the string at runtime from user input.

0:21 TEttinger: oh. sounds like a reflection thing?

0:22 s4muel: ToxicFrog: multimethods and a dispatch function that takes the user string and runs the right fn

0:22 SegFaultAX: ,((resolve (symbol "+")) 1 1)

0:22 clojurebot: 2

0:22 ToxicFrog: SegFaultAX: awesome, thank you.

0:23 SegFaultAX: ToxicFrog: Noooo, don't do that.

0:23 So unsafe.

0:23 You need to validate input. Create a map of all possible inputs to fns.

0:24 ,(({"+" #'clojure.core/+ "-" #'clojure.core/-} "+") 1 1)

0:24 clojurebot: 2

0:24 callen: ToxicFrog: don't do that :|

0:25 SegFaultAX: callen: I immediately regretted it.

0:25 callen: SegFaultAX: as you should.

0:26 TEttinger: ,((resolve (symbol "eval")) "(with-precision 10 (/ 1M 6))")

0:26 clojurebot: "(with-precision 10 (/ 1M 6))"

0:27 SegFaultAX: TEttinger: You need to read it as data first.

0:27 ToxicFrog: callen, SegFaultAX: anything evil the user can do with this they can do just as easily by, you know, starting the repl.

0:28 SegFaultAX: ToxicFrog: What are you doing?

0:28 TEttinger: ,((resolve (symbol "eval")) (read-string "(with-precision 10 (/ 1M 6))")) ;; ##((resolve (symbol "eval")) (read-string "(with-precision 10 (/ 1M 6))"))

0:28 lazybot: java.lang.SecurityException: You tripped the alarm! resolve is bad!

0:28 clojurebot: 0.1666666667M

0:28 TEttinger: interesting contrast

0:29 ToxicFrog: SegFaultAX: program for making batch edits of Backloggery game entries

0:29 SegFaultAX: ToxicFrog: Why do you need to call functions by name like that?

0:30 ToxicFrog: SegFaultAX: because I'd rather have a namespace containing all of the handlers for user commands and resolve them automatically than manually enumerate them all.

0:30 Hmm. I guess I could write a defcommand macro that stuffs them into a map instead, then look them up in the map...

0:30 SegFaultAX: ToxicFrog: Yes, do that.

0:54 Got it.

0:58 amalloy: just to emphasize and generalize, ToxicFrog, i'd say that using maps as namespaces is much better than using namespaces as maps, in general

1:00 ToxicFrog: amalloy: part of this may be that I'

1:00 m used to lua, where maps and namespaces are the same thing.

1:05 SegFaultAX: ToxicFrog: He isn't talking about implementation details.

1:05 ToxicFrog: He's talking about the semantics of namespaces vs maps in an application.

1:06 Yes you /can/ look something up by name in a namespace, but that isn't the ideal usage (in Clojure or Lua)

1:09 callen: ah, the memories of using getattr and a string in namespaces in Django.

1:10 #metaprogramming #lel #killmenow

1:10 ToxicFrog: listen to them. Been there, done that, you don't want to shove that shit to runtime.

1:22 dissipate: noncom, ping

1:24 bja: so if I'm starting up a cljs.repl/repl via some random -main (so I can just "lein run -m browser-repl" for instance) how might I go about getting back the improved repl experience that lein repl provides?

1:25 dissipate: clojurebot, noncom

1:25 clojurebot: Titim gan éirí ort.

1:26 ddellacosta: bja: have you seen austin or piggieback? https://github.com/cemerick/austin

2:02 muhoo: iirc, in clojure, namespaces *are* maps. not sure though if i'm misremembering

2:04 bbloom: muhoo: you're misremembering :-P

2:04 muhoo: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Namespace.java

2:09 ambrosebs: muhoo: http://www.infoq.com/presentations/Clojure-Namespaces-Vars-Symbols

2:12 callen: thanks for that recommend btw ^

2:19 ddellacosta: what is the best way to compare a list and a vector? I can do this: (clojure.set/difference (set ["a" "b" "c"]) '("a" "c" "b")) but is there a smarter way?

2:20 dissipate: ddellacosta, hmm, doesn't a list require something in the 'function' position, while a vector does not?

2:20 seems like apples and oranges to me

2:21 SegFaultAX: Finally got it.

2:21 ddellacosta: dissipate: I'm just curious about how to compare the values of the two.

2:21 SegFaultAX: And about a million times faster than the naive formulation.

2:21 dissipate: ddellacosta, convert the list into a vector first, that's what i would do

2:21 ddellacosta: SegFaultAX: 4clojure question?

2:22 dissipate: how? This: (= ["a" "b" "c"] (vector '("a" "c" "b"))) …for example, doesn't work

2:22 callen: ddellacosta: I'm with dissipate. Don't do the set thing, just make them both vectors.

2:22 ddellacosta: whoops, apply

2:22 sontek: Anyone developing webapps in clojure and done benchmarking on basic check for how many requests per second a standard stack could handle?

2:22 callen: ddellacosta: vec.

2:22 ddellacosta: don't use apply, it's slow.

2:22 ,(vec '(1 2 3))

2:22 clojurebot: [1 2 3]

2:23 callen: ddellacosta: the short words are usually casts. (int, vec, str, etc...)

2:23 sontek: My python app handles about 200 requests per second right now and I've had to start adding servers to it, was wondering if a rewrite in clojure would allow me to keep servers down

2:23 callen: ddellacosta: vector exists as a constructor, like for mapping across multiple seqs.

2:23 ddellacosta: callen, dissipate: okay, but none of this solves my problem, comparing two collections by value

2:23 ivan: sontek: you can try it with pypy first

2:23 ddellacosta: ,(= ["a" "b" "c"] ["a" "c" "b"])

2:23 clojurebot: false

2:23 SegFaultAX: ddellacosta: Yea, 89

2:24 callen: sontek: don't bother with pypy, it doesn't make typical web stuff faster.

2:24 dissipate: ddellacosta, what are you ultimately trying to do?

2:24 callen: ddellacosta: if you want order-agnostic, then you're getting into set territory, but why aren't they both sets to begin with?

2:24 sontek: ivan: callen: thats on pypy

2:25 callen: pypy did improve it by about 30-50 rps

2:25 callen: sontek: something to keep in mind, 200 requests per second is 525948000 requests per month. Do you really need more?

2:25 ivan: are you actually getting 200 requests/sec? nice problem to have

2:25 dissipate: callen, i'm curious. how does clojure check the equality of an ordered set?

2:25 sontek: callen: but the warm-up of the JIT is extremely slow, so it takes forever before pypy is helpful

2:25 callen: dissipate: check the source.

2:26 ivan: sontek: it would take 20+ seconds with Clojure

2:26 ddellacosta: callen: because I am writing a test. What the function returns is a vector, it doesn't need to return a set. I only need to ensure I'm getting back what I expect. I mean, let's be clear, I know how to do this, I just was asking if there was some more clever way to compare two collections by value that I didn't know.

2:26 ivan: sontek: unless you have a really new Intel

2:26 dissipate: callen, the source of how ordered sets are represented?

2:26 callen: ddellacosta: do you expect duplicates or care if there are any? if not and order agnosticism is desired, that's a set.

2:26 dissipate: the equality check.

2:26 dissipate: just go read the code.

2:27 sontek: callen: I don't need more *all* the time, just at the high load times, and I've been wanting to add some real-time stuff using socket.io, so improving the UI would add more requests for the same user base

2:27 dissipate: callen, is that a macro? i haven't looked at the clojure source. i thought clojure was in java.

2:27 ddellacosta: callen: yeah, what I want to prove is that the difference of two sets is empty, I suppose. In the end, I guess what I really want is some set action here, I'll just do that.

2:27 callen: dissipate: just go read the code.

2:28 ddellacosta: I find it helps sometimes to step away from 'code' and instead think about 'data' and what I do and not care about the data and what it should represent.

2:28 do and do not*

2:28 sontek: I'm really just looking for a reason to play with clojure anyways

2:28 dissipate: callen, i don't know where that code lives.

2:28 callen: dissipate: you really want to get in the habit of reading code to answer your own questions, it will make you a vastly better programmer.

2:29 dissipate: learning to navigate code you didn't write is part of learning to read code.

2:29 ddellacosta: dissipate: https://github.com/clojure/clojure

2:29 dissipate: callen, i'm barely through the first chapter of the Clojure Programming book. i'm not good at reading the code, yet. :P

2:29 callen: dissipate: you won't get good at it without reading code.

2:29 TEttinger: dissipate: the source is here for ordered sets, yes, java https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentTreeSet.java

2:30 callen: you're *going* to encounter things you don't understand, that's part of the point. You create new questions and ten answer them.

2:30 sontek: Most people using luminus for their web stack in clojure?

2:30 callen: sontek: I don't know about most, but yogthos, myself, and others are happy with it.

2:30 sontek: Luminus itself is a roll-up of best practices for Ring/Clojure based web apps. You can learn from it and then write your own stuff bespoke afterward.

2:31 or enjoy the labor-saving aspects of using Luminus. up to you.

2:31 sontek: callen: Is there any small demo apps you guys have built that I can pull down and tinker with?

2:32 dissipate: TEttinger, why was it implemented in Java and not clojure itself?

2:32 callen: sontek: github.com/bitemyapp/neubite/

2:32 TEttinger: dissipate, because it's needed before clojure can evaluate anything

2:33 all the core types are done in java

2:33 callen: pretty typical for bootstrapping a Lisp

2:33 TEttinger: but only very basic operations on them

2:33 the more complex stuff is in clojure's core.clj

2:33 and by more complex, I mean nicer to use

2:33 sontek: callen: thanks

2:33 TEttinger: more complex to implement

2:34 dissipate: TEttinger, but i was told that anything that is not a special form is a macro, function or something else written in clojure

2:34 callen: I still need to see if I can hijack AnnotationWriter.java

2:34 TEttinger: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L395

2:34 dissipate: callen, i thought it was bootstrapped from the special forms alone

2:35 TEttinger: dissipate, keep in mind, special forms includes calls to java

2:35 callen: dissipate: there are plenty of ways more efficient for learning why it was implemented the way it was.

2:35 dissipate: some of those ways include reading the code or watching talks hickey has given

2:35 TEttinger: dissipate, see how that function just calls the PersistentTreeSet I linked earlier?

2:36 it's still only using a special form

2:36 just the java interop one

2:36 dissipate: TEttinger, yes. but couldn't PersistentTreeSet be implemented in pure clojure?

2:36 TEttinger: and it needs some thing in hava before, like []

2:36 for args I mean, if there was no vectors, you couldn't do defn...

2:36 callen: dissipate: honestly - who cares?

2:37 TEttinger: dissipate, it was a goal at one point, to help with cljs

2:37 callen: dissipate: the data structures need to be reliably fast because they underly most of clojure.

2:37 dissipate: callen, those who are curious?

2:37 callen: I already presented a good path for satisfying curiosity

2:37 TEttinger: but it ended up I think being easier to just implement a little bit in java, then a little bit for js

2:37 you saw how the TreeSet was less than 100 lines?

2:37 there's other parts that are bigger

2:38 dissipate: yeah, and it looks awful

2:38 TEttinger: it's efficient, is why it is the way it is.

2:38 callen: you clearly haven't seen enterprise Java code.

2:38 TEttinger: haha

2:38 yeah anything by google

2:38 guice and all that horror

2:38 callen: dissipate: you're not accustomed to reading code you didn't write, so you're not really seeing it properly.

2:38 dissipate: callen, i have explicitly tried to avoid java entirely

2:38 callen: dissipate: what would help with that is learning to read code.

2:39 dissipate: well your prejudice is adorable but probably limiting you.

2:39 sontek: Found these benchmarks of servers: https://github.com/ptaoussanis/clojure-web-server-benchmarks

2:39 callen: sontek: techempower is better.

2:39 TEttinger: dissipate, it's surprisingly hard to avoid java, since all the libs are written in java and may or may not have clojure bindings

2:39 ddellacosta: dissipate: if you want to use Clojure, you cannot be afraid of Java

2:39 callen: sontek: benchmark whoring really isn't the way to make decisions like that.

2:39 TEttinger: but it really isn't so bad

2:39 callen: it really isn't.

2:39 dissipate: callen, i spend a lot of time reading code. BTW, i'm not saying that code is awful because the author wrote it poorly, i'm saying it's awful from an absolute standpoint. Objects and casts are terrible IMO.

2:39 sontek: callen: Its just one of many things i'm evaluting

2:40 TEttinger: dissipate, woah

2:40 callen: wrapping java libs in Clojure is nicer than stumbling into somebody's psychotic meta-universe of weirdo libraries in Common Lisp.

2:40 Ember-: I very rarely see any type casting in good Java code

2:40 TEttinger: clojure isn't normal java code, keep in mind

2:40 Ember-: indeed

2:40 ddellacosta: really don't know what to say about where this conversation is going

2:40 * ddellacosta makes popcorn

2:40 TEttinger: it is a dynamically typed language, so you could have a ##(sorted-set 1 2 "STRONG")

2:40 lazybot: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String

2:41 TEttinger: err maybe not

2:41 callen: ddellacosta: ITT: people that have never implemented a language criticizing the first bit of code they see in a language implementation.

2:41 ddellacosta: I say we show them gcc's source and see if they piss blood.

2:41 sontek: How is writing interop code between java and clojure? (Speaking of things I'm evaluating)... Java has such a large ecosystem of great libraries, does it take much work to take advantage of that?

2:41 dissipate: callen, i'm willing to get dirty with Java if i can reap the rewards of clojure

2:41 ddellacosta: callen: haha

2:41 dissipate: Excellent! Problem solved.

2:42 TEttinger: well I am just saying, clojure needs objects and casts to be able to be able to represent lisp stuff. you don't need it in "good java" but this isn't for java

2:42 dissipate: callen, read what i said above. i'm not criticizing the author. i'm saying Java is bad in general.

2:42 callen: dissipate: so moving on to the part where we all use our time more effectively, I strongly suggest you watch some talks and read some material on the implementation of Clojure and read the code.

2:42 TEttinger: also, 4clojure rules

2:42 callen: TEttinger: yes it does.

2:42 * ddellacosta goes back to actually writing Clojure for fun and profit

2:43 * callen goes to sleep so he can write clojure for fun and profit at work tomorrow. Also Datomic.

2:43 ddellacosta: callen: g'night!

2:43 callen: ddellacosta: g'night :D

2:43 TEttinger: night all of you

2:43 ddellacosta: TEttinger: 'night!

2:44 TEttinger: i ain't sleepin'!

2:44 ddellacosta: oh, I ain't either, but I do have to write some code.

2:44 dissipate: I have watched talks, but i don't see the point of reading code at this point because I don't know the absolute basics of the language. sheesh

2:45 shaunxcode: seriously who sleeps?

2:47 TEttinger: dissipate: definitely going to recommend trying as many 4clojure problems as you can until you hit one you can't solve. then read your book until you find a possible solution

2:47 it is really empowering to see a big list of "solved" in the site

2:49 dissipate: TEttinger, thanks, looks like a great way to learn

2:52 TEttinger, have you solved all the problems?

2:53 TEttinger: haha no way! only less than... 20 people have?

2:53 err 21 now

2:53 dissipate: damn, guess they get tough!

2:54 seems a lot like Euler Project

2:54 TEttinger: indeed. the one only 54 people solved is a poker hand thing, which looks all kinds of hard

2:56 dissipate: TEttinger, ah, i see it.

2:57 TEttinger, i solved the first one! yay

2:58 TEttinger: heh

2:59 keep at it, the seq stuff gets tricky

2:59 the early things should be very fast

3:04 SegFaultAX: Finally top 100 on 4clojure!

3:05 dissipate: TEttinger, these exercises have lists that have things that don't make sense in the function position, like the literal 1

3:05 TEttinger, if you evaluate these lists, you get an error

3:05 TEttinger: dissipate: which problem, link?

3:07 dissipate: TEttinger, http://www.4clojure.com/problem/5

3:07 noonian: they are still data structures and you can use them as such

3:07 they are quoted so they will not be evaluated

3:08 TEttinger: '(1 2 3) is a list

3:08 the ' prevents it from trying to call 1

3:08 dissipate: noonian, true, but wouldn't a vector be better suited?

3:08 TEttinger: indeed, but!

3:09 conj has different behavior (slightly) for vectors

3:09 that comes later

3:09 there's a reason clojure has both

3:09 dissipate: noonian, i don't think i would pass a list around that couldn't be evaluated. a vector would safely evaluate to itself.

3:09 noonian: dissipate: depends on you need, for recursive functions lists will be just as fast

3:10 ,(map (fn [k] (+ k 5)) (list 1 2 3 4))

3:10 clojurebot: (6 7 8 9)

3:10 TEttinger: and you can use a quoted list much like a vector: ##(map + [1 2 3] '(10 20 30))

3:10 lazybot: ⇒ (11 22 33)

3:10 noonian: dissipate: usually you don't need to know whether its a list or a vector because all of the core functions will work on both

3:11 ,(= [1 2 3] '(1 2 3))

3:11 clojurebot: true

3:12 noonian: ,(= (type [1 2 3]) (type '(1 2 4)))

3:12 clojurebot: false

3:13 TEttinger: that's sometimes called the "seq abstraction" (seq short for sequence), and it's one of the best parts of clojure's design IMO

3:13 dissipate: TEttinger, so why have vectors at all? one could just use quoted lists everywhere, right?

3:13 TEttinger: dissipate, performance reasons. lists are slower for random access, vectors are slower for sequential I think

3:14 dissipate: i see.

3:14 TEttinger: vectors also have different conj ordering, which is a common pitfall but the reason why they act differently

3:15 ,(conj 1 [1 2 3])

3:15 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IPersistentCollection>

3:15 TEttinger: ,(conj [1 2 3] 1)

3:15 clojurebot: [1 2 3 1]

3:15 TEttinger: ,(conj '(1 2 3) 1)

3:15 clojurebot: (1 1 2 3)

3:16 dissipate: a queue vs. a stack?

3:16 TEttinger: very close

3:16 the list is a linked list

3:17 the vector is something more complicated, built over arrays I think.

3:17 but they are as different as queues and stacks most of the time

3:20 noonian: implementing an efficient queue with lists is not as straightforward as it is with vectors

3:21 but a list could be faster for a stack

3:21 TEttinger: if I am correct about this, conj is very fast for lists, but not as fast for vectors. vectors have array-like (very good) speed for random access, linked lists need to go through each element's links to get to the one they want, which is a little slow unless you're doing recursive stuff, in which case it isn't a problem

3:22 there's lots of subtle differences you won't encounter until you hit a bottleneck on performance

3:23 zeroem: ,(apply str 1 2 3 [4 5 6])

3:23 clojurebot: "123456"

3:27 dissipate: TEttinger, is clojuredocs.org a good place for clojure documentation?

3:27 TEttinger: yes

3:28 it hasn't been updated since 1.3, but the core language hasn't changed

3:31 dissipate: cool

4:53 quanticle: Are any of you awake? I'm wondering why I get ArityExceptions when I try to call a multimethod that I've defined.

4:54 One sec, I'll Gist the code

4:55 ucb: quanticle: I'm awake (kind of)

4:56 quanticle: https://gist.github.com/quanticle/6339254

4:57 I think I'm getting an ArityException when I try to call the send-command multimethod

4:57 ucb: you think? Can you gist/paste the actual stacktrace?

4:57 quanticle: Yeah. It's just one line, so it's not very helpful.

4:57 ucb: quanticle: btw, you've defn and def-multi send-command

4:58 quanticle: ArityException Wrong number of args (3) passed to: core$eval95$fn clojure.lang.AFn.throwArity (AFn.java:437)

4:58 vijaykiran: quanticle: why is there a defn and defmulti ?

4:58 quanticle: Oh

4:58 ucb: not sure how that's going to play ;)

4:58 quanticle: If that's the issue, I'm going to cry.

4:58 Yeah, I started writing it as a function, and then decided that a multimethod was more appropriate.

5:01 No, I deleted the defn, and I'm still getting the same error. Let me update the gist.

5:02 ucb: quanticle: is this in a running repl? Just wondering about lingering definitions

5:02 quanticle: ucb: I restarted the REPL. I thought that might have been the problem as well, but even after the restart I see the same error.

5:02 Updated gist: https://gist.github.com/quanticle/6339254

5:04 ucb: quanticle: are you sure you can define multimethods with different arities? (I've never done it nor seen it done.)

5:05 alexyakushev: quanticle: dispatch function and methods should have the same arity

5:05 quanticle: you need to add command-type to methods' arguments as well

5:08 quanticle: Ahhhh, okay.

5:08 Thanks.

5:08 vijaykiran: quanticle: or - use : http://stackoverflow.com/questions/10313657/is-it-possible-to-overload-clojure-multi-methods-on-arity

5:11 quanticle: Thanks vijaykiran, alexyakushev, ucb.

5:12 I've got past the initial error; the code still doesn't work, but I know where to go from here.

6:38 jwr7: So I just found out that (merge-with conj {:abc nil} {:abc :cde}) will give a different result than (merge-with conj {} {:abc :cde}). I did not expect this.

6:39 ucb: that's reasonable, right?

6:39 jwr7: But, the way merge-with is written, the merge function will only get called if a key exists in two merged maps.

6:39 ucb: I mean, {} doesn't have a key :abc

6:39 so there's no clash

6:39 unless I'm missing something

6:39 jwr7: ucb: not if my values are sequences and I want to *always* keep them as sequences

6:40 ucb: ,(merge-with conj {} {:abc :def})

6:40 clojurebot: {:abc :def}

6:40 ucb: ,(merge-with conj {:abc nil} {:abc :def})

6:40 clojurebot: {:abc (:def)}

6:40 ucb: that's the behaviour I would expect

6:43 jwr7: I guess I expected to be able to also initialize values using the merge function. But perhaps that isn't reasonable...

6:44 ucb: well, the merge function gets called only when there's a key clash

6:44 otherwise, it's plain merge

6:44 it's a conflict resolution scheme really

6:45 jwr7: so (merge-with conj ...) makes little sense.

6:48 ucb: well, it depends on what you're after

6:49 jwr7: I think I'm after (merge-with concat) :-)

6:52 ucb: ok!

7:16 clgv: jwr7: that might be dangerous - if you stack too many conacts your stack will blow up

7:16 similar to (reduce concat ...)

8:31 noncom: how do i find the first matching entry in a colelction

8:31 ?

8:32 rkneufeld: noncom: sounds like you're looking for some + an anonymous function

8:33 noncom: oh, right

8:48 dark_element: noncom what need is 'some'

8:48 noncom: looks like it is indeed!

8:48 dark_element: oh i didn't read rkneufeld response.

8:49 noncom: i did not try yet also haha

8:55 clgv: noncom: but beware ##(some odd? (range 10))

8:55 lazybot: ⇒ true

8:55 noncom: heh

8:56 clgv: noncom: you'd nee to write it as ##(some #(when (odd? %) %) (range 10))

8:56 lazybot: ⇒ 1

8:56 clgv: noncom: first+filter is a solution as well

8:56 noncom: interesting.. these functional combinations always make so much fun

8:58 clgv: they should have implemented "some?" as predicate and a separate thing to find the first matching on a predicate ^^

8:59 kohkane: i guess some is implemented as a short circuit eval

9:06 clgv: yeslike "some?" would be as well ;)

9:13 kohkane: is there any way to "apply" to a macro

9:13 noncom: ,(doc some?)

9:13 clojurebot: I don't understand.

9:14 noncom: ,(doc +)

9:14 clojurebot: "([] [x] [x y] [x y & more]); Returns the sum of nums. (+) returns 0. Does not auto-promote longs, will throw on overflow. See also: +'"

9:14 noncom: i always though there is some? predicate

9:14 as ther eis every? predicate

9:14 Ember-: ,(doc some)

9:14 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

9:14 Ember-: there is that

9:14 but it isn't a predicate

9:36 clgv: noncom: no. that was the point I was making ;)

9:42 noncom: i try (let [^double d bla-bla-bla]) and i get Can't type hint a local with a primitive initializer

9:42 for what reason?

9:42 why is clojure's computation capabilities are so crippled for no good reason?

9:43 bja: noncom: crippled how?

9:43 noncom: first i find that floats and ints are not frist class citizens , so a while load of java interop or opengl interop (opengl only accepts floats, as the ahrdware does) simply goes away, here take these doubles and casting lags..

9:44 now i can't typehint even doubles for speed...

9:44 tim___: noncom: example code?

9:44 noncom: man, i need to compute things.. and do it fast... i'm on a computer...

9:45 https://www.refheap.com/18029

9:45 i get Can't type hint a local with a primitive initializer here

9:46 opqdonut: noncom: use d (double ...)

9:46 instead of hinting

9:47 noncom: so casting instead of immediate typization..

9:47 oh well..

9:47 as much as clojure is fascinating with anything else, so much it is frustrating on computations

9:47 bja: noncom: I've always just dipped down to java for that stuff

9:48 noncom: agreed, i will do that too.

9:48 bja: but agreed, that it is a shame that we have to

9:48 tbaldridge: noncom: you are talking about using a dynamic language for high performance situations. Clojure is way faster/flexible than any other language I've used for this. Try doing what you're doing in Python for instance.

9:48 bja: tbaldridge: numba actually makes this pretty reasonable in python

9:49 noncom: tbaldridge: fully i agree with you, no argument here.. i enjoy clojure very much - full credit, but... i simply see no reason to ignore ints and floats and to disallow local unboxed computations in manner of local mutability like with transients

9:50 jvm does it

9:51 tbaldridge: noncom: using ints instead of longs is a bit pointless. Memory is cheap, using longs on a 64bit system isn't going to be slower.

9:52 noncom: tbaldridge: yes, i know, but lots of hardware works with ints and floats, for example, the whole opengl graphics adapters world knows nothing of 64 bit (as of yet).. so.. instead of adding support for them in the core, we simply lose opengl.. fair trade?

9:52 tbaldridge: noncom: same for doubles, both get turned into 10-byte reals... http://stackoverflow.com/questions/417568/float-vs-double-performance

9:53 noncom: it just turns out that any opengl program is ways slower coz no floats here

9:54 tbaldridge: noncom: always slower...how? Casting is slowing you down that much?

9:55 noncom: tbaldridge: sure! casting is very slow! imagine having like thousands of vertices on a dynamic mesh... each vertex is 3 components. So, you cast them all. And if you compute, say, deltas for them, then you have to cast these too. And if you get float values from the opengl driver to include in your coputations, you cast them too.

9:56 thousands of thousands of casts

9:56 per frame

9:56 and you also have many other things to do besides that

9:57 tbaldridge: shouldn't all that be done via vertex buffers and vertex shaders anyways?

10:00 noncom: tbaldridge: buffers are just that - buffers, datastructures. you have buffers of floats or ints. if you deal with coordinates, them are floats. if you deal with indices, them are ints. and you do computations in the program anyway. you can't put all in your shaders. shaders are just VFX.

10:00 imagine a buffer of 1000000 floats that you have to cast from doubles each frame..

10:01 shaders are too, programmed and communicated from your main program

10:01 they receive floats

10:01 there are no magical double <-> float adapters on a video card...

10:02 clgv: noncom: you do not need to type hint or cast values to doubles if the compiler already nows they are. the compiler performs local type inference (in compilation units, e.g. defn) for that

10:03 unrelated question: I want to store experiment results in a database. which clojure library should I go for? I'd like to define the entities in a high level way

10:04 noncom: i use monger + mongodb

10:04 simply you put in and get {}

10:04 Ember-: doesn't provide any abstractions for defining the entitites, but that's kinda easy with records

10:05 noncom: i think that in clojure, entities cannot be anything but {} or [].. and them are mapped to mongo 1:2

10:05 ahaha

10:05 s/1:2/1:1

10:05 Ember-: noncom: well, records are maps but they are also a bit more

10:05 clgv: mongodb is not sql, right?

10:05 Ember-: yes

10:06 noncom: right

10:06 tbaldridge: clgv: datomic's Clojure integration is very very tight

10:06 noncom: yeah, right, datomic should be great too, just never used it before

10:06 gonna try some time too

10:08 clgv: so datomic and mongodb are the main options?

10:09 Ember-: you can use sql too if you want

10:09 but in my honest opinion sql is pretty crappy abstraction for persisting data structures

10:09 clgv: I really dont know if I need sql features.

10:09 nDuff: clgv: There are plenty of alternatives to MongoDB if you want something with a similar model but more of a focus on reliable storage.

10:09 Ember-: that doesn't mean that sql is bad

10:10 noncom: clgv: what kind of data you want to store?

10:11 clgv: noncom: experiment results, i.e. numbers and solution datastructures

10:11 I want to generate additional attributes based on that data

10:11 noncom: clgv: i think no need for sql then

10:11 pick a db with a loose schema (no schema :D)

10:11 clgv: and generate plots from it

10:12 tbaldridge: clgv: datomic also stores values/entities as raw data, in an extremely efficient serialization format. This means massive arrays of primitives take up little space.

10:12 clgv: could be better than whatever mongodb uses

10:12 noncom: mongodb uses bson

10:12 clgv: tbaldridge: ok. how easy is it to set up datomic on a machine?

10:13 noncom: i am all ears.. wanted to test datomic for a long time too

10:15 tbaldridge: clgv: [com.datomic/datomic-free "version"]

10:15 versions are here: http://downloads.datomic.com/free.html

10:15 clojure api http://docs.datomic.com/clojure/

10:16 basic docs: http://docs.datomic.com/

10:19 clgv: tbaldridge: do I understand correctly that the free version only has in-memory storage?

10:20 tbaldridge: clgv: no it also has the free:// storage, which is stored on disk.

10:20 clgv: tbaldridge: ah ok. :)

10:21 tbaldridge: transactor url would look like this datomic:free://localhost:4334/<DB-NAME>

10:21 clgv: tbaldridge: ok. I'll need to work through a tutorial then ...

10:22 tbaldridge: clgv: it can be a bit daunting at first, but after playing around with it a bit I like it more than any other DB I've used from Clojure.

10:30 fredyr: iirc the day-of-datomic repo was nice to play around with from the repl

10:32 clgv: good hint

10:32 rkneufeld: http://www.learndatalogtoday.org/ is pretty badass for learning the datalog syntax

10:51 jamii: Hotspot is so fast it goes back in time - https://gist.github.com/jamii/6341985

10:52 wakeup: hi

10:52 How do I get the list of values from a set?

10:52 tried vals without luck

10:53 jamii: wakeup: (seq ...)

10:53 wakeup: cool thank you jamii

11:00 Denommus: hi

11:00 is the Clojure REPL application for Android open source or something?

11:01 deg: cemerick: You around? re the pprng/cljsbuild issue (https://github.com/cemerick/pprng/issues/1 for lurkers)... So, what's best practice until the cljsbuild issue is resolved? Remove the libs line and copy the js file into my project for now?

11:02 nDuff: Denommus: https://github.com/clojure-android/clojure

11:03 Denommus: nDuff: no, I was talking about Clojure REPL, an application for android. They have a splash screen, aparently written in Java. But I can't get my own splash screen to work

11:03 nDuff: Denommus: that repo is created by the one from sattvik, who created the Android application you refer to.

11:03 Denommus: nDuff: thanks

11:04 nifff: can someone help me with reducers/pmap ,i know pmap is for slow functions and similar evaluation time for each member

11:04 when to use reducers?

11:07 noncom: nifff: afaik reducers be used when possible... this is a development of the theory where the formulation becomes more abstract and allows for generalizing the concept. that results in writing better implementation for reduce

11:08 nifff: i am new and confused,sometime when i use reducer its fast others its not,i dont know when to use them

11:14 TimMc: jamii: That's not good. :-(

11:15 jamii: You should maybe file an issue about that?

11:15 jamii: TimMC: Was just making sure its not expected behaviour first :)

11:18 coventry`: nifff: Use reducers when you have some reason for wanting to do a reduction in a nonstandard way. In a similar fashion, pmap will get you the same result as map, but does the function evaluations in parallel if possible, whereas map does them in series. Same result, different style of calculation. See the "Basics" section of http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html

11:19 nDuff: nifff: generally, you'll only get parallelization from reducers when operating on data structures that support random access -- so, say, vectors, not seqs.

11:27 squidz_at_work: I am trying to translate a iterative function to clojurescript(functional) and am stuck. The function takes an array of maps(js objects) and if there isnt an equal number of maps containing certain date values, it creates a default map for the array. Here is the javascript example: http://jsfiddle.net/N4E5c ... only the function and the data are important

11:27 seangrov`: $seen bodil

11:27 lazybot: I have never seen bodil.

11:27 squidz_at_work: I would be very grateful if anybody could give me an idea

11:28 hyPiRion: seangrov`: her nick is Bodil, lazybot is bad a captializing

11:28 at

11:28 tbaldridge: bad lazybot

11:29 seangrov`: $seen Bodil

11:29 lazybot: Bodil was last seen joining on clojure 1 week ago.

11:29 seangrov`: That was awhile ago, just heard on twitter she's not going to JSConfEu, a bit bummed

11:29 Bodil: That bot is pretty useless. :)

11:29 TimMc: $seen lazybot

11:29 lazybot: lazybot was last seen joining on elixir-lang 1 week and 4 days ago.

11:30 seangrov`: squidz_at_work: Looks like something I'd be happy to help with in a fe whours if you can wait

11:30 thanks hyPiRion

11:30 squidz_at_work: seangrov`: Yeah I would be thankful for any help

11:30 muhoo: $seen a function more prone to abuse

11:30 lazybot: a was last seen joining on clojure 59 weeks and 1 day ago.

11:30 squidz_at_work: seangrov`: if I can't figure it out by then

11:30 seangrov`: Bodil: Woops, I guess it is

11:31 Bodil: seangrov`: Yeah, I basically had to choose between JSConf and Strangeloop. And that's not a choice. :)

11:31 TimMc: uh-oh, I may have precipitated another seenstorm

11:31 hyPiRion: muhoo: it's safe, really. nicks can't start off with a comma

11:31 muhoo: $seen the light

11:31 lazybot: I have never seen the.

11:32 seangrov`: Bodil: Ah, I didn't have that luxury, just barely ended up getting two tickets to JSConf

11:32 I'll have to be on top of my game next year for Stangeloop

11:32 Oh well, I'll chat with you about cljs stuff in person another time

11:33 Bodil: EuroClojure? :)

11:33 squidz_at_work: the array should have an equal number maps containing the same key. if not -> insert map with default values. [{:key group1 :date 1/1/13 :val 200} {:key group1 :date 1/1/12 :value 400} {:key group2 :date 1/1/12 :val 100}] -> since there are not two group2's insert insert map {:key group2 :date 1/1/13 :val 0}

11:33 dnolen: squidz_at_work: let me see if I understand

11:33 lgs32a: i have a very strange problem

11:34 dnolen: squidz_at_work: each group may not have the same number of entries, so you want to pad them in with a default date value?

11:34 seangrov`: Bodil: Might be irresponsible for me to spend more than a month in Europe, what with this whole "job" thing :)

11:34 But I did see it, and if it were one week earlier, I would go

11:34 Bodil: seangrov`: Ah, well, Clojure/conj? :)

11:35 lgs32a: since today i cannot import anything from sun.jvmstat.monitor package anymore, on openjdk

11:35 i even tried it with a different user on my system with a blank leiningen project

11:35 the package is gone

11:36 seangrov`: Bodil: Yes, that seems reasonable. I'll add it to my calendar and look at tickets

11:36 lgs32a: is this related to some leiningen update? can anyone confirm?

11:38 anildigital: I am solving this http://www.4clojure.com/problem/99 here is solution of mine .. but why is it not working https://gist.github.com/anildigital/5035a058027e878fe3d6

11:38 looks correct to me.. but 4clojure is saying

11:38 You tripped the alarm! def is bad!

11:39 hyPiRion: anildigital: you're not allowed to use def.

11:39 noncom: lgs32a: do you get an error message?

11:39 ToxicFrog: anildigital: don't use def/defn. Like it says, the code needs to fill in the blank - it needs to be something you can splice into the code given.

11:39 anildigital: hyPiRion: then?

11:39 ToxicFrog: okay let me try

11:39 hyPiRion: anildigital: make an expression returning a fn

11:40 lgs32a: noncom: (import

11:40 '[sun.jvmstat.monitor MonitoredHost]) ==>

11:40 ClassNotFoundException sun.jvmstat.monitor.MonitoredHost java.net.URLClassLoader$1.run (URLClassLoader.java:366)

11:40 noncom: lgs32a: and your IDE is?

11:40 lgs32a: emacs/nrepl

11:40 i tried it in a plain lein repl as well

11:41 dnolen: lgs32a: I doubt it, http://stackoverflow.com/questions/6196984/how-do-i-include-jvmstat

11:41 Denommus: hm, it seems the newer version of lein droid already creates a splash activity for me. Great :D

11:41 I just... don't know where the source code is

11:41 lgs32a: dnolen: thanks

11:41 anildigital: hyPiRion, ToxicFrog thanks

11:42 noncom: jarfinder is cool

11:42 lgs32a: dnolen: i already found this but the strange thing is that until yesterday it worked

11:42 hyPiRion: lgs32a: did you update the jdk version of yours?

11:43 lgs32a: no

11:43 i changed nothing

11:43 maybe leiningen updated itself or some other library

11:43 hyPiRion: No, leiningen doesn't update itself

11:43 lgs32a: hmmmm

11:43 hyPiRion: It pulls snapshots daily though

11:44 lgs32a: is it possible to add tools.jar globally in profiles.clj?

11:44 ToxicFrog: This is probably not the best way to do it: (fn [x y] (->> [x y] (apply *) str vec (map int) (map #(- % (int \0)))))

11:44 What's the good way to turn \1 into "1"? (int ...) is a ClassCastException.

11:44 hyPiRion: ToxicFrog: str

11:45 ToxicFrog: Wait, sorry, wrong question

11:45 \1 into 1

11:45 (int ...) returns the character code, (int (str ...)) is a ClassCastException.

11:45 solussd: hrm.. clojurescript doesn't have 'extends?'. How do you check to see if a record type extends a particular protocol?

11:45 hyPiRion: ToxicFrog: (- (int char) 48)

11:45 ToxicFrog: Well yes, that's basically what I'm doing there

11:45 It seems like there should be a better way, though.

11:45 hyPiRion: (48 is the 0 char)

11:46 ToxicFrog: That doesn't e.g. rely on being in a character set where the digits are contiguous and start with 0.

11:46 Yes, I know, there's a (map #(- % (int \0))) right there

11:46 hyPiRion: ToxicFrog: well, you could use a map if you wanted to

11:46 {\0 0, \1 1, \2 2} etc

11:46 `cbp: ToxicFrog: I've never seen a 'better' way unless its some dumb trick like js's +

11:46 ToxicFrog: It seems like there should be a general, character-set-independent function for "turn a char or str into the int it represents"

11:47 A la lua's tonumber(), or C's atol()

11:47 hyPiRion: (comp read-string str) does the job then

11:47 solussd: parseInteger?

11:47 ToxicFrog: solussd: where is that?

11:47 hyPiRion: solussd: no, that's too hard.

11:47 ToxicFrog: Integer/parseInt

11:48 solussd: there we go

11:48 ToxicFrog: Oh, it's in Java.

11:48 That explains why I couldn't find it.

11:48 solussd: and in javascript

11:48 `cbp: ToxicFrog: you cant parseInt a char though

11:49 ToxicFrog: `cbp: you can ->> the-char str parseInt, though

11:49 Which I find less ugly than subtracting \0 from it

11:49 tbaldridge: ToxicFrog: ick

11:49 solussd: (Integer/parseInt (str mychar)) ? :)

11:49 jamii: Surprised to find that (instance? Foo x) is significantly faster than (= Foo (class x))

11:49 solussd: oh, wait, brb

11:49 `cbp: you have weird taste imho :-)

11:49 ToxicFrog: tbaldridge: well, in this case it's part of a longer ->> chain

11:49 dnolen: jamii: = is equiv, it'll do an identity check but slow for the failed case (bunch of other checks)

11:49 ToxicFrog: If it were just that I'd probably (parseInt (str the-char))

11:50 dnolen: jamii: use identical?

11:50 ToxicFrog: That said, I do like the whole -> family for making things more readable.

11:50 jamii: dnolen: ah, will try that

11:50 tbaldridge: ToxicFrog: char num to string:

11:50 ,(- (int \0) 48)

11:50 clojurebot: 0

11:50 tbaldridge: ,(- (int \4) 48)

11:50 clojurebot: 4

11:51 ToxicFrog: tbaldridge: we just went over this twice

11:51 `cbp: He says that's too ugly

11:51 solussd: ToxicFrog: how about this? https://www.refheap.com/18031

11:51 tbaldridge: ToxicFrog: ah, didn't see the history.

11:51 ToxicFrog: Not only is it ugly, it relies on the characters being in a character set where digits are contiguous and ascending from 0.

11:51 jamii: dnolen: I remember testing the same thing last year in core.logic (closed dispatch on type) but I don't remember what won...

11:51 ToxicFrog: Integer/parseInt is what I was looking for.

11:51 TimMc: ,(Integer/parseInt "८९")

11:51 clojurebot: 89

11:51 tbaldridge: Still, a char is a integer, just do simple math, simpler cleaner, etc.

11:52 TimMc: ^ parseInt also does that

11:52 ToxicFrog: I just couldn't find it because I was looking for a Clojure function rather than a Java one. That's all.

11:52 dnolen: jamii: probably best to use instance? or something similar if you can

11:52 TimMc: Whether you see that as a positive or a negative is unclear.

11:52 ToxicFrog: tbaldridge: simple math that gets you nonsensical results as soon as you're working in something not ASCII-compatible!

11:53 tbaldridge: ToxicFrog: true, I don't often work with non ASCII numbers, actually I don't do it at all, so I am biased in that respect.

11:53 nDuff: ...anyone have a feel for whether/when rhickey will be merging feature expressions?

11:53 tbaldridge: Glad you found a solution

11:53 jamii: dnolen: it does look like that is the fastest. I guess its pretty heavily optimised in the jvm

11:53 tbaldridge: nDuff: There was some talk about it a few months ago, then we got a bit tied up with core.async, haven't heard about it since. Also I'm not sure anyone fully likes any of the ideas.

11:54 ToxicFrog: In other news: is there a reason that :require/:use aren't overloaded to support Java classloading as well, instead having :import instead?

11:54 tbaldridge: nDuff: I think everyone involved in that confluence page is hoping a better solution appears, as they all have some rather serious drawbacks

11:55 ToxicFrog: don't complect things? :-P

11:55 ambrosebs: not *more* features for use :)

11:55 nDuff: tbaldridge: *nod*. Reader macros aren't so great for tools that round-trip code, either, which makes me somewhat unhappy with that proposal too. Unfortunately, _not_ having any solution in place at all is arguably worse than having something with significant flaws.

11:56 ToxicFrog: ambrosebs: it's more that if I :require foo.bar, I would expect that to work whether foo.bar is a clojure or a java package.

11:57 ambrosebs: clojure and java packages have different syntax, which is probably why they are separated.

11:57 tbaldridge: ToxicFrog: the mechanics of the two are completely different, I prefer to have more control over what happens, if I don't want the interface a protocol defines, I simply don't import it.

11:59 scriptor: trying to get a basic understanding of protocol internals

11:59 when you call defprotocol, does clojure generate a dispatch function for each protocol function you declare?

12:01 tbaldridge: scriptor: yes. It also creates a Java interface that types can inherit for super fast dispatch, and the functions also look at an internal hashmap for fallback in cases where you extend-type after the type has been created. There is also magic that makes all this work with excellent performance.

12:02 scriptor: it's that magic that's intriguing the hell out of me :)

12:03 I figure with the internal hashmap a new entry gets added for each new type, function-implementation pair added via extend-type

12:06 deg: cemerick: ping?

12:07 cemerick: deg: maybe-pong

12:07 deg: Re the pprng/cljsbuild issue (https://github.com/cemerick/pprng/issues/1 for lurkers)... So, what's best practice until the cljsbuild issue is resolved? Remove the libs line and copy the js file into my project for now?

12:08 cemerick: deg: either that or don't run auto

12:09 deg: You mentioned that you had removed the lib line altogether from your projects. That would break things even without auto.

12:09 rurumate: Hi, when I do (let [[a b] x] (if (= 1 a) "a is 1" [a b]), will a new vector [a b] get created in the else case, or is the compiler smart enough to reuse the input?

12:10 oops, seems like it needs another bracket

12:12 I mean, this: (let [[a b] [2 2]] (if (= 1 a) "a is 1" [a b]))

12:12 cemerick: deg: I meant, from a project that wasn't using pprng or otherwise required :libs at all.

12:12 rurumate: it will return [2 2], but was a new vector created or was the input reused?

12:12 `cbp: rurumate: (let [[a b :as y] x] ... y)

12:13 cemerick: I had blindly copied it over from a prior project.clj in that case

12:13 rurumate: `cbp: ok nice

12:13 `cbp: oh wait nevermind im wrong

12:14 squidz_at_work: dnolen: yes they may not have the same number of enttires, and in that case i want to create additional maps for those groups so that each group has the same number

12:15 deg: cemerick: Ah, ok. So for now, I can either copy the lib or deal with slowness and no auto. Both are acceptable for the now. I had just hoped you had some magic bullet. Ah well.

12:15 cemerick: deg: nope. I'll see about getting a fix into cljsbuild shortly.

12:16 `cbp: rurumate: well you can use that in your [2 2] example, but if you have x then the y is redundant :-P

12:16 dnolen: scriptor: there's also call site caching for protocol fns to avoid hash table lookups.

12:16 squidz_at_work: dnolen: so that for each group there is a map for each date

12:16 and in the cases where a map is created the value be set to 0

12:18 which is what that first function does in http://jsfiddle.net/N4E5c/ but i'm not sure how to translate that to clojurescript

12:19 dnolen: sorry here is the correct link http://jsfiddle.net/N4E5c/3/

12:24 ucb: callen: ping

12:39 anildigital: what's wrong with this code https://gist.github.com/anildigital/830d565a5e05c911b972

12:39 not compiling as expected

12:40 bbloom: anildigital: would help if you said what is expected and what you're actually getting

12:42 anildigital: ClassCastException java.lang.String cannot be cast to clojure.lang.IFn bob/response-for (bob.clj:5)

12:42 bbloom: ^

12:42 bbloom: anildigital: that's what i expected :-) but trying to teach a man to fish here

12:42 anildigital: that error is saying that you have a string where the runtime expects an IFn

12:42 nDuff: anildigital: well, ("foo") is trying to call "foo" as a function.

12:42 rasmusto: anildigital: it's trying to call "Tom-ay-to, tom-aaaah-to." as a function apparantly

12:42 coventry: anildigital: What do you want ("Tom-ay-to, tom-aaaah-to.") to do?

12:43 bbloom: nDuff: shhhh trying to help him help himself :-)

12:44 coventry: Maybe you want (println "Tom-ay-to, tom-aaaah-to.")?

12:45 cmajor7: anildigital: ("Tom-ay-to, tom-aaaah-to.") is interpreted as function

12:45 anildigital: but it is in fact a string

12:45 anildigital: bbloom: return as string

12:45 coventry: If you want it to return that string, just take it out of the list it's in.

12:45 bbloom: anildigital: parens, generally, mean to call a function

12:45 cmajor7: anildigital: (defn response-for [input] (when (= input "Whatever.") "Tom-ay-to, tom-aaaah-to."))

12:45 coventry: I.e., ("Tom-ay-to, tom-aaaah-to.") => "Tom-ay-to, tom-aaaah-to."

12:46 anildigital: cmajor7: thanks

12:47 bbloom: thanks.. I though something in parens get returned as it is

12:47 coventry: What can I use to get a parse tree of a clojure form prior processing of reader macros like backticks?

12:47 s/prior/prior to/

12:47 bbloom: coventry: tools.reader, probably

12:49 hiredman: bbloom: I doubt it

12:49 coventry: tools.reader.read is great for mimicking the results of the clojure reader, but I am not sure how to turn off the reader macros. Is there a way to reach into the tools.reader ns and monkeypatch private fns like read-syntax-quote?

12:49 bbloom: hiredman: i thought Bronsa made the quasi-quote a dynamic function you could configure & just replace w/ identity

12:49 or maybe i imagined that

12:51 coventry: bbloom: I could certainly do that if I copy-and-pasted the library and monkeypatched it. Is there a less icky way to achieve the same result?

12:51 bbloom: coventry: contribute a patch to parameterize it? :-) I think just throwing a ^:dynamic on that function & making it part of the API would pretty much solve the issue

12:52 coventry: Thanks for the suggestion, I'll try that.

12:55 Actually, I think the structure to make dynamic is probably the dispatch functions `macros` and `dispatch-macros`.

12:56 (or something like that.)

12:59 dnolen: squidz_at_work: so you're actually trying to port this to D3 using CLJS? You will have to do some data conversions.

13:04 Bronsa: bbloom: there never was such a thing in tools.reader, you must have imagined it

13:04 bbloom: Bronsa: you should add that :-)

13:04 squidz_at_work: dnolen: i'm using the strokes library which takes care of converting for me

13:06 Bronsa: bbloom: it's probably best to make `macros` dynamic then

13:07 bbloom: Bronsa: i'll assume that's a map of reader macros? i haven't studied the source closely

13:07 Bronsa: that's where the dispatch happens, not a map but a case for performance

13:07 coventry: It's a function with a case switch, which I was thinking could easily be made to depend on a configurable map instead. (But maybe that's not the best idea.)

13:09 ownatik: How should I store global config that I want accessible across multiple namespaces?

13:09 atom?

13:09 nDuff: ownatik: ...well, it's ideal not to do that. :)

13:10 ownatik: a dynamic var probably makes more sense than an atom.

13:10 ownatik: nDuff: Im actually looking for the ideal way :)

13:10 dnolen: cemerick: are you planning on bumping lein-cljsbuild to the latest release? it seems that lein-cljsbuild actually needs to be kept in sync for browser REPL. Probably best to just remove the dependency as I'd suggested in the past.

13:11 ownatik: passing the configuration data from functions to function does not seem very clean in my current application state.

13:12 `cbp: ownatik: I'd say that is cleaner than global state and you can use partial to set some defaults, otherwise a dynamic var or atom are fine if they are supposed to change

13:13 ownatik: they are not supposed to change .... I will be storing command line arguments in there.

13:15 `cbp: ownatik: then just use a dynamic var if you feel its too cumbersome to pass values or use partial. Extra argument passing is normal in functional programming though.

13:33 seangrov`: `cbp ownatik: referential transparency and all that

13:37 justin_smith: is clojure-clr actually usable?

13:39 nDuff: justin_smith: it was originally a first-tier implementation, maintained in lockstep with Clojure for the JVM.

13:39 justin_smith: how out of step is it?

13:39 nDuff: Hard to say. The language hasn't been moving _that_ quickly, though, so I'd expect it to be thoroughly usable still.

13:40 justin_smith: I may consider using it for stuff where the spin up time of the jvm is a nogo

13:45 the github page does not mention a version, and the references to the jvm in the changelog confuse me (copy paste error?) https://github.com/clojure/clojure-clr/blob/master/changes.md

13:55 seangrov`: Ok, found a hackish-way to get the constants table output at the right location, more of the cljs test suite passes now

13:57 eric_normand: clojure error messages!

13:58 doesn't even tell me what file it's in

13:59 mabes: eric_normand: are you printing the full stack trace?

13:59 eric_normand: yes

14:00 I believe so

14:00 it's a compiler error

14:00 mabes: ,(doc pst)

14:00 clojurebot: "([] [e-or-depth] [e depth]); Prints a stack trace of the exception, to the depth requested. If none supplied, uses the root cause of the most recent repl exception (*e), and a depth of 12."

14:00 mabes: yeah, compiler errors can be tricky at time but they generally have some hint as to what file caused the problem

14:00 eric_normand: I'm definitely seeing that one of the imports of a particular file is failing to compile

14:01 but not which required file it is

14:01 mabes: but I found it

14:01 mabes: I had only edited a few files before compiling

14:01 mabes: eric_normand: yeah, I am typically compiling as I go so the problem is obvious when I see it

14:02 eric_normand: mabes: me, too

14:02 mabes: I usually have nrepl open to compile to

14:02 mabes: this time, no

14:16 swarthy_: Any chance that was answered when I disconnected?

14:34 justin_s`: After finding the latest clojure-clr download (1.4.1) and getting mono up and running; the start time is significantly better but not great, ram usage is quite a bit lower

14:34 callen: justin_s`: whyyyy?

14:34 justin_s`: java without -server is generally fast enough / good enough for me.

14:34 in terms of start time, mem usage, etc.

14:34 mdrogalis: tbaldridge: ping

14:34 justin_s`: mono interop has some interesting possibilities, and even on my beast of a multiprocessor laptop startup isn't transperent enough for, say, implementing command line utilities

14:35 justin_smith: also, I have crusty old linux using friends who won't use clojure because of the mem footprint on their outdated computers, so an order of magnitude less memory used helps me spread the good word (if the ecosystem turns out to be usable)

14:36 callen: justin_smith: use Drip.

14:36 clojure llvm is probably the real path forward for command line utilities. technomancy sidesteps the problem with OCaml.

14:36 technomancy: justin_smith: mono typically doesn't go over will with the crusty crowd =)

14:36 justin_smith: technomancy: true enough, but until a bare metal or llvm clojure is usable, it is worth looking at maybe

14:37 tbaldridge: mdrogalis: pong

14:37 callen: I don't know about that. Vala exists because crusty Linux/Gnome people didn't want to use mono for desktop and command line utilities.

14:37 Vala is a credible language for writing things like that, even if it doesn't suit my fascist FP preferences.

14:38 mdrogalis: tbaldridge: Would you be able to do a small code review (~150 lines) sometime? I want to make sure I'm using core.async sanely. :)

14:38 tbaldridge: mdrogalis: sure, send it to my irc handle at gmail

14:39 mdrogalis: tbaldridge: Thanks man :)

14:43 coventry: I'm trying to run a criterium benchmark, and with-progress-reporting is outputting a long string of messages like "classes loaded before 73864 iterations" every second or so, with the number of classes increasing by about 1000 for each message. Is this normal? It's taking forever.

14:43 (And this is with quick-bench.)

14:44 hiredman: coventry: are you calling eval?

14:44 coventry: Yes.

14:45 hiredman: eval generates classes, new classes being loaded can change runtimes (the jit does class hierarchy analysis and new classes loading can cause deoptimizations, etc)

14:45 not sure if cirterium restarts the benchmarck in that case

14:47 ToxicFrog: callen: so I watched the infoQ talk and that actually did help a lot, thanks.

14:47 coventry: hiredman: Thanks, I test that out.

14:49 callen: ToxicFrog: Good. :)

14:51 cemerick: is anyone having any luck using Firefox with any browser-REPL impl?

14:51 Clearly, I've been using Chrome exclusively for too long. :-/

14:53 malyn: cemerick: Yeah, Firefox is the main browser that I use with the REPL.

14:53 cemerick: malyn: OK, thanks. Maybe something is wrong in my env. Which version?

14:54 * nDuff might be more jumping to ask which plugins are installed/active

14:54 nDuff: (noscripts? adblock? ...?)

14:55 malyn: cemerick: Hmm... I just picked up a Firefox upgrade (23) and haven't tried with that one. Definitely worked with the previous one (22, I guess?) though.

14:55 cemerick: nDuff: flashblock is the only intrusive thing I have installed

14:55 kmicu: cemerick: no problems with bREPL in conkeror (xulrunner/gecko) from version 22.0 to 25.0

14:55 cemerick: kmicu: nice, thanks.

14:56 malyn: cemerick: What problem(s) are you having?

14:59 kmicu: Some problems with cljs/pedestal rendering code, but not with REPL

14:59 cemerick: kmicu: seems like simple connection failure. I haven't dug into what's going on with the x-page channel yet.

15:01 seangrov`: jesus christ, the never-ending chained ternary conditions cljs generates are unpleasant to look at

15:02 TimMc: I ? don't : know ? what : your ? problem : is ;

15:03 seangrov`: TimMc: Thinking on it for a minute, I'm not sure it's any worse than endlessly nested if/else's

15:06 pandeiro: cemerick: i have often screwed up the repl URL by forgetting to append '/repl' to the host & port...

15:06 cemerick: pandeiro: nah, I have that all automated

15:08 callen: TimMc: wars have been fought over less than that.

15:11 dnolen: seangrov`: that's artifact of Closure

15:11 seangrov`: it's rare for CLJS to emit those, can only be done in a statement context

15:56 kmerz: hi

15:56 dobry-den: https://github.com/magomimmo/modern-cljs is amazing

15:58 coventry: For the sake of speed, clojure.tools.reader has a case statement switching on characters. It would be ugly to replace that with a HashMap<Character, Object> for the sake of configurability while preserving speed, right? How do you say "new HashMap<Character, Object>();" in clojure, anyway?

15:58 stuartsierra: coventry: Clojure's `case` is essentially that.

15:59 i.e. a hash map.

16:02 coventry: stuartsierra: Oh, interesting.

16:04 amalloy: coventry: new HashMap<Character, Object>() => {}

16:05 or (HashMap.) if you're really set on using a mutable map

16:06 coventry: amalloy: But Clojure's hashes can take arbitrary keys. I thought a HashMap<Character, Object> would have faster lookups.

16:06 amalloy: coventry: that's nonsense

16:07 HashMap<X,Y>() is just HashMap<Object,Object>() with some casts automatically thrown in by the compiler

16:07 stuartsierra: coventry, amalloy: It's not necessarily nonsense, just not relevant in the context of the JVM.

16:08 Java collections are weakly-typed.

16:09 coventry: Thanks, I went down the wrong path, then. What I meant is something which would take advantage of the fact that all the keys are characters to give fast lookup times. An array 256 elements long would work just as well, I suppose.

16:09 amalloy: coventry: s/256/65536?

16:09 a character is two bytes

16:11 coventry: I was assuming all of the reader macro characters are ascii.

16:11 tbaldridge: coventry: they are, the two byte character thing doesn't matter in this case

16:13 coventry: the java version of the reader uses an array : https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L59

16:13 stuartsierra: In theory, you could make some clever hack that takes advantage of the small key space, but it would have to be really clever to beat a hash map.

16:13 tbaldridge: coventry: but in some cases, the JVM may actually compile the case statement down to a jump table, so I'm not sure that it matters in the end

16:13 clj_newb_2345: I recently swithced from Vim to Emacs-Live for clojure development. Despite all the cool config options of Emacs-Live, anyone else find Emacs-live to be really slow / laggy?

16:14 technomancy: clj_newb_2345: probably auto-complete

16:14 but that's the problem with starter-kit-like stuff, it's very difficult to tell where the problem comes from

16:15 coventry: Thanks for the patient explanations, everyone. I think I've thought of a less ugly way.

16:17 ozzloy: is there a way to import a maven based project as a lib for use in a leiningen project?

16:18 i could swear i had seen an example of this before, but now i can't find it. specifically, i have a clojure project and i want to use hapi to generate hl7 messages http://hl7api.sourceforge.net/

16:19 llasram: ozzloy: You just depend on the repository-deployed artifacts

16:20 stuartsierra: It looks like `case` will compile into a jump table when possible: https://github.com/clojure/clojure/blob/229bf8fe9a751e4f48bb2b7ea57e27ebc43d26ae/src/jvm/clojure/lang/Compiler.java#L8128

16:20 llasram: ozzloy: Looks to be in maven central. You should just need to add [ca.uhn.hapi/hapi "2.1] to your :dependencies

16:20 (or whichever the correct specific artifact is)

16:21 ozzloy: er... so i would add a line to project.clj like :dependencies [...[ca.uhn.hapi/hapi-base "2.1"]... ?

16:21 (according to http://hl7api.sourceforge.net/getting_started.html"

16:21 llasram: Yep, exactly

16:21 ozzloy: llasram, cool, i'll give that a shot

16:24 dnolen: stuartsierra: looks like only for integers and keyword - which excluded characters.

16:25 Bronsa: I wonder if that means it would be faster to use condp + identical?

16:26 stuartsierra: dnolen: Unless you treat characters as integers! https://github.com/clojure/data.json/blob/1b0d829077f607ead37269f78fd6f04a3b2462d7/src/main/clojure/clojure/data/json.clj#L39-L57

16:26 dnolen: stuartsierra: aha! nice :)

16:28 Bronsa: dnolen: I'll check if case+converting the chars to int speeds up

16:29 coventry: dnolen: as far as I know, Bronsa is happy with the efficiency of the current case statement. I'm trying to arrange things so that the dispatch on reader-macro characters is configurable by users of the library. It would be natural to make the dispatch functions maps, but Bronsa says he chose functions with case statements because it's faster.

16:29 stuartsierra: Profile, profile, profile!

16:30 coventry: So I was trying to devise a way which would make it configurable and keep the current speed.

16:31 Bronsa: coventry: I'm happy to take a patch if the performance penalty is not significant

16:33 stuartsierra: Why should the reader macro dispatch characters be configurable?

16:33 tbaldridge: coventry: why are we trying to make the reader configurable?

16:34 stuartsierra: tbaldridge: Ha!

16:37 ozzloy: llasram, thanks!

16:37 jtoy: what kind of object is 699N ?

16:37 ozzloy: llasram, that totally worked

16:37 coventry: stuartsierra, tbaldridge: Because I would like to get the parse tree of clojure forms prior to modifications by reader macros. This is for making something like edebug or tools.trace which can do sensible things with macros without being told how to, by using the location metadata tools.reader's indexing readers put on the symbols it returns. I want the unmodified parse tree so that I can compute the MST of the symbols in the current

16:37 form.

16:37 ozzloy: i should have just tried that

16:38 jtoy: BigInt

16:38 coventry: ,(class 699N)

16:38 clojurebot: clojure.lang.BigInt

16:38 jtoy: what is N here mean though?

16:39 stuartsierra: coventry: OK, fair enough. But that probably constitutes a completely new parser.

16:40 justin_smith: ,(class 699L)

16:40 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 699L>

16:40 justin_smith: oops

16:40 stuartsierra: coventry: I believe Christophe Grande has done some work in this area: https://github.com/cgrand/sjacket

16:41 coventry: stuartsierra: Awesome, thank you.

16:41 stuartsierra: coventry: You're welcome.

16:50 gtrak: has anyone a macro that lets you use 'clojure.test/is' in utility functions but transfers the reporting bits to the calling stack frame? I'm about to write one.

16:51 I keep writing assertions macros that could be functions except for that reporting annoyance.

16:51 gleag: coventry: I don't know much about clojure, but in most dialects of Lisp, when reader macros kick in, there's no parse tree yet, and vice versa, when you have a parse tree, all reader macros are already off for the weekend.

16:53 coventry: gleag: Yes, but a parse tree of the form prior to reader macro modification still might be useful in some circumstances, e.g. for development tools.

16:54 gleag: coventry: the point is that reader macros are special in the sense that they don't operate on expression trees but on sequences of input characters.

16:54 Which means that "a parse tree prior to reader macro modification" is something that never happens.

16:56 Bronsa: stuartsierra: dnolen there seems to be no performance enhancement when using codepoint-case instead of case in tools.reader

16:56 coventry: No, it never happens in the standard reader, but it's something you could construct independently, at least with the current set of reader macros, I think.

16:56 stuartsierra: Bronsa: Interesting.

16:57 gleag: coventry: i don't see how that would be possible. Once a piece of core receives a parse tree to operate on, it's not a reader macro anymore *by definition*.

16:57 "piece of code"...

16:58 Bronsa: (my test was `(dotimes [_ 10] (read-core.clj))`)

16:58 stuartsierra: Bronsa: That's probably not enough for JVM optimizatiton.

16:58 Bronsa: not the best of benchmarks admittedly

16:58 stuartsierra: do you think criterium will do?

16:58 callen: Bronsa: use criterium.

16:59 stuartsierra: Bronsa: Yes, also be careful to eliminate any startup-time optimization settings added by Leiningen.

16:59 Bronsa: ok, so criterium + bare java -cp

16:59 stuartsierra: Bronsa: That's pretty good, in my experience.

16:59 coventry: callen, Bronsa: if you use criterium, you might have trouble using clojure/core. (See earlier IRC discussion with hiredman.)

17:00 callen: coventry: it's worked for the various template lib benchmarks I've done.

17:00 coventry: s|using clojure/core|using clojure/core for the test source code|

17:00 tbaldridge: coventry: that's only if your lib is doing runtime code generation.

17:05 gtrak: anyone have any feelings about this clojure.test hack? give you control over file-and-line: https://gist.github.com/gtrak/6346408

17:05 coventry: I'm still not sure what the problem was, but I was benchmarking with (let [s (slurp "core.clj")] (bench (read-string s))) when I ran into that problem before.

17:07 Bronsa: stuartsierra: no difference even with criterium (53ms vs 52ms)

17:07 stuartsierra: Bronsa: Not terribly surprising.

17:07 coventry: gleag: Yes, this parse tree is not something I want to execute code from. I want to use it to map the forms in the macro expansion back to a form in the source by the taking the MST of the symbols they contain.

17:07 Bronsa: I'll stick with clojure.core/case then

17:09 tbaldridge: Bronsa: I've been very happy with the performance of case, core.async abuses it to some extent, and yet I really can't find a faster int->code block dispatch.

17:10 coventry: Bronsa: could you post read-core.clj, and the command you used to run it, please? I think it will be useful for me.

17:11 Bronsa: coventry: it's a silly script but here http://sprunge.us/WEbT

17:14 hiredman: ztellman: I would be very surprised if using a protocol like https://github.com/hiredman/tuples/blob/master/src/tuples/core.clj#L24 (and of course implementing it for your tuple type) didn't outperform using nth to access elements

17:15 ztellman: of course you still need to implement nth for destructuring, but the getN functions give you something hotspot can easily optimize that sort of drops down under nth when you need peformance

17:15 ztellman: hiredman: agreed, but the idea here was to make something that was a transparent stand-in for the existing sequence types

17:15 if I care about that, it's maybe easier to just create a deftype and use member accessors

17:16 which will be faster than a defprotocol invocation

17:16 hiredman: ztellman: but less generic, a protocol can be extend to other types as well, vectors for example

17:17 ztellman: hiredman: but then get3 has inconsistent performance

17:17 coventry: Bronsa: thanks. Do you know why that would work, but (bench (read-string s)) would fail because of class loading? Actually if you could show me the criterium harness and your command-line to invoke it, that would be useful, too. Today was the first time I used it. Sounds like it was a mistake to just run it in the repl, for starters.

17:17 hiredman: ztellman: nth has inconsistent performance

17:18 nth is linear access on seqs

17:18 ztellman: hiredman: absolutely, but it doesn't claim anything else

17:18 this is "a faster nth, sometimes, maybe"

17:19 hiredman: ztellman: the use case I see for something like tuples is: oh I want something faster than vectors, ok swap in the tuples, ok I want to go faster still, oh I can switch to the tuple access protocol

17:19 (which of course leaves out the smaller memory foot print for tuples)

17:19 ztellman: right, but why extend the access protocol to vectors?

17:20 inlined interface calls are significantly faster

17:20 so you're sacrificing performance for the case where you want to switch from tuples back to a slower collection

17:20 hugod: coventry: criterium tries to ensure that jit is completed, and checks for classloading as a sign that jit is still in progress - at present it does not support eval, etc

17:21 hiredman: ztellman: if you extend the protocol to the type inline it is an interface call with the little wrapper and cached callsite

17:21 ztellman: cached callsite ain't free

17:21 hiredman: ztellman: sure :)

17:22 ztellman: if all the function is doing is returning a value, the difference shows

17:22 hiredman: ztellman: sure, but odds are if you are chasing speed you are doing more than that in your inner loop

17:23 ztellman: hiredman: get0 by definition only returns a value

17:23 I'n not sure I follow

17:23 I'm*

17:23 hiredman: ztellman: yeah, but it is the protocol function, the callsite isn't in get0, it is in the client code that consumes it

17:24 ztellman: it's still 1:1 with get0 invocation, right?

17:24 is there something clever being done that I'm unaware of?

17:25 hiredman: ztellman: well that depends what you mean by invocation(runtime function calls? function calls in the code), if you put get0 in a loop, you will get one callsite and multiple invocations at runtime

17:25 coventry: Thanks, hugod. I'm trying to understand why Bronsa's (r/read (rt/string-push-back-reader (slurp "core.clj")) true nil true) doesn't trigger that issue, whereas my (r/read-string (slurp "core.clj")) does.

17:28 hiredman: ztellman: anyway, clj-tuple is a neat little library

17:28 ztellman: hiredman: I had assumed the callsite lookup was once per invocation

17:29 I guess I need to look at that a bit more closely

17:29 and thanks, I didn't realize you had done something similar

17:29 hiredman: meh, just toying with the idea

17:31 actually amalloy did a pr switching the backing to an array which changed some performance characteristics

17:32 but from the email it sounded like you had already looked at arrays instead of fields

17:34 ztellman: hiredman: runtime function calls

17:35 oh, crap, had scrolled up

17:35 assumed that was a new message

18:18 bja: is there a -> variant that accepts a sequence of forms (and manually unrolls them before threading through)?

18:19 scriptor: ,(-> 1 (+ 2) (+ 3))

18:19 clojurebot: 6

18:19 scriptor: ,(apply -> [1 '(+ 2) '(+ 3)])

18:19 clojurebot: #<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/->, compiling:(NO_SOURCE_PATH:0:0)>

18:19 scriptor: bleh

18:21 `cbp`: bja: I don't understand what you're asking, can you provide an example of what you want?

18:21 `cbp: what does unrolling a form mean?

18:21 bja: (-> 1 [inc inc inc])

18:22 basically

18:22 I have a sequence of functions that I'd like to thread through

18:22 hyPiRion: bja: closest is possibly thrush, which is just (defn trush [init & fns] (reduce #(%2 %1) init fns))

18:22 $google thrush fogus

18:22 lazybot: [fogus: Thrush in Clojure – Redux] http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/

18:23 scriptor: -> is a macro, so if the sequence is generated at runtime it wouldn't work

18:24 justin_smith: scriptor: that is why thrush probably does what you want

18:24 scriptor: yep

18:24 justin_smith: it just doesn't do the magic argument insertion, which will require some refactoring

18:24 `cbp: bja: maybe (apply comp (reverse fns)) ?

18:29 coventry: I think I was getting that criterium failure because I was running it under a lein repl. My script runs fine under Bronsa's framework.

18:41 bja: https://gist.github.com/b018da2c94f5d4b9d9d7

18:41 that is essentially what I'm after

18:41 perhaps with (list ...) replaced with a literal quoted list or a vector

18:43 bbloom: i've been reading haskell for years, and yet somehow i find it easier to read an obscure dialect of scheme nobody has ever used than i find it to read haskell

18:44 `cbp: bja: is there any special reason you need a macro?

18:45 bja: I was under the assumption that since -> existed as a macro, that doing nearly the same thing would also be. I don't want a macro. I was just curious if something already existed. The answer appears to be no.

18:47 justin_smith: (apply comp (reverse fns)) is smaller than many function names in competing languages :)

18:47 benkay: does anyone have tips to share on the topic of rendering clojure well in browsers?

18:48 justin_smith: you could look into what 4clojure is using js wise

18:49 `cbp: or refheap

18:49 justin_smith: on 4clojure: code: https://www.4clojure.com/script/codebox__v2.0.0-rc1.js usage https://www.4clojure.com/script/foreclojure__v2.0.0-rc1.js

18:50 oh, nevermind the "code" link, that is wrong

18:51 http://codemirror.net/ it appears this is what they are using (it has a clojure mode) http://codemirror.net/mode/clojure/

18:51 brehaut: code mirror is pretty amazing

18:52 justin_smith: yeah, refheap uses codemirror too

18:52 looks like that is likely the way to go

18:52 patchwork: benkay: I am using SyntaxHighlighter with some success

18:53 Though I also use codemirror in another project

18:53 Raynes: I don't use codemirror for code highlighting.

18:53 patchwork: Codemirror is actually an editor though

18:53 Raynes: I use it for the editor.

18:53 You *can* use it for highlighting though.

18:53 patchwork: Raynes: right

18:53 Raynes: I prefer to just shell out to pygments.

18:53 Pygments supports far more languages.

18:53 patchwork: Raynes: But that has a python dependency : (

18:53 `cbp: = (

18:53 patchwork: SyntaxHighlighter is all js

18:53 Raynes: patchwork: http://www.youtube.com/watch?v=DksSPZTZES0

18:54 gtrak: can pygments run in jython? looks like it can: http://pygments.org/docs/java/

18:54 patchwork: Raynes: Ha! I would rather not run python every time I want to deploy my project

18:54 gtrak: That would solve that

18:54 Raynes: patchwork: Are your code samples dynamic or static?

18:54 If they're static then you need to generate HTML with pygments exactly once.

18:55 patchwork: But if they are dynamic… you need js

18:55 Raynes: No you don't :p

18:55 Refheap uses pygments and you can change pastes/add new ones/etc.

18:55 It just regenerates when it needs.

18:55 patchwork: It is not compiling the html in the background?

18:55 Aha yeah

18:56 But if you don't want to have a python process running in the background on your server, then yeah

18:56 you need js

18:57 benkay: well thanks y'all

18:58 seangrov`: dnolen: How do you output debug statements when debugging core_test.cljs? I've caused a stack overflow somewhere, but it's nmot easy to see where

18:59 Specifically for v8

19:02 I can set the d8 stack_trace_limit to 15000 and it works enough to find the line, but it's not ideal

19:02 mikerod: is there a good work around to clojure.walk/walk not throwing "UnsupportedOperationException Can't create empty:" when a Symbol referencing an IRecord is found in the nested structure?

19:03 I see this https://github.com/stuartsierra/clojure.walk2 exists, but has not replaced clojure.walk yet.

19:06 bbloom: mikerod: the usage of the extend function in that code makes me happy

19:08 mikerod: bbloom: are you referring to extend in clojure.walk2? I agree it looks to be a better implementation of clojure.walk.

19:08 bbloom: mikerod: well stuart wrote the first walk too, i believe :-)

19:08 mikerod: I'd prefer to not have to take on this additional dependency in my current project though.

19:08 I think I remember reading that he wrote the first one.

19:09 bbloom: mikerod: but i was making a more general comment that i like the "extend" function as opposed to macros that expand to extend-type or extend-protocol

19:09 Bronsa: there's still hope with http://dev.clojure.org/jira/browse/CLJ-1239

19:10 seangrov`: Hrm, something about Keyword$IEquiv is causing a stack overflow when building BitmapIndexedNode

19:10 mikerod: I saw these related jiras. I wished they'd be accepted :P

19:10 bbloom: you like the usage of extend over extend-type and extend-protocol?

19:11 I'm used to seeing the macro variants being used

19:11 bbloom: mikerod: extend-type and extend-protocol are syntax, they are macros. they are appropriate for that use. but here, he's using doseq over a vector of types & calling a *function* not a macro

19:12 dnolen: ^^ that's why we need extend in cljs :-)

19:13 mikerod: bbloom: It looks like a clever approach to not repeating the walkt-transient on all the types that use it in the extend-protocol

19:14 bbloom: mikerod: yup, that's exactly what it's for. but sadly you don't see it much b/c 1) most of clojure's internal abstractions are java interfaces and 2) extend isn't in cljs

19:15 mikerod: ah, I see. sad indeed.

19:23 Raynes: $login

19:23 lazybot: You've been logged in.

19:23 Raynes: $shell git pull

19:24 Hm.

19:24 $shell git pull origin master

19:24 lazybot: Updating 1d0a2f5..6c592a3 Fast-forward src/lazybot/plugins/seen.clj | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-)

19:24 Raynes: $reload

19:24 I suck at configuring things.

19:25 `cbp: cheshire doesnt support joda.time.DateTime =(

19:26 dakrone: `cbp: it's easy to add your own encoders

19:26 Raynes: $reload

19:26 lazybot: Reloaded successfully.

19:26 Raynes: hyPiRion: Your change should be live now.

19:26 dakrone: `cbp: it doesn't by default because it would require bundling joda with cheshire

19:27 hyPiRion: Raynes: whoa what man

19:27 Raynes: Not going to bother converting the old nicks.

19:27 hyPiRion: $seen hypirion

19:27 lazybot: hypirion was last seen talking on #clojure 44 milliseconds ago.

19:27 `cbp: dakrone: Oh I'll look up how to do that

19:27 hyPiRion: You're damn fast

19:28 dakrone: `cbp: https://github.com/dakrone/cheshire#custom-encoders

19:28 hyPiRion: (inc Raynes)

19:28 lazybot: ⇒ 36

19:29 `cbp: dakrone: thanks

19:34 callen: dakrone: also I liked your alter-var-root for removing encoder protocol implementations :)

19:37 dakrone: callen: hah, thanks

19:42 ddellacosta: Raynes: <java idiot> upgrading from fs 1.2.x to most recent, I see temp-file args no longer contain directory. Can I set this, or is it best practice to assume java.io.tmpdir is where temp files should be going?</java idiot>

19:43 Raynes: wat

19:43 temp-file shouldn't have changed since it was added.

19:43 ddellacosta: really? huh, wait a sec then, chances are I'm being stupid...

19:43 Raynes: ddellacosta: I don't think it ever had a directory argument.

19:44 ddellacosta: However, it gets java.io.tmpdir every time so you can change that if necessary.

19:44 ddellacosta: Raynes: okay, thanks for the sanity check. Not sure what is up with this old crusty code I'm fixing up, but I didn't write it originally so don't know what the deal is.

19:45 one of those, "it was working before" kinda dealies

19:45 justin_smith: is there a standalone nrepl client

19:46 technomancy: justin_smith: working on it

19:46 Raynes: ddellacosta: I'm stupid.

19:46 ddellacosta: Raynes: ?

19:46 Raynes: ddellacosta: There was an old implementation that took directory.

19:46 justin_smith: like say I have a long running process with an nrepl server, and I decide to connect to it to debug - is that only possible from within an editor? is there a standalone program? a way to make one nrepl actually send all commands to the other in a "sub repl"

19:46 Raynes: I just checked my git history.

19:46 justin_smith: technomancy: cool

19:47 technomancy: justin_smith: I have a command that can send a single form

19:47 Raynes: ddellacosta: I changed all of that around because there were race conditions and such.

19:47 technomancy: it's not so much of a repl as a rep

19:47 justin_smith: technomancy: I would like to see that

19:47 ddellacosta: Raynes: ah, so I'm not crazy. Well, it's no biggie, I just wanted to make sure I wasn't doing something stupid. Mostly I want to figure out the best thing to do in this particular case, which you answered my question regarding above. But thanks for checking. :-)

19:48 technomancy: justin_smith: that said, you can use `lein repl :connect $PORT` and it works a lot better if you don't mind waiting for JVM startup

19:48 justin_smith: technomancy: that actually is acceptable

19:48 muhoo: `cbp: https://www.refheap.com/18049

19:49 callen: muhoo: cool :)

19:49 `cbp: any news on pomegranate/sync! ?

19:49 did you look at the Ritz implementation?

19:49 technomancy: justin_smith: that's probably for the best; then you don't have to spend half an hour installing ocaml compilers+libs

19:50 danielszmulewicz: technomancy: when you type `lein run` just after `lein new app my-project` with no modification, you get the `hello world` string, but when you type `lein uberjar` and then run `java -jar standalone.jar`, you get class not found. Not what I expected. Is this by design?

19:51 technomancy: danielszmulewicz: hm; no, that's an oversight

19:51 hyPiRion: danielszmulewicz: do `lein upgrade` :)

19:51 technomancy: it's missing both :main and :gen-class, the heck

19:51 * `cbp blushes

19:52 danielszmulewicz: technomancy: :gen-class is there, :main too

19:52 technomancy: oh, never mind

19:52 `cbp: callen: from what I vaguely recall from 2 weeks ago Ritz only reloads the classpath and doesnt fetch any dependencies, also I don't think just reloading would work but I cant try in a couple hours

19:52 technomancy: I was invoking the default template

19:53 hyPiRion: oh, you silly sausage.

19:53 danielszmulewicz: Leiningen 2.3.1 on Java 1.6.0_51 Java HotSpot(TM) 64-Bit Server VM

19:53 `cbp: callen: I'll work on it over the week promise! =P

19:53 hyPiRion: danielszmulewicz: just upgrade to 2.3.2

19:53 technomancy: the app template is missing :aot though, which is silly

19:53 `cbp: I can try in a couple hours*

19:53 danielszmulewicz: technomancy: oh, that's it, right, thanks.

19:55 `cbp: I need to reread the Ritz code so I can remember. Anyway be back in 1.5 hours

19:55 callen: `cbp: nuts @ Ritz. I'm grateful for anything you put into it, thank you! :)

19:56 `cbp: callen: np

19:56 muhoo: thanks for the snippet

19:56 hyPiRion: technomancy: the app template has `:profiles {:uberjar {:aot :all}}`, doesn't it?

19:57 technomancy: hyPiRion: yeah, but it emits a warning because of :main nonetheless

19:58 hyPiRion: ah

19:58 technomancy: it needs ^:skip-aot

19:58 not :aot

20:00 hyPiRion: right

20:03 danielszmulewicz: hyPiRion: can I see somewhere an app template with the correct aot settings. I think it's possible to run into issues when using org.clojure/tools.namespace

20:03 hyPiRion: danielszmulewicz: well, 2.3.2's `lein new app foobar` should work, even though there are some warnings during uberjaring

20:04 danielszmulewicz: technomancy: aot disabled in dev profile, but enabled in production, is that right?

20:04 technomancy: danielszmulewicz: that's my recommendation, yeah

20:04 danielszmulewicz: though you don't benefit from it unless you customize :target-path =\

20:05 (see the end of `lein help faq`)

20:05 hugod: `cbp, callen: what's pomegranate/sync!?

20:05 danielszmulewicz: hyPiRion: thanks.

20:06 technomancy: thanks

20:09 seangrov`: dnolen: Ok, I have real keywords and the test suite passes on simple mode except for this test in spidermonkey: (assert (not (integer? 1e308)))

20:10 danielszmulewicz: hugod: have you seen this? https://github.com/cemerick/austin/issues/11

20:10 seangrov`: Looks like it works with advanced optimizations as well

20:10 danielszmulewicz: hugod: does it make sense?

20:11 ddellacosta: Raynes: on another note, fs seems to be barfing on the Java 7 (java.nio.file.Files and the like) import--I see there is a conditional import commit () but it's not released yet.

20:13 hugod: danielszmulewicz: I'll try and take a look later

20:13 danielszmulewicz: hugod: sure.

20:15 ddellacosta: Raynes: ah, I see there is a 1.4.5 in clojars, never mind.

20:16 callen: hugod: "sync with project.clj"

20:16 hugod: it was in my to-do list, but `cbp wanted something to do so I let him pick it off the queue.

20:16 hugod: automatically downloads deps and syncs classpath with whatever is in project.clj

20:23 seangrov`: bbloom: Up for a code review for a cljs patch?

20:23 bbloom: seangrov`: um…. i've got about 15 minutes :-)

20:24 seangrov`: Heh, I'll commit and push if you wouldn't mind perusing

20:25 bbloom: sure, i'll do what i can before i gotta run to dinner

20:27 seangrov`: bbloom: https://github.com/sgrove/clojurescript/compare/real_keywords

20:28 bbloom: seangrov`: ooo interesting commit message. i'm interested….

20:28 seangrov`: dnolen asked to make this a configurable thing, which I suppose I really haven't done, on reflection

20:28 bbloom: why configurable? in what way?

20:28 seangrov`: The compiler/analyzer/closure stuff is configurable, but I've changed core.cljs so that it depends on real keywords

20:29 So you can keep the old "string as keywords" behavior if you don't want to switch over initially

20:29 bbloom: hmm… i'm not sure why we'd ever want to have both co-exist in the code base.. but ok… let me just check this out a bit

20:30 seangrov`: Example constants_table.js output - it's output after cljs.core, before any user code https://gist.github.com/sgrove/d139e439394689febbcd

20:30 bbloom: does core use those values?

20:30 seangrov`: All the tests pass and String.prototype no longer has .call or .apply

20:31 Yeah

20:31 But it's all late-binding, so it works ouyt

20:31 bbloom: ok… good thing we made it so that core executes no code during bootstrap :-)

20:31 that was a tricky first step!

20:31 seangrov`: Exactly, was quite worried about that

20:31 bbloom: yeah, i think david & i got the last of that out of there a few months ago

20:32 seangrov`: Well, thank you, I had a difficult enough time as it was :)

20:32 Though this is definitely getting a lot easier

20:32 bbloom: do you have a unit test for comparing & doing map look up with dynamic keywords?

20:32 I dont see "(keyword " in this diff :-)

20:33 seangrov`: Hrm..

20:33 bbloom: also, is the plan to support other types of constants too?

20:33 seangrov`: bbloom: I was supposed to support other constants, but I'm unclear on what they would be

20:33 bbloom: like we wanted to get constant data structures too, which i think we annotated as :constant? or something like that

20:33 seangrov`: But they would fit in here pretty easily

20:33 bbloom: maybe you should break this patch up as follows:

20:34 step 1) constant table

20:34 step 2) reified keywords

20:34 [1 2 3] should be a constant

20:34 instead of inline construction of PersistentVector.fromArray[....

20:34 would be a HUGE perf win

20:34 seangrov`: Ah, interesting

20:34 Would be willing to tackle that later

20:34 bbloom: would also be a much smaller patch

20:35 so yeah, that's my feedback: 1) test the interaction between dynamic & static keywords. i suspect you have some major bugs there, just from my cursory glance at this

20:35 seangrov`: bbloom: So 1.) constants table would just be in the analyzer

20:36 bbloom: 2) don't bother with #1 or reified keywords until after you do constant tables for already reified types (like symbols & collection types)

20:36 seangrov`: bbloom: You mean (= (keyword "a") :a)?

20:36 bbloom: seangrov`: yeah

20:36 seangrov`: Seems to work

20:36 It's in the test suite

20:36 The specific change being here https://github.com/sgrove/clojurescript/compare/real_keywords#L3R2049

20:36 bbloom: what about identical?

20:36 right now, keywords are considered identical to each other

20:37 b/c they use js string compare

20:37 oooh you know what, you're also really lucky that we fixed PersistentArrayMap

20:37 b/c ObjMap required keywords to be identical? for perf

20:37 so it might not be an issue any more

20:38 but yeah, start w/ the constant table w/o reifying keywords

20:38 that a bigger perf win than reified keywords are a usability win :-)

20:39 & the patch should be a bit easier to review like that. it should be pretty easy for you to split out the keyword parts

20:39 gfredericks: TimMc: a generalization to what?

20:39 lazybot: java.lang.RuntimeException: Unable to resolve symbol: the in this context

20:39 bbloom: anyway, i gotta run.

20:39 seangrov`: cool stuff! thanks :-)

20:39 seangrov`: Thanks bbloom!

20:39 * seangrov` looks into identical...

20:41 seangrov`: Ok, now I see the need for keyword-identical?

20:45 gvickers: Hey guys, so I have a ref with a bunch of namespace names as symbols in it, each of them has function foo, is there any way to call foo on each of the namespaces?

20:46 gfredericks: yes.

20:46 (doseq [ns @my-ns's] ((resolve (symbol (name ns) "foo"))))

20:54 hugod: callen: fwiw, alembic already has lein running in a classloader via classlojure - it should be straightforward to add it there

20:55 rasmusto: gfredericks: that's cool. Is it common to have many namespaces that all have the same function like that?

20:57 gfredericks: rasmusto: I don't think so

20:57 gvickers: I have n number of plugins that will all have the same functions that can be called on them.

20:58 gfredericks: there's usually a better data-oriented way to do abstraction like that than using namespaces for it

21:03 rasmusto: gfredericks: I guess I have a weird case where I have a very similar function that needs to be called in my 'core' namespace, so now I have a list of each of them

21:10 justin_smith: we had something similar with a web framework - the lib needs to know which initializations need to be applied to its data, so giving it a bunch of namespaces, from which it would call "init" in each one, seemed to make sense

21:14 seangrov`: ,(let [m {"name" "test"}] ("name" m))

21:15 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn>

21:15 * seangrov` finds out he's been using a loophole in cljs to make that work

21:15 seangrov`: So, that may be a migration for people when moving to keywords

21:19 gfredericks: oh geez that works in clojurescript?

21:19 seangrov`: WOOOO

21:19 Rapportive + Zenbox work together now

21:20 ClojureScript is a much better citizen of the world now without the String.prototype modifications

21:20 gfredericks: Yeah

21:20 gfredericks: seangrov`: I think I patched underscore.js to be compatible with the String.prototype mugglings

21:20 seangrov`: But as a kind of accidental side-effect of Strings and keywords being conflated

21:21 gfredericks: Yeah, we don't have access to Rapportive's code, can't patch it at runtime, serving our own modified version would be a violation of ToS, and they won't change it for us

21:21 So only option is to get ClojureScript to behave properly

21:21 gfredericks: https://github.com/jashkenas/underscore/commit/2206092e25f66f3a0dbb05c24509a7831b1863fe

21:23 seangrov`: ah, from just method.call -> _.isFunction(method) ?

21:23 gfredericks: something like that, yeah

21:23 they seemed to like the idea for unrelated reasons

21:23 seangrov`: Wouldn't that still cause "test" to be recognized as a fn though?

21:23 gfredericks: the string "test"?

21:24 I think isFunction checks that the .prototype == Function

21:24 * gfredericks doesn't know anything about javascript

21:24 seangrov`: I see, ok

21:25 Phew, very happy that this change fixed the cause of the bug, would have been debilitating had it not

21:25 Should also fix cljs + dojo stuff, though I don't use any of those

21:32 dissipate: what's the best javascript framework to use with cljs?

21:33 gfredericks: to do what?

21:35 dissipate: gfredericks, build a single page app

21:35 devn: weirdest application ive ever used: Argeïphontes Lyre

21:36 wrong channel, sorry

21:38 pandeiro: dissipate: i was reading something recently about using angular

21:40 dissipate: pandeiro, angularjs with cljs??

21:40 lazybot: dissipate: Uh, no. Why would you even ask?

21:40 pandeiro: http://keminglabs.com/blog/

21:44 anyone gotten around to trying the new lighttable?

21:44 dissipate: pandeiro, that's nice, what about ext js?

21:45 pandeiro: dissipate: not familiar but i think people have used it

21:45 oakmac: I have a question about recursion: http://pastebin.com/jeC1qAiK

21:45 seems I can't call "new-position-id" at the end there

21:48 dissipate: pandeiro, not using EMACS? The treachery!

21:51 pandeiro: dissipate: no I do use emacs but I have been interested in lighttable as a more 'web-native' tool

22:17 muhoo: (inc lazybot)

22:17 lazybot: ⇒ 20

22:17 muhoo: (inc clojurebot)

22:17 lazybot: ⇒ 31

22:18 muhoo: (inc inc)

22:18 lazybot: ⇒ 3

22:31 dissipate: (inc def)

22:31 lazybot: ⇒ 1

22:31 dissipate: (inc def)

22:31 lazybot: ⇒ 2

22:58 TimMc: gfredericks: A generalization of "trampolining" with loop/recur and argument sets for the remainder of a computation.

22:59 gfredericks: Probably monads or somesuch. :-P

23:39 dnolen: seangrov`:

23:39 seangrov`: Totally

23:40 Always strive to leave 'em speechless

23:40 dnolen: seangrov`: glad to hear you fixed that abomination, if you have a link to a squashed diff I can comment on changes, and then you can attach patch to ticket.

23:41 seangrov`: dnolen: https://github.com/sgrove/clojurescript/compare/real_keywords

23:41 Started looking into bbloom's suggestions, but it seems like it's a bit bigger than just initially getting keywords

23:42 dnolen: seangrov`: yes if you can squash that then I can comment on the whole commit.

23:42 seangrov`: we can look into the bigger stuff later

23:42 bbloom: seangrov`: i was trying to suggest something *smaller* :-)

23:42 dnolen: seangrov`: keywords are critical.

23:43 bbloom: can you produce a constant table of symbol objects? sure, they are far less used than keywords, but it would be a much smaller patch

23:43 but i guess dnolen is the one to review & accept, so it's up to him

23:43 seangrov`: bbloom: But that doesn't help with the main problem I'm trying to solve

23:43 Happy to do it bit by bit though

23:44 dnolen: bbloom: I don't see how it would be smaller?

23:44 seangrov`: glad to see you removed all the gnarly keyword special casing from the string related code.

23:45 bbloom: dnolen: he's detecting & emitting a constant table and ALSO reifying keywords at the same time. he could detect & emit constants, THEN reify them in two patches

23:45 i like to have multi-commit patches in steps like that

23:45 makes it easier for me to understand

23:45 but you like squashed patches :-)

23:45 dnolen: bbloom: yes :)

23:45 bbloom: *shrug* you've got commit bit, not me

23:46 if i had to review the patch, i'd probably do so by rebasing it in to two parts, lol

23:46 i hate huge patches

23:46 dnolen: seangrov`: please squash those commits so I can comment on the whole thing.

23:46 seangrov`: How can I squash these commits so they can be commented on?

23:46 git merge --squash?

23:46 bbloom: seangrov`: no, you want rebase

23:46 git co my-branch

23:47 er checkout

23:47 git checkout my-branch

23:47 git rebase --squash `git merge-base my-branch master`

23:48 er nevermind

23:48 i always do interactive

23:48 apparently rebase has no --squash, only --interactive and --autosquash

23:48 seangrov`: Haha, just tried that, didn't quite work. I've avoided this for a long time

23:48 bbloom: so use merge, my bad :-P

23:48 tbaldridge: dnolen: just fixed a core.async bug that would cause errors when someone generated tons of inactive handlers (via alts!). I don't think it'll impact performance much, but the commit is here: https://github.com/clojure/core.async/commit/70f45e939c889858b9263e5a1b3c9dfbd311ecf9

23:48 bbloom: learning to use rebase, especially interactively, was LIFE CHANGING for me

23:49 now i use git to edit code almost as much as i use vim ;-)

23:49 dnolen: seangrov`: I just do it the poor mans way, new branch, rewind, recommit

23:49 xeqi: I usually use `git rebase -i master` and then mark them to be squashed

23:49 bbloom: xeqi: that's what i actually do, but -i requires you learn how to use that :-)

23:49 which i highly recommend

23:49 tbaldridge: dnolen: we have to run cleanup (we weren't before this patch). So I decided to add a counter and only run cleanup every 64 puts/takes.

23:49 bbloom: i have an alias for rebase -i w/ merge-base master

23:51 dnolen: tbaldridge: gotcha, did someone run into this in practice?

23:52 tbaldridge: dnolen: no, it was one of those moments when you wake up in the middle of the night and think "well crap, I just introduced that bug...".

23:52 dnolen: tbaldridge: hehe, gotcha

23:55 devn: Recommended reading on distributed systems? Fault-tolerant systems? Things of that nature?

23:55 tbaldridge: devn: anything by Joe Armstrong (if you haven't already)

23:56 devn: tbaldridge: one cannot hear those phrases and think about anything than erlang.

23:56 anything other than*

23:56 hiredman: I suggest the letrec email

23:56 devn: hiredman: link?

23:57 hiredman: http://erlang.org/pipermail/erlang-questions/2011-May/058768.html is pretty much my all time favorite email

23:57 devn: thanks hiredman

Logging service provided by n01se.net