#clojure log - Jul 08 2012

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

0:10 S11001001: ssutch: uh, those messages are because in one case you left off parens and the other you tried to call a disallowed function

0:10 ssutch: S11001001 yes i know

0:10 it looks like i should just use pattern matching for what i was trying to do

0:10 S11001001: if you like

0:11 multi-lambda only manages different arities, and the destructuring built-in to clojure isn't pattern matching, per se

0:11 ,(let [{:keys [x y z]} 42] (list x y z))

0:11 clojurebot: (nil nil nil)

0:12 S11001001: ,(let [[x y z] 42] (list x y z))

0:12 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Long>

0:12 S11001001: iow there is no report of whether a match "succeeded". A bad match can express itself in the form of nils in some places, or type-related exceptionsf

0:13 ssutch: i was trying to make a multi-lambda that would choose the right form based on keys passed in a map

0:13 https://github.com/clojure/core.match/ does mostly what i was trying to do

0:13 *does exactly what i was trying to do

0:14 S11001001: I have a lambda wrapper for core.match that mixes in arities: https://bazaar.launchpad.net/~scompall/+junk/clojure-stuff/view/head:/src/com/nocandysw/cloj_dummy/scala/tertiary.clj#L37

0:15 michaelr`: good morning!

0:15 S11001001: example use at https://bazaar.launchpad.net/~scompall/+junk/clojure-stuff/view/head:/src/com/nocandysw/cloj_dummy/scala/adt.clj#L80

0:17 ssutch: interesting

0:21 mindbender: S11001001: what's a lambda wrapper?

0:25 ssutch: mindbender wraps lambdas

0:29 S11001001: mindbender: lambda version of core.match/match, just a wrapper for it

0:56 evildaemon: Is there an error message translator?

1:01 tremolo: question about monads: the whole point is supposed to be function composition, right? how come all the clojure examples I see have long chains of "let" bindings and absolutely no visible composition?

1:01 this includes all the examples from algo.monads

1:02 i expect to see something like -> (f1 (f2 (f3 val))), but what I see instead is [a (f1) b (f2 a) c (f3 b)]

1:05 S11001001: tremolo: that's just sugar, rewritten to (m-bind (f1) (fn [a] (m-bind (f2 a) (fn [b] (m-bind (f3 b) (fn [c] ...))))))

1:08 tremolo: it's clearer in haskell and scala, which use <- instead of = to signify that it's not really let

1:08 tremolo: yea, I guess I just find it a bit weird syntactical choice

1:09 seems like something more like the thread macro would be clearer

1:09 S11001001: tremolo: for the identity monad, domonad is equivalent to let

1:09 tremolo: typically it isn't quite so common to line up pure values and actions like that

1:10 tremolo: I believe m-chain is provided for the cases where you do want that

1:10 tremolo: ah, alright. didn't know about m-chain

1:10 thanks

1:12 S11001001: tremolo: it's worth browsing all of monads.clj; it's not that long, and there's lots of useful stuff in there if you want to take serious advantage of the library

1:12 tremolo: yep, good idea

1:12 S11001001: knowledge of its idiosyncratic interface is also quite useful

1:12 with respect to the way with-monad and defmonadfn work, for example

1:29 wingy: the wrong fn is used here: http://clojuredocs.org/clojure_core/clojure.core/send-off

1:36 Tricks: What is the best way to replace two items in a vector that are next to each other with new values. Say I have [1,2,3,4,5] and I want to replace 3 and 4 with 5 and 2 and I know that 3 and 4 are at index 2 and 3 and Ialso know the values I want to replace them with.

1:37 amalloy: &(assoc [1 2 3 4 5] 2 'a 3 'b)

1:37 lazybot: ⇒ [1 2 a b 5]

1:37 Tricks: Thank you.

1:38 amalloy: only for an actual vector, though, not some lazy-seq that you pretended was a vector for simplicity

3:41 michaelr`: what

3:41 why no dissoc-in in core?

4:00 amalloy: michaelr`: my guess? (a) it's easy to build yourself with update-in, and (b) unlike assoc-in, there are corner cases where it's not entirely clear what the right output should be and any choice in core would surprise you eventually

4:01 eg: (dissoc-in {} [:a :b :c]). are you really happy with that returning {:a {:b {}}}? or {:a {:b nil}}?

4:04 michaelr`: hmm

4:08 ,(update-in {:a {:b {:c 1}}} [:a :b] (fn [m] (dissoc m :c)))

4:08 clojurebot: {:a {:b {}}}

4:08 michaelr`: like that?

4:08 amalloy: ^^

4:11 amalloy: more or less. it's certainly better to do (update-in m [:a :b] dissoc :c)

4:12 michaelr`: oh cool

4:12 :)

4:12 ,(update-in {:a {:b {:c 1}}} [:a :b] dissoc m :c)

4:12 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: m in this context, compiling:(NO_SOURCE_PATH:0)>

4:12 michaelr`: ,(update-in {:a {:b {:c 1}}} [:a :b] dissoc :c)

4:12 clojurebot: {:a {:b {}}}

5:34 wingy: from what i have understood we can use clj data structures instead of json/xml

5:35 does this mean that if a system is using clojure then it would be more beneficial for it if my restful API returned clj data instead of json?

5:35 _ulises: wingy: in principle I'd say yes; have you seen pinot? (related to the noir project)

5:36 wingy: reason I mention pinot is because it does exactly that to transfer data from noir apps to the cljs frontend

5:36 wingy: i c

5:37 but when it comes to restful HTTP API .. i have never seen someone returning clj data structures

5:37 but i guess i could make that as an alternative for systems in clj .. i think they would appreciate that rather than having to deal with JSON?

5:37 _ulises: wingy: returning clj structures implies (unless you're willing to jump through several hoops) that you'll be reading them using cljs/clj I'd say

5:37 wingy: also i think that would make a good promotion of clj. what do you think?

5:38 yeah .. for clients in clj

5:38 _ulises: wingy: it depends on what you're building; if it's a public API, then clj data structures would be a nice to have to clojure people, but if it was the standard you'd restrict yourself to that community

5:38 wingy: JSON is more "universal" in that respect

5:40 wingy: i would provide both JSON and clj data structures

5:41 _ulises: wingy: again, don't know what you're building; if you expect quite an interest from the clojure community on your service then providing clj structures sounds like a good idea

5:42 wingy: yeah you always wanna do something for the clj community .. i think this would promote clj really well as well

5:42 _ulises: wingy: then by all means go for it

5:43 wingy: i was actually watching http://www.infoq.com/presentations/One-Parenthesis-to-Rule-them-All where he mentions clj data structure is far more superior than json .. and that it could be used as a wire protocol between end points

5:44 _ulises: wingy: sure, clj structures may be richer than json, but perhaps they're not the right solution in some domains

5:46 wingy: right

6:13 ro_st: has anyone come up with an elegant way to share code between clojure and clojure script?

6:13 eg, 'model' code that doesn't depend on a particular execution environment such as the dom or access to a database

6:13 one approach i found is https://github.com/lynaghk/cljx

6:37 antihero: Is there a tutorial that takes me through building a simple application?

6:37 _ulises: antihero: what sort of application? I'm sure there are plenty tutorials to get you started writing clojure

6:37 antihero: Hmm, not sure what I want to use it for yet, I do web stuff at the moment

6:38 surprise me?

6:38 _ulises: antihero: it may be easiest to start with noir (a web framework for clojure)

6:38 antihero: ok

6:39 I suppose I can learn clojure by trying to write stuff with noir and looking up the reference

6:39 _ulises: antihero: however, if you know nothing about clojure, I'd start with something simpler

6:39 hyPiRion: If you use Leiningen and Noir, then it's very simple to start off.

6:39 _ulises: antihero: http://webnoir.org/

6:39 hyPiRion: Sorry, I mean easy.

6:39 _ulises: +1

6:39 antihero: I ghot Leiningen :)

6:39 so I could use the irepl

6:39 as that seems nice

6:40 is there a .tmTheme for the style on the noir website?

6:40 hyPiRion: .tmTheme?

6:41 antihero: like textmate/sublime text highlighting theme

6:43 Java pops out loads of stuff on startup, any ideas what "which: no rlwrap in (...)" is and how to avoid it? Also "Picked up _JAVA_OPTIONS: ..."

6:48 hyPiRion: antihero: I don't think so, but I'm not using sublime.

6:49 antihero: fair enough

6:53 My serve doesn'd seem to run :(

6:54 I do lein run and it says it's listening

6:54 but if I open the page, it just sits there loading

6:54 I'm using openjdk7

7:07 wmealing: antihero, obvious question.. but firewall ?

7:07 antihero, which ip are you connecting on ?

7:08 antihero: Ok, it seems to work now I'm using Oracle JDK/JRE

7:08 weird

7:08 wmealing: no idea, ok

7:08 antihero: all is local

7:11 hyPiRion: antihero: That's weird. I use open JDK and have no problems with it.

7:12 antihero: maybe I have some config issues

7:12 I get this error output

7:13 wmealing: openjdk here too

7:13 no problems, Fedora 16 and 17

7:13 antihero: I'd prefer to use openJDK

7:13 http://bpaste.net/show/wveuzkheqH2CJH3Mqwbw/

7:13 perhaps those errors could be causing?

7:14 wmealing: looks ok

7:14 rlwrap wont cause a listening problem

7:14 and the awt settings wont either

7:14 antihero: is there any way to get rid of those errors anyway? They are annoying as hell

7:17 * wmealing thinks

7:17 wmealing: distro ?

7:24 bosie: why does htis code result in a NullPointerException? https://gist.github.com/3070583

7:24 unnali: bosie: you've got one-too many levels of ()

7:24 #((println %))

7:24 should be

7:24 #(println %)

7:25 right now it's executing (println %), which should work, but it yields nil

7:25 i.e.

7:25 bosie: ah

7:25 right

7:25 unnali: ((println "blah")) --> (nil) --> NPE

7:25 bosie: working

7:25 i just overlooked it

7:25 new to the whole () game

7:26 unnali: :)!

7:26 bosie: ;)

7:26 unnali: ;D

7:39 b6n: Hi, does anybody have some resources about how to use google closures soy templates together with clojurescript (cljsbuild)?

7:54 penthief: Am being asked to accept an expired certificate on clojars.org at the moment. Just saying.

7:57 michaelr525: this whole certificate thing is ridiculous, anybody can buy a certificate. so the only thing it certificates is the money that has been paid for it :)

8:48 bosie: is there a way to actually get better error messages

8:51 hyPiRion: bosie: As of right now, nope.

8:51 weavejester: bosie: Tools like clj-stacktrace can help

8:58 gfredericks: michaelr525: that sounds simplistic

9:07 michaelr525: gfredericks: there is a bigger picture.. the certificate authorities make lot's of money.. hmm what else?

9:11 weavejester: Today I learned that the order of dependencies in Leiningen matters… :/

9:14 wingy: sometimes i just can't get the explanations people use to describe how clojure works .. they make things really hard to get :/

9:16 kmicu: wingy: can you give an example :)?

9:17 wingy: http://java.ociweb.com/mark/clojure/article.html

9:18 "The def macro binds a value to a symbol. It provides a mechanism to define metadata, :dynamic, which allows a thread-local value within the scope of a binding call. In other words, it allows re-definition of assigned value per execution thread and scope. If the Var is not re-assigned to a new value in a separate execution thread, the Var refers to the value of the root binding, if accessed from another

9:18 thread."

9:19 lucky me i read it in another book. but that is just one of many explanations not telling you much .. i can read it 10 times and still have a ?

9:24 i hope "clojure-tutorial-for-the-non-lisp-programmer" is better in explaining stuff .. so tired of reading materials that only make you frustrated

9:25 i realized not only does one have to choose a lang that makes sense .. one has to choose docs that make sense as well

9:27 yy: nice

9:29 kmicu: wingy: it is more a personal thing or matter of taste, for me clojure source code is the best docs ;)

9:29 wingy: kmicu: yeah .. source code is great

9:39 TimMc: kmicu: As long as you aren't talking about msot of the Java impl of Clojure, sure.

9:40 rhickey is apparently allergic to javadocs.

9:40 or comments in general, I guess

9:40 michaelr525: yeah, comments are evil man ;)

9:41 kmicu: TimMc: Not my level :]

9:41 TimMc: "not my level" == "I mean the .clj impl"?

9:43 kmicu: TimMc: yes, but also I am more of cljs than clj

9:43 TimMc: Ah, OK.

9:53 kmicu: TimMc: can you tell what you do that you need docs for clojure's *.java files? ;)

9:53 TimMc: kmicu: A lot of clojure/core.clj fns delegate their implementations to RT.java, etc.

9:56 kmicu: Say, for instance, you wish to see what 'seq will accept and what will cause it to throw an exception: https://github.com/clojure/clojure/blob/1.3.x/src/jvm/clojure/lang/RT.java#L462

10:42 michaelr525: inline-block or float?

10:44 bosie: https://gist.github.com/3071242

10:44 how would i do this with apply, rather than doseq

10:45 i tried it like this "#(apply #(do %) logger-fns)" but it says nested #() are not allowed

10:53 hyPiRion: bosie: Obviously, the % can be owned by either the inner or the outer anonymous fn.

10:55 wmealing: so if i wanted to profile some clojure code to find out where the cpu time is spent

10:55 what is the best way to do that right now ?

10:56 hyPiRion: bosie: A shorter version of your code would be this: https://www.refheap.com/paste/3514

10:56 wmealing: now i could use the whatever is new clojure.contrib.profile

10:56 but i'm wondering if there something more useful out there, right now

11:00 duck1123: there was a new logging library that has profiling. I've been meaning to try it

11:00 https://github.com/ptaoussanis/timbre

11:02 wmealing: i'll look into it

11:03 i'm doing some basic RMS calculations and the read from microphone loop chews quite a bit of CPU

11:03 duck1123: it was just announced the other day, and it looks intriguing

11:03 wmealing: i'm doing it wrong (obviously) now i need to find out where

11:03 looks clear

11:03 thanks for the link

11:04 duck1123: I've also been thinking about trying to make use of https://github.com/etsy/statsd from clojure

11:04 I like the idea of having control of my loggers at runtime

11:05 I'm hoping it'll be more or less a drop-in replacement (ie replace all my :require calls)

11:05 jg: hi all, so it seems the new lein uses [reply "0.1.0-beta8"] by default, the thing is - i cannot evaluate any expression with it! (return does not work!) what gives?

11:06 or: how can i change the default repl used by lein?

11:07 duck1123: you might be able to use lein run if the repl you want to use has a main

11:08 although it's odd that it doesn't work for you.

11:11 _wingy: i have read that clojure's tail call optimization is a hack using loop, recur. is there a plan to fix this?

11:12 duck1123: from what I heard, even if they could support it automatically, recur isn't going away

11:12 pandeiro: i want to be able to take a symbol representing a namespace and do something with all of its vars that have a certain metadata value - can anyone point me towards the functions i need?

11:12 duck1123: recur at least gives you the assurance that you are actually in the tail call

11:12 jg: duck1123: removed my .inputrc, repl started working again

11:12 pandeiro: _wingy: i don't understand that stuff but i remember reading it's due to a JVM limitation

11:12 duck1123: jg: cool.

11:13 jg: duck1123: it seems https://github.com/jline/jline2/issues/48 this was the problem

11:13 duck1123: IIRC java 7 has some support for TCO, but at this point, recur is a design desicion

11:16 Licenser: _wingy the reason for loop recur is not mainly javas limitations but to make sure that you KNOW when you get fast TCO and that you also notice when a change in your algorithm breaks it

11:16 and not things get magically 10x slower or something

11:16 _wingy the reason for loop recur is not mainly javas limitations but to make sure that you KNOW when you get fast TCO and that you also notice when a change in your algorithm breaks it (re)

11:16 _wingy: pandeiro: im pretty new to that stuff as well. i think that it is referring to the memory leak when each loop creates a value that is saved in memory

11:17 duck1123: in clojure there's a memory leak with loop?

11:18 tmciver: _wingy: no memory 'leak'. Not using TCO consumes stack space.

11:19 duck1123: thankfully, most of the time you need loop/recur, you don't really need loop recur as there is a better higher-level abstraction

11:19 pandeiro: so am i correct in understanding only macros can take unquoted namespaces and work with them without evaluating?

11:19 tmciver: _wingy: TCO is a technique that allows recursion without consuming the stack.

11:20 duck1123: well, the macro sees that unquoted namespace as just symbols to manipulate, that's how it gets around it

11:21 _wingy: tmciver: why not let us do recursion without loop/recur?

11:21 tmciver: _wingy: you can

11:22 AimHere: You can, but it's better to use loop/recur if you can

11:22 tmciver: _wingy: but it consumes the stack

11:22 Licenser: _wingy you can also recur to a function head

11:22 bosie: hyPiRion: not "obviously" as that is an implementation question

11:23 duck1123: with recur, you're explicit about your intent. A small price to pay for how infrequent it comes up

11:24 _wingy: is there a way to do normal recursion without consuming stack space? and is someone working on it?

11:24 just curious

11:24 bosie: hyPiRion: your code doesn't seem to work for me

11:25 hyPiRion: cos i forgot the %

11:25 nvm

11:26 mstrlu: _wingy: laziness ;)

11:30 duck1123: _wingy: https://groups.google.com/d/msg/clojure/4bSdsbperNE/tXdcmbiv4g0J

11:35 _wingy: duck1123: good read

11:45 pandeiro: still trying to figure out how to filter a seq of vars from a ns based on metadata values... any help? when i (map meta (vals (ns-publics 'the.namespace))) i get :ns :name :line and :file keys but not the metadata i attached

11:46 the-kenny: pandeiro: How do you attach the metadata?

11:46 pandeiro: i'm just doing it at the repl when i def the vars

11:47 (def a1 ^{:a true} [1 2 3])

11:47 the-kenny: This attaches the metadata to [1 2 3]

11:48 You want (def ^{:a true} a1 [1 2 3] ) :)

11:48 duck1123: try (def ^{:a true} a1 [1 2 3])

11:48 also just ^:a is a shortcut for that

11:50 pandeiro: ok when i was doing that i wasn't getting the metadata with (meta a1)

11:54 why does (def ^{:a true} a1 [1 2 3]) and then (meta a1) return nil?

11:54 ah i need var there, got it

11:55 amazing i've used clojure many months and still don't get namespaces and vars :-/

11:56 duck1123: It's a great design when you think about it and compare it to some other languages

12:09 solussd_: question: I have a ruby on rails rest api that needs to communicate with a clojure process on the same server. I'm currently using http webservice calls to communicate (one way) from rails to clojure (the rails process knows about the clojure webservices). Any suggestions for a faster serverside IPC approach between ruby/rails and clojure?

12:15 jeremyheiler: solussd_: you could use some sort of message queue like redis or something.

12:16 solussd_: jeremyheiler: possibly. I'll investigate

12:16 thank

12:16 bosie: https://gist.github.com/3071575 ok, so why doesn't println print 2 lines?

12:16 solussd_: *s

12:16 bosie: and how would i go about debugging that?

12:17 the-kenny: bosie: (println "foo" "bar") doesn't print two lines either, right?

12:17 solussd_: bosie: you're last expression looks like this : (println firstitem seconditem), so it'll print them on the same line followed by a newline

12:18 bosie: the-kenny: true, it doesn't

12:18 the-kenny: bosie: (apply println ["foo" "bar"]) is the same as (println "foo" "bar")

12:18 bosie: hm

12:18 the-kenny: because?

12:18 solussd_: you want (doseq [item (take 2 seq)] (println item))

12:18 the-kenny: Because apply works like this

12:18 :)

12:19 bosie: the-kenny: but doesn't apply take the sequence and apply each item in the sequence to the function (first param)?

12:19 the-kenny: No!

12:19 That's map.

12:19 solussd_: apply takes a sequence and splices it in as more args to the function

12:19 the-kenny: (map inc [1 2 3]) -> [2 3 4]

12:19 bosie: solussd_: right but doseq is for side effects only methods. so if i don't do println but something else i would have to change my doseq, no?

12:19 solussd_: e.g. (apply + 1 2 [3 4 5]) == (+ 1 2 3 4 5)

12:20 bosie: printing is a side-effect

12:20 yes

12:20 just do the other thing right after the doseq. :)

12:21 the-kenny: or use for

12:22 ,(for [i [1 2 3]] (+ i 42))

12:22 clojurebot: (43 44 45)

12:22 the-kenny: (map (partial + 42) [1 2 3])

12:22 ,(map (partial + 42) [1 2 3])

12:22 clojurebot: (43 44 45)

12:22 solussd_: or just do this: (apply println (clojure.string/join "\n" (take 2 seq)))

12:22 bosie: solussd_: wait what? why would i join

12:23 the-kenny: reading up on for

12:23 the-kenny: solussd_: He's already reading lines from a file :D

12:23 solussd_: ,(apply println (clojure.string/join "\n" ["first thing" "second thing"]))

12:23 clojurebot: f i r s t t h i n g

12:23 s e c o n d t h i n g

12:23 the-kenny: bosie: Be careful! for is lazy, doseq isn't. So doseq is the choice for side effects

12:24 Frozenlo`: Who is the owner of clojars? The certificate expired...

12:24 bosie: the-kenny: would doseq throw an exception if my method had no side effects? or is that "just" a common, unwritten rule amongst clojure programmers?

12:25 the-kenny: doseq is rather useless without side effects because it returns nil :)

12:25 bosie: k

12:25 solussd_: bosie: doseq just makes sure your seq is actually traversed

12:25 bosie: good point

12:25 the-kenny: ,(doseq [i (range 1000)] i)

12:25 clojurebot: nil

12:26 bosie: ok, so line-seq returns a lazy sequence and for requires a vector for its binding

12:28 the-kenny: for's syntax is the same as for doseq

12:29 for is really useful for transforming seqs.

12:29 But prefer map when it's more intuitive. (map count (line-seq ...)) is easier to read than (for [line (line-seq ...)] (count line))

12:30 (both return a new seq with the length of each line)

12:30 bosie: woho

12:30 got it together with doeq

12:31 the-kenny: alright

12:31 a question about the implementation of the lazy seq eval

12:31 wouldn't (doseq [item (take 2 seq)] (println item)) this read the entire file?

12:31 and store the 2 lines in item?

12:31 since i force it to with "take"?

12:32 duck1123: you take it, then force it

12:32 bosie: ok

12:32 right. take returns a lazy seq again

12:32 duck1123: (take 2 (doall (for [item seq] (println item)))), however

12:34 bosie: duck1123: hm. reading doall sounds very similar to dosync. forcing the lazy seq to be evaluated fully

12:34 except doseq i mean

12:34 doseq i mean

12:35 making sense of the documentation requires a PHD in lisp i guess ;)

12:35 duck1123: yeah I use doall and map quite frequently when I want to force them all but I want the return (I tend not to use for often)

12:36 bosie: how does map force anything? according to the api it returns a lazy sequence itself?

12:36 the-kenny: bosie: It does.

12:36 doall forces the realization of the lazy seq

12:36 duck1123: doall forces it

12:36 bosie: k

12:36 can't remember the last time it took me this long to write a simple iteration over a list ;)

12:38 the-kenny: You won't regret it. Clojure provides really powerful tools for that :)

12:38 bosie: the-kenny: i looked into scala.

12:38 the-kenny: since i am jvm bound ;)

12:38 the-kenny: for is in reality more powerful than that as it provides full list comprehension

12:39 (Why do I keep typing 'lisp comprehension'?)

12:39 bosie: the-kenny: probably your 28 years of lisp programming? ;)

12:39 the-kenny: I'm not even that old :p

12:39 bosie: yet

12:40 ;)

12:40 Clojure Programming (Emerick/Carper/Grand) is rather excellent, isn't it?

12:42 the-kenny: I haven't had a deep look at it, but I heard it's awesome

12:42 wkelly: I quite like it!

12:42 bosie: wkelly: you far you in?

12:43 wkelly: bosie: I have browsed its entirety, and I have been actually reading chapters here and there as they become pertinent to my interests

12:43 it is hard to say :/

12:43 I've probably read about half of it in detail

12:43 bosie: alrighty

12:43 read about 80 pages and quite like it

12:44 just had to ask if there was something better out there

12:44 wkelly: I have most of the rest. It seems to be the best for people without a big lisp background

12:45 I like joy of clojure as well, but I had to back off and find something more down to earth first

12:45 bosie: down to earth? ;)

12:45 wkelly: haha

12:45 joy of clojure started off a bit over my head!

12:45 :P

12:46 bosie: wkelly: good. then i made the right choice cos i never did FP/Lisp before (not counting ruby's FP stuff)

12:48 duck1123: ruby is a good prep for clojure I think

12:48 mybuddymichael: duck1123: I agree.

12:48 Ruby has a lot of "Lisp-y" features.

12:48 bosie: duck1123: how so? #((apply juxt functions) ) blew my mind today. no idea how you would do that in rugy

12:49 ruby

12:49 duck1123: I'm just saying on the types of language features, my experience with ruby helped in my learning of clojure

12:49 bosie: k

12:50 duck1123: my problem was I wanted to do coll.map { :key } in ruby, and it didn't work

12:51 you can do juxt in ruby... I'm too out of practice now.

12:51 my day job lately has been in perl and it's been making me cry

12:52 bosie: duck1123: where are you (city/country) if you don't mind me asking?

12:52 duck1123: I'm just outside Detroit, MI

12:53 bosie: k

12:54 duck1123: grr.. clj-webdriver and htmlunit are acting up for me today.

12:54 bosie: duck1123: i guess one can't switch to a clojure job in detroit? ;)

12:55 duck1123: Well, this was supposed to be a java job, but it's a java/perl shop and my project I was hired for was put on hold

12:55 so I've been working in perl

12:55 bosie: i hate that

12:56 duck1123: I got to use a bit of clojure when I was trying to test out external api's (use what I know well)

12:57 My last job I was starting the process of converting my large ruby application over to clojure, but many of the features never went live

12:58 bosie: duck1123: interesting, why would you switch to clojure?

12:59 duck1123: We were doing heavy data processing, and had limitations with concurrency

12:59 plus I really wanted to use clojure :)

12:59 bosie: limitations… that was very friendly put ;)

13:00 duck1123: So I built a big admin interface to the ruby part, but I built it using my framework, so it got some nice features as part of it.

13:02 I just yanked out the worker admin interface the other day and dropped it into my personal project. I need to figure out how to make it a component that can be placed into any app

13:02 bosie: and then you sell your personal project?

13:02 duck1123: my personal project is open source

13:03 bosie: can you just open source work stuff like that?

13:03 duck1123: I got assurances from my boss

13:03 most of the stuff is too specific that it's not usable

13:04 but he was aware that I was contributing to the base libraries

13:04 bosie: link?

13:04 clojurebot: your link is dead

13:05 duck1123: I'm building a microblogging application. I'm running a copy at renfer.name

13:05 yonatane: reading some github history is almost like porn

13:05 _wingy: probably the best beginner's guide: http://moxleystratton.com/clojure/clojure-tutorial-for-the-non-lisp-programmer#sequences

13:05 yonatane: the first commit, the evolution

13:06 _wingy: i finally get what a seq(uence) is

13:07 bosie: _wingy: saved

13:07 _wingy: bosie: :)

13:09 bosie: thanks for all your help guys

13:09 gotta bounce. cu

13:09 zdennis: I've just installed clojure 1.4 and leiningen recently, I'm trying to figure out how to get access to clojure.math.combinatorics but I can't seem to figure out how

13:10 do I need to download off github and build myself?

13:10 or is there a dependency I can add to my lein projects.yml?

13:11 yonatane: don't you have a project.clj file?

13:11 zdennis: er.. oops

13:11 yeah i have that

13:11 project.clj (not projects.yml,… typo theree)

13:11 xeqi: zdennis: [org.clojure/math.combinatorics "0.0.3"]

13:12 zdennis: awesome, thank you @xeqi

13:14 xeqi: zdennis: you can find most org.clojure stuff by searching central

13:14 http://search.maven.org/#search|ga|1|math.combinatorics

13:14 zdennis: sweet i was just trying google how to find clojure packages

13:14 xeqi: zdennis: alot of non-clojure core projects end up in clojars.org

13:15 * non-(clojure core)

13:15 so you can search there as well

13:17 zdennis: ty

13:20 yonatane: what does "first cut implementation" means?

13:21 zdennis: I am making a combination of all possible points in two vectors (i.e.: [-1 0 1] and [-1 0 1]). I have a version that uses two functions to do this.

13:21 https://gist.github.com/3071882

13:21 I have a inkling there is a better way to approach this in clojure

13:21 any one have a moment to review my code and point me in a direction?

13:23 I was hoping that clojure.math.combinatorics/combinations would be something of interest but I don't think it will help me out

13:23 xeqi: &(for [x [-1 0 1] y [-1 0 1]] [x y])

13:23 lazybot: ⇒ ([-1 -1] [-1 0] [-1 1] [0 -1] [0 0] [0 1] [1 -1] [1 0] [1 1])

13:23 amalloy: also i think combinatorics contains cartesian-product

13:25 zdennis: oh dang

13:25 @xeqi that's pretty awesome

13:26 &(clojure.math.combinatorics/cartesian-product [-1 0 1] [-1 0 1])

13:26 lazybot: java.lang.ClassNotFoundException: clojure.math.combinatorics

13:26 zdennis: shucks… well in repl that seems to also work

13:28 another question… I have a namespace called drunken-cockroach.point. Inside of that namespace I have a min and max function (defined with defn)

13:29 whenever I load that code I always get: WARNING: min already refers to: #'clojure.core/min in namespace: point, being replaced by: #'point/min

13:29 #'point/min

13:29 shouldn't it not be conflicting since it's in its own namespace?

13:29 is that warning telling me i am overriding globally available functions?

13:31 metellus: if you load it with use it will put the definitions into your current namespace

13:31 with require it will not

13:33 zdennis: ok

13:34 thank you for your help @metellus @amalloy @xeqi I am slowly but surely triangulating knowledge around using clojure :)

13:48 mcohen: anyone know what the status of cake is these days?

13:48 looks like it isn't actively developed anymore

13:49 nsxt_: didn't cake join forces with lein?

13:50 https://groups.google.com/group/leiningen/browse_thread/thread/5a79d02198a91b91

13:51 mcohen: ahh, i see. thank you

14:52 penthief: Anyone know why I might be getting "No 'xpc' param provided to child iframe" when doing "user> (cljs.repl/repl (cljs.repl.browser/repl-env))" ?

15:03 Frozenlock: Is there a command to force leningen to re-download libraries?

15:04 hyPiRion: lein clean and then lein deps

15:04 Frozenlock: Thanks!

15:04 hyPiRion: My pleasure :)

15:06 Frozenlock: Hmm didn't work... I think lein store the libraries in another folder and simply copy them back :(

15:07 qubit[01]: so the @ when used with futures means 'wait on this future' ?

15:08 "Or, as usual, you can use the reader macro version" , what is 'a reader macro', and what are some other reader macro examples ?

15:10 chmllr: Frozenlock: you want to delete the maven cache, see the ~/.m2/ folder

15:11 amalloy: qubit[01]: 'x is a reader macro that's the same as (quote x)

15:11 @x is (deref x)

15:11 #(inc %) is (fn [x] (inc x)), and so on. those are all reader macros

15:11 qubit[01]: ahh, so its just a macro that manipulates what the ast ?

15:11 not manipulates

15:12 amalloy: well, it's a reader macro - it gets applied before other macros; at read time, not compile time

15:12 qubit[01]: ahh gotcha

15:18 Frozenlock: chmllr: That worked! Thanks!

15:29 bosie: has anyone remapped his/her keyboard specifically for clojure and if so, what?

15:44 qubit[01]: bosie: cool idea

15:44 bosie: qubit[01]: just figured that () should be homerow ;)

15:44 qubit[01]: id like to not have to push shift everytime I want a paren, think I'll do that now

15:44 bosie: qubit[01]: or are you mocking me?

15:44 qubit[01]: nope :)

15:45 maybe I sacrifice my left shift, have shift (, and caps lock )

15:46 hmm thats no good

15:46 bosie: qubit[01]: i was thinking along the same lines

15:46 caps for (

15:46 ; for )

15:46 qubit[01]: think I'll try it

15:47 bosie: but i have no idea. i never remapped for a language, but since i am using vim i have been anal about homerow and remap almost every app ;)

15:56 nickaugust: I have an embedded h2 database in my application can I enable the built in web-console? anyone have experience doing this?

16:12 qubit[01]: bosie: ok I got it setup with xbindkeys

16:12 bosie: qubit[01]: ok

16:14 qubit[01]: here is my setup incase you wanted it https://gist.github.com/3072641

16:16 bosie: i am on osx

16:16 but i will set it up tomorrow

16:18 qubit[01]: ahh , coolio

16:19 bosie: is it good?

16:20 pandeiro: any suggestions on how to conditionally construct hashmaps based on non-nil values?

16:21 hmm, maybe just i'll just make the hashmap first then filter out the nils

16:22 qubit[01]: bosie: still getting used to it, hard not to go right to where it usually is, I ended up using Caps_Lock as (, and shift, caps as )

16:44 how would I find where clj-record is with lein ?

16:44 do know what I need to add as a dependency

16:44 duck1123: go to clojars and search there

16:45 qubit[01]: kk

16:45 duck1123: https://clojars.org/clj-record

17:03 wingy: i dont get this one .. so the rails guys gladly invited rich to enlighten them about how inferior ruby/rails/oop is? http://www.youtube.com/watch?v=rI8tNMsozo0&feature=related

17:05 gfredericks: wingy: yeah I had a hard time with the idea that they didn't all fit my stereotype either

17:08 wingy: gfredericks: irony?

17:10 jsl_: Speaking of Ruby, is there a Clojure REPL equivalent of '_' in ruby IRB to refer to the value the previous statement?

17:10 dnolen: jsl_: *1 *2 *3

17:11 jsl_: dnolen: thank you very much!

17:15 qubit[01]: https://gist.github.com/3072831 , what does -> do in this context ?

17:18 tmciver: qubit[01]: it's a threading macro: http://clojuredocs.org/clojure_core/clojure.core/-%3E

17:19 qubit[01]: cool!

17:20 tmciver: qubit[01]: Yes, it is!

17:20 duck1123: -> allows you to rewrite (a (b (c (d e)))) as (-> e d c b a)

17:33 gfredericks: ,(macroexpand-all '(-> e d c b a))

17:33 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: macroexpand-all in this context, compiling:(NO_SOURCE_PATH:0)>

17:33 gfredericks: ,(clojure.walk/macroexpand-all '(-> e d c b a))

17:33 clojurebot: #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.walk>

17:33 gfredericks: &(clojure.walk/macroexpand-all '(-> e d c b a))

17:33 lazybot: ⇒ (a (b (c (d e))))

17:34 duck1123: &*clojure-version*

17:34 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

17:35 duck1123: did the expansion change between 1.3 and 1.4?

17:50 TimMc: qubit[01]: I prefer to call it a "stitching" macro to avoid concurrency connotations.

17:51 duck1123: No, why?

17:53 ToxicFrog: TimMc: I just call it a pipe.

17:59 Raynes: I call it ->

17:59 pandeiro: hyphen-greater-than?

18:00 Raynes: Right arrow.

18:00 I call it theyshouldhavegivenitarealnameinsteadofastupidsymbolthateveryonecomesupwithadifferentnamefor

18:11 TimMc: Raynes: You can't spell that without "threadingmacro".

18:13 &(map key (remove (comp pos? val) (merge-with - (frequencies "theyshouldhavegivenitarealnameinsteadofastupidsymbolthateveryonecomesupwithadifferentnamefor") (frequencies "threadingmacro"))))

18:13 lazybot: ⇒ (\c \g)

18:13 TimMc: Oops, I guess you don't need *all* of those letters.

18:13 arohner: I alwasy thought the official name is "thread-first" and "thread-last" for ->>

18:14 TimMc: Maybe I should write >-, which stitches into the call position instead of the first-arg position.

18:14 I am sure that would be super-useful.

18:17 amalloy: qubit[01]: i just swapped all the numbers and symbols so that 9 is shift-(

18:17 hyPiRion: TimMc: May be useful for nested structures.

18:17 Raynes: amalloy: You're broken.

18:17 wmealing: on another note, a friend calls it ker chunk.

18:17 and the reverse chunk-ker

18:21 TimMc: amalloy: I'd do the same if I wasn't scared of X key mapping.

18:21 *weren't

18:22 amalloy: TimMc: you want my .xmodmap?

18:22 * TimMc shuns

18:22 TimMc: I think Ubuntu would halt and catch fire.

18:22 amalloy: that's a pretty crippling phobia

18:23 TimMc: Ubuntu is pretty crippling.

18:23 I feel like I'm damned if I do muck with settings and damned if I don't.

18:23 wkelly: stop using ubuntu! :P

18:24 Raynes: I think you'll be okay without numbers switched with symbols, TimMc .

18:24 yonatane: In clojure's source code, what is RestFn for?

18:24 TimMc: wkelly: Planning on it.

18:42 amalloy: &(ancestors (class (fn [])))

18:42 lazybot: ⇒ #{clojure.lang.IObj java.lang.Runnable clojure.lang.IFn java.lang.Object java.io.Serializable clojure.lang.AFunction java.util.concurrent.Callable clojure.lang.IMeta clojure.lang.Fn java.util.Comparator clojure.lang.AFn}

18:42 amalloy: &(ancestors (class (fn [& args])))

18:42 lazybot: ⇒ #{clojure.lang.IObj clojure.lang.RestFn java.lang.Runnable clojure.lang.IFn java.lang.Object java.io.Serializable clojure.lang.AFunction java.util.concurrent.Callable clojure.lang.IMeta clojure.lang.Fn java.util.Comparator clojure.lang.AFn}

18:43 yonatane: &(ancestors (class (fn [x])))

18:43 lazybot: ⇒ #{clojure.lang.IObj java.lang.Runnable clojure.lang.IFn java.lang.Object java.io.Serializable clojure.lang.AFunction java.util.concurrent.Callable clojure.lang.IMeta clojure.lang.Fn java.util.Comparator clojure.lang.AFn}

18:43 yonatane: &(ancestors (class (fn [x & args])))

18:43 lazybot: ⇒ #{clojure.lang.IObj clojure.lang.RestFn java.lang.Runnable clojure.lang.IFn java.lang.Object java.io.Serializable clojure.lang.AFunction java.util.concurrent.Callable clojure.lang.IMeta clojure.lang.Fn java.util.Comparator clojure.lang.AFn}

19:12 yonatane: What is RT.setValues for? I don't see any usages.

19:20 timsgardner: hey, I'm a beginner at elisp, and was wondering if anyone has a .init snippet to disable slime-mode for .cljs files? thanks

19:26 qubit[01]: amalloy: oh nice, can I have your modmap ?

19:28 amalloy: https://gist.github.com/ccc1d89be6893ca6ef3f

19:31 qubit[01]: sweet trying it out

19:36 yonatane: Do you think partial could be enhanced to do this: (partial f _ _ arg _ arg2) ?

19:37 #(f % %2 arg %3 arg2)

19:38 amalloy: you just did it, congratulations!

19:38 yonatane: yeah, i wanted to compare

19:40 wait, that's wrong

19:41 #(apply f (conj [% %2 arg %3 arg2] %&))

19:41 something like that

19:44 So yeah, the enhancement is useful i think

19:45 Jayunit100: I wonder if there is a good way that clojure can improve its stack traces so that they are shorter and more concise without hiding anything.

19:47 nicholasf: anyone know a redis client that can publish to a pub-sub channel?

19:48 nm found one. Couldnt on Friday

21:32 locojay1: hi is there a way to rename a project using leiningen. rename project.clj , namespaces... could do so bash sed script but if it already exists?

22:54 isaacggg: I am trying to call a vector of functions that each start an oscillator from the overtone framework when called, like so `(doall (map #(%) [(create-inst 400) (create-inst 50)]))`. This code returns each instrument in a list but I can only hear one- the last in the vector. Any clues as to why I don't hear each instrument?

23:13 amalloy: isaacggg: probably need to ask overtone folks about that. certainly all the functions are being called, but perhaps calling an overtone instrument stops the others, and you have to do something else to combine them

23:15 brainproxy: what are the correspondences between graph databases like OrientDB and Neo4j and Datomic?

23:16 ro_st: how many datomic peers do i need for a single-server setup? app+database on the same box

23:16 1 or 2?

23:18 isaacggg: amalloy: thanks! I'll check with that crew

23:18 technomancy: isn't there an IRC channel for datomic?

23:19 ro_st: there is. i've asked in there too :-)

23:19 brainproxy: technomancy: oh, didn't realize that

23:31 madsy: Hm.. in clojurescript it seems that converting from vectors to Float32Array doesn't work as intended.

23:31 But array to Float32Array is fine.

23:31 Am I missing something, or do I really need the extra step?

23:33 Like: (let [foo [1 2 3]] (. someMethod someObject (new js/Float32Array (array foo))))

23:34 Ok, I guess "array" is the only way to map between ClojureScript containers and js arrays. And Float32Array in js is compatible with normal js arrays

23:37 ro_st: probably been reported already. clojars.org ssl is broken

23:38 ToxicFrog: Say I have a function that returns either a string or a vector of strings. I want to call another function on its result, unpacking the vector if there is one

23:39 ro_st: (if (seq? arg) (map fn arg) (fn arg))

23:39 ToxicFrog: Is there a better way to do this than something like (let [result (g)] (if (string? result) (f result) (apply f result)))?

23:39 ro_st: I want apply, not map, but thanks

23:39 ro_st: i don't think so

23:40 unless f in this context knows how to deal with both internally, which probably means the same code :-)

23:40 ToxicFrog: Ok, thanks

23:41 madsy: ToxicFrog: What is f? Your own function or an existing one?

23:42 ToxicFrog: f is provided by the caller of this library, so I have no guarantee it handles both

23:42 madsy: aha

23:42 ToxicFrog: So I'd rather have a consistent callconv (either it's always passed a seq, possibly of one element, or it's always passed multiple arguments)

23:42 madsy: Well, you could make that a part of the usage policy

23:42 f must be a function with such-and-such overloaded entrypoints

23:42 ToxicFrog: Yeah, but the code has to be somewhere, might as well put it in my library and make life easier for the users

23:43 madsy: sure

23:43 ToxicFrog: (the actual output is from re-find, which returns either a string if there were no captures, or a vector of strings if there were; this kind of annoys me)

23:44 * ToxicFrog pokes the IntelliJ Clojure plugin with a stick, since its syntax hilighting appears to have gone insane

23:44 madsy: :)

23:45 * madsy hugs his emacs

23:45 ro_st: +1

23:45 emacs plays hard to get but it's so worth it

23:46 technomancy: ahem; the preferred terminology is "inc", dude

23:46 ro_st: -grin-

23:46 or is that (grin)?

23:46 ToxicFrog: My experience with emacs has been that I would probably have loved it ten years ago when I had enough free time that I didn't mind spending ages rummaging around in the guts to get things working

23:46 But these days, not so much

23:46 technomancy: preferred nomenclature, rather

23:47 ro_st: ToxicFrog: i swore non-stop for a week getting used to it.

23:47 technomancy: my lebowski-quoting is hindered by the fact that clojurebot doesn't respond to the apropos-dude command

23:47 madsy: Hm, so I got webGL working with ClojureScript.

23:47 ToxicFrog: ro_st: after a month of fiddling I had it about where JEdit was with twenty minutes of configuration.

23:47 After two months it was better.

23:48 After two and a half months it broke entirely.

23:48 ro_st: did you keep your .emacs.d in git?

23:48 ToxicFrog: Yes, but at that point I was just sick of the entire thing

23:48 It's a great editor if you're willing to write your own edit

23:48 *editor

23:48 I'm not

23:48 ro_st: i guess it depends what you want

23:49 madsy: Think I'm going to abstract away the differences between js/WebGL and java/OpenGL

23:49 ro_st: i grabbed overtone/emacs-live, added magit, changed font and colours, and added stuff like linum and maxframe

23:49 madsy: So I can develop with my proper REPL instead of doing ass debug printing in the js console

23:49 ibdknox: technomancy: quick question for you. I have my own version of clojure for this lein plugin and I need it to supplant the other versions of clojure that might be in someone's project

23:49 ro_st: madsy: do you have a technique for sharing code between clj and cljs?

23:50 ibdknox: technomancy: I do this locally by just building my own clojure and keeping it in the same group. But I can't do that if I want to give out my plugin

23:50 ro_st: madsy: i'm about to embark on a cljs project but i'd -really- like to do all the model stuff in clj so i can use repl+midje-mode

23:51 madsy: ro_st: Except for the fact that cljs code is a subset of clojure code, no.

23:52 technomancy: ibdknox: yeah, in that case you need a separate group-id plus a top-level exclusion of the real org.clojure/clojure

23:52 ibdknox: I didn't know there were top-level exclusions

23:52 madsy: ro_st: You could keep yourself to the subset of functionality that exist in both clojure and cljs, and then have the platform-specific code hidden in a library/namespace

23:52 technomancy: it's just a hack; it's implemented by adding exclusions into each dependency before it reaches aether. but it gets the job done.

23:52 ibdknox: technomancy: hah, learn something new every day :) Thanks

23:53 technomancy: sure

23:53 I've noodled a bit on the idea of mapping coordinates to source control trees to be able to track forks and non-linear version progression, but that's just been brainstorming so far.

23:53 ro_st: line dropped, madsy, did you say anything after 'subset of clojure' ?

23:54 emezeske: technomancy: like some kind of version vector?

23:54 * emezeske is not sure what to picture in his head.

23:54 madsy: ro_st: Yes. I said you could keep yourself to the subset of functionality that exist in both clojure and cljs, and then have the platform-specific code stashed in an external library.

23:55 technomancy: emezeske: no, some sort of separate data store that could map coordinates to repo/sha pairs and could compare repo/sha pairs

23:55 but I don't think it would be that useful

23:55 * emezeske noodles on this.

23:55 ro_st: madsy: one approach i found was github.com/lynaghk/cljx

23:55 technomancy: probably not enough to justify the huge implementation effort anyway

23:56 ro_st: i'm talking about some automated way to have the same code available to both the server and the client via a simple :require statement

23:57 madsy: ro_st: Looks useful. Though I wouldn't like to mix cljs and clj code in the same file

23:58 I have still nightmares of C++ #ifdef's

23:58 :)

23:59 ro_st: i guess i can just copy/paste code from clj to cljs, but this is lisp, damnit! there must be a way

23:59 lisp is supposed to be the One -grin-

Logging service provided by n01se.net