#clojure log - Oct 13 2010

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

0:00 amalloy: hm. but just turning it into args# doesn't work because the scoping is different

0:00 * kmc just recently ran into a scoping issue with auto-gensym

0:01 kmc: and i solved it by doing an explicit gensym and splicing that

0:01 amalloy: yeah, you did. what was my clever solution? i said something neat, didn't i?

0:01 kmc: yeah, you moved the quotes and splices around

0:01 you had something like ~x#

0:02 but it didn't work in my situation

0:02 amalloy: damn. ~x# isn't working for me now, either

0:02 time to go digging through the logs on my office computer, i guess

0:02 kmc: ,`(x# ~@(`(x# ~x#)))

0:02 clojurebot: java.lang.Exception: Unable to resolve symbol: x# in this context

0:03 kmc: ,`(x# ~@(`(x# y#)))

0:03 clojurebot: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn

0:04 amalloy: ah. the trick is you have to be still inside the outer scope; you can be in the middle of unquoting it

0:04 clojurebot: scope is at http://paste.lisp.org/display/73838

0:05 amalloy: argh. i want to tell him to shut up when he does that, but (i think?) that makes him stop responding to genuine ,(requests)

0:09 kmc: what sets him off?

0:09 also clojurebot is male?

0:09 amalloy: well, hiredman made him. if you want her to be female, hiredman, just say the word

0:10 kmc: i'm just curious because lambdabot is canonically female

0:10 amalloy: as for setting him off: god only knows. he has a set of words he knows, and sometimes he notices something you say and thinks it's relevant. sometimes he's right, sometimes he's not

0:10 well, i haven't hung around in #lisp very much. maybe the lisp->clojure folks in here are secretly laughing at me all the time, i dunno

0:15 notsonerdysunny: good morning Fellow clojurers! :)

0:16 ohpauleez: hey

0:16 !

0:17 Are we clojurers? clojurists maybe? Clojurinos?

0:17 notsonerdysunny: :)

0:17 amalloy: clojurians, i thought?

0:17 ohpauleez: ah, yes, that's it

0:17 notsonerdysunny: clojuredocs.org seems to be down

0:17 ohpauleez: notsonerdysunny: not for me

0:20 notsonerdysunny: hmmm

0:29 amalloy: ,(let [[a & more] [1] [b & rest] []] [more rest a b])

0:29 clojurebot: [nil nil 1 nil]

0:29 amalloy: excellent. thanks clojurebot

0:36 kmc: ,(let [[a b c] []] a)

0:36 clojurebot: nil

0:37 kmc: ,(let [[a b c] []] c)

0:37 clojurebot: nil

0:37 TigerUppercut: I don't know why, the same code in clojure and java was 35x more slow than java. That my calc to check 1mill numbers if is a perfect square

0:38 does it really happen?

0:38 amalloy: TigerUppercut: i think there are a lot of things you're doing less efficiently than you could be

0:40 if efficiency matters, you might look into those

0:41 calvini: z

0:43 erohtar: amalloy: did you figure out your multi-pred issue?

0:44 amalloy: erohtar: mmm, i'm half-heartedly hacking on it at the moment. i think it ought to be a function rather than a macro, but it's proving a little awkward to write

0:45 i can't find a way to do it without an explicit (loop), which feels way wrong to me

0:49 tomoj: ,(letfn [(conjunction [& preds] (fn [x] (every? #(% x) preds)))] ((conjunction pos? integer?) 3))

0:49 clojurebot: true

0:49 tomoj: does that work?

0:50 amalloy: ,(letfn [(conjunction [& preds] (fn [x] (every? #(% x) preds)))] ((conjunction pos? integer?) 'a))

0:50 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.Number

0:50 amalloy: ,(letfn [(conjunction [& preds] (fn [x] (every? #(% x) preds)))] ((conjunction integer? pos?) 'a))

0:50 clojurebot: false

0:51 tomoj: was the original problem that order matters?

0:51 I came in late

0:51 amalloy: no, the original problem was that i was doing something eagerly

0:51 where every? is lazier

0:52 i wrote this gross monstrosity, but yours is much better

0:54 _rata__: good night guys

0:54 see you

0:55 and thanks for all the help =)

0:55 amalloy: tomoj: yeah, yours is perfect, aside from the implementation detail that i want &x, not x

0:55 even the name is better :)

0:56 tomoj: I've wanted that function sometimes

0:57 we have complement, but that's it

0:57 amalloy: yeah

0:57 tomoj: disjunction and conjunction aren't as useful I guess

0:57 actually..

0:57 amalloy: no, not quite as useful, but seems like they come up sometimes and might well belong in contrib?

1:00 tomoj: s/actually..//

1:00 sexpbot: <tomoj>

1:00 tomoj: I was thinking juxt could help but it's not lazy and makes it uglier anyway

1:00 amalloy: right. juxt was my first solution

1:01 i've seen juxt applied cleverly so many times on #clojure that when i have an interesting problem the first thing i ask myself is "does this problem have anything to do with juxt?"

1:02 tomoj: haha

1:07 amalloy: anyway, conjunct (-ion seems too verbose for me) is quite handy. i'll have to put it into some kind of library for my other projects

1:09 especially now that i'm adding pre- and post-conditions on my functions to remind me where to look when i start using them wrong

1:11 tomoj, or anyone: how do you feel about writing (defn baz [[& foo] bar]) vs (defn baz [foo bar]) to clarify that foo should be a collection?

1:12 hiredman: ,(doc refer)

1:12 clojurebot: "([ns-sym & filters]); refers to all public vars of ns, subject to filters. filters can include at most one each of: :exclude list-of-symbols :only list-of-symbols :rename map-of-fromsymbol-tosymbol For each public interned var in the namespace named by the symbol, adds a mapping from the name of the var to the var to the current namespace. Throws an exception if name is already mapped to something else in the current name

1:17 amalloy: what's the keybinding in paredit to kill the sexp at point? C-k kills everything on the line, even after that sexp. i could go into the sexp, hit C-k, and then delete it, but that seems silly

1:18 i guess going into the sexp and then hitting M-<down> isn't too bad

1:23 also, is there a function that combines quot and rem? i know i can use (juxt quot rem), but it seems like that's duplicating work for the computer

1:24 replaca_: amalloy: C-M-k?

1:24 amalloy: replaca_: thanks, that's exactly what i was looking for

1:24 replaca_: cool

1:25 that's not really paredit, just emacs

1:25 amalloy: oh, so it is

1:25 i assumed that since C-k was rebound by paredit, so was C-M-k

1:25 replaca_: it will work in your python buffer, too, I think :)

1:26 amalloy: heh. php, more likely :(

1:26 replaca_: C-M-k already does the "right" thing

1:26 oooh :(

1:26 ohpauleez: amalloy: juxt is the best solution I think

1:28 amalloy: replaca_: i think paredit's C-k is useful sometimes, but C-M-k must be useful more often. maybe i should rebind

1:31 replaca_: well, C-k is standard emacs (and just slightly modified by paredit), so if you use emacs for other things, you might want to keep it

1:31 but the beauty of emacs is that you can do what you want :)

1:36 * amalloy feels silly for writing (complement #(every? zero? %)) instead of (not= [0 0] %), when the object in question is known to be a seq of length two...

1:41 shachaf: amalloy: Why not #(any? (complement zero?) %) (or however you'd write that)?

1:42 amalloy: shachaf: that's basically the same as my original form - equally verbose, and equally correct

1:43 the second form is much shorter and faster, and just as correct given that the seq is always two long

1:43 and arguably easier to understand?

1:43 shachaf: amalloy: Well, it's more general, so if it's as clear it's nicer.

1:43 amalloy: it's not more general than my original, is it?

1:43 shachaf: amalloy: Nope. I prefer your original in principle. It's just an attempt to make that one clearer.

1:44 I don't know much about Clojure syntax (apologies for being an intruder here), but in Haskell "any (/= 0)" and "(/= [0,0])" are the same length.

1:44 I suppose which one is clearer depends on the context.

1:46 amalloy: well, i don't know much about haskell syntax, but it seems like there are some implied arguments in there?

1:46 in clojure you could theoretically write #(take-whlile #(not= 0 %) %), except that you need % to mean two different things

1:47 er, every? not take-while. getting projects mixed up. but you see what i mean

1:48 shachaf: amalloy: Well, Haskell functions are curried (I hope the strict pedants don't beat me up for saying this :-) ).

1:48 amalloy: So perhaps it's not really a fair comparison.

1:49 amalloy: ah

1:49 shachaf: amalloy: I tend to feel silly when I do the opposite, though -- use a more specific form of a function than necessary.

1:50 amalloy: shachaf: well, i feel silly when i reinvent the wheel in a way that is clumsier than using the general case would be. i don't mind reinventing the wheel if i get a wheel that's actually better-suited to my current purposes

1:57 notsonerdysunny: Hello everybody, I thought describing the problem here may not give me enough space to do justice.. so I just sent it to the MailingList .. If anybody could help me .. with this http://groups.google.com/group/clojure/browse_thread/thread/ee283fa6af4f2bc8 it would be very nice of you

2:00 amalloy: notsonerdysunny: why is Variables a macro to begin with? just write it as a function and your problems seem solved?

2:00 notsonerdysunny: amolloy is also a predifined macro available in a library

2:01 erohtar: amolloy: sorry, i had stepped away

2:01 amalloy: what about this

2:01 notsonerdysunny: I want to write it in such a way that Variable only get accessed at compile time since it is accessing mathematica ... and we cannot distribute mathematica along with our tool

2:01 amalloy: *

2:01 erohtar: amalloy: (defn multi-pred [& preds]

2:01 (fn [x]

2:01 (not (some #(not (true? (% x))) preds))))

2:02 amalloy: erohtar: it's cool, tomoj came up with a solution i liked earlier

2:02 search for conjunct in the logs if you wanna look at it

2:03 erohtar: amalloy: if you use every, will that short-circuit?

2:03 amalloy: yes

2:03 kmc: amalloy, i'm a pedant and i'm here to beat you up :D

2:03 amalloy: it's only juxt that won't

2:04 shachaf: kmc: You mean me?

2:04 kmc: sure you too

2:04 :D

2:04 * kmc fails at scrollback

2:04 amalloy: haha

2:04 shachaf: kmc: Well... Haskell functions *are* curried in a sense. Even if not explicitly.

2:04 amalloy: kmc: feel free to beat me up if i ever make an assertion about haskell, since it will be false

2:05 kmc: shachaf, sure, i mean if you really want the pedantic answer

2:05 shachaf: kmc: The function that in Clojure would be :: (a,a) -> Bool is in Haskell :: a -> a -> Bool.

2:05 kmc: currying is just a convention

2:05 there's nothing in the Haskell language forcing you to curry, but the std lib and the syntax encourage it

2:05 * amalloy reflects: i could probably learn haskell just by writing down all the things i think are not true about it, and then treating them as true

2:05 shachaf: kmc: Oh, that's not the type of beating-up I had in mind.

2:06 kmc: amalloy, Haskell is the set of all languages that do not contain themselves?

2:06 amalloy: i don't think my statement was *quite* a russell problem, but maybe it was

2:06 kmc: it depends on whether you consider the statement you made to be itself a fact about Haskell

2:07 amalloy: ah, i see

2:07 shachaf: amalloy: Do you think Haskell is worth learning?

2:07 * shachaf attempts to set a trap.

2:08 amalloy: oh crap. i'd have fallen right in if you hadn't warned me

2:08 or if your name were easier to type. i can never remember where the Cs and Hs are, and i end up hitting TAB five times while i try to figure it out

2:08 kmc: trap sprung

2:09 which pedantic objection did you forsee shachaf?

2:09 amalloy: this slows me down enough that you have time to warn me

2:09 shachaf: kmc: Usually "currying" refers to the transformation of a function from (a,b) -> c to a -> b -> c.

2:10 kmc: So some people could say that as long as that transformation isn't explicitly applied, functions aren't curried.

2:10 kmc: ah

2:10 shachaf: amalloy: That's just because English is an awkward language.

2:10 kmc: *shrug*

2:10 shachaf: kmc: This objection usually pops up when people refer to partial application as currying.

2:10 kmc: yeah

2:10 that's wrong

2:10 amalloy: notsonerdysunny: you might look into apply-macro - i don't know if it does quite what you want, but it's basically a wrapper around using (eval)

2:10 kmc: but i think it's okay to use the word "curried" to refer to any function which follows the curried convention

2:11 anyway, i've had this argument in #haskell :)

2:11 hiredman: haskell is useful because the type signature for bind isn't completely etched into my mind yet so I need lambdabot to remind me

2:11 shachaf: hiredman: Unfortunately λbot is dead. :-(

2:11 kmc: not, like, permanently

2:11 she's just sleeping

2:12 hiredman, you're using (>>=) in clojure or another language?

2:12 shachaf: hiredman: Anyway, who needs bind? join/fmap/return is the True Way.

2:12 amalloy: notsonerdysunny: or, just don't put this code that returns a compile-time literal into functions - put them into compile-time literals!

2:12 kmc: hehe

2:12 hiredman: clojure

2:12 kmc: cool

2:12 * shachaf was recently reflecting on how nice monads would be in JavaScript.

2:12 hiredman: I am playing with writing a clojure compiler, which is just a big state monad

2:12 * shachaf suspects he's getting dangerously off-topic at this point.

2:13 kmc: hiredman, cool

2:15 it seems that Haskell and Clojure are technologically very different languages, but share a lot philosophically

2:15 notsonerdysunny: amalloy: that was just a example ...

2:16 amalloy: notsonerdysunny: but if the data is known at compile time, you can factor it out to a compile-time literal; if it's not known at compile time, you can't apply a macro to it

2:16 notsonerdysunny: amalloy: what I really want is the return value of (mathematica-eval "D[x*x,x]") which would calculate the derivative

2:16 replaca_: kmc: I think that they represent a lot of design choice made differently, but carefully, so all the parts fit really nicely

2:17 kmc: yeah

2:17 notsonerdysunny: amalloy: the funcition could be more complex

2:17 hiredman: http://github.com/hiredman/Archimedes/blob/master/src/Archimedes/compiler.clj is the front end and http://github.com/hiredman/Archimedes/blob/9da0f7cd3072f140573f678044176b884e968299/src/Archimedes/compiler/jvm2.clj is the backend

2:17 replaca_: kmc: a lot of us here in #clojure are big haskell fans

2:17 kmc: Haskell might be the only good committee-designed language

2:18 replaca_: maybe cause it's a (good committee)-designed language :)

2:18 kmc: hehe

2:18 i think it helps that they had no ambitions for more than like 100 people to use it

2:18 and that this was the case for the better part of a decade

2:19 replaca_: yeah. some academics trying only to unify their work

2:19 notsonerdysunny: amalloy: the purpose is to use mathematica to generate the code for solution of PDEs which ofcourse is know at compile time.. If I want the solution for a different PDE then I would substitute the original one with a new one and recompile to get the code that solves the new PDE .. its just a experiment I am running .. I want to see how far I can take it

2:19 kmc: to try to be a bit more on-topic: i'm interested in Clojure's STM, and in comparing with (GHC) Haskell

2:19 am i correct that Clojure's STM is not lockless?

2:20 replaca_: it's lockless from the user's point of view

2:20 but it's implementation involves locks

2:20 amalloy: notsonerdysunny: so it sounds like your data isn't known at *clojure* compile time, but only at *your-tool-here* compile time. what if you ran clojure in multiple passes? invoke mathematica, write the results to your clojure file, and repeat until you're satisfied with what's there

2:20 or use eval to accomplish the same thing; but the code you deploy can't refer to Variables, so you need to rewrite it somehow before you can have "finished" clj files

2:21 replaca_: ooh, an apostrophe crime, sorry

2:21 kmc: right, i meant on the implementation side

2:21 amalloy: replaca_: perhaps we should send you for a timeout in #english?

2:21 replaca_: no, not that! I recant!

2:21 kmc: GHC's STM is lockless and suffers from terrible performance at high contention

2:22 as threads step on each other and cause repeated retrys

2:22 replaca_: yeah, I'd be interested to see how clojure's does at high contention

2:22 amalloy: kmc: clojure does the same thing, though i understand there are a couple optimizations to try to reduce the problem

2:22 kmc: i'm interested in the idea of an STM implementation which introduces locking selectively at high contention

2:22 ah

2:24 replaca_: it's interesting, since it's still a research area. I think we'll learn a lot from the Clojure version since I expect it to be used very heavily

2:24 ok, time to zip off to bed. night all

2:26 amalloy: kmc: found the part of JoC that discusses this STM issue

2:27 (a) if a transaction has to retry N times (for some uninteresting N), it gives up and throws an exception

2:27 i presume this gives you a chance to re-evaluate how you're using STM

2:28 kmc: yeah

2:28 seems like a useful performance-investigation tool

2:28 amalloy: (b) older transactions are allowed to "shut out" younger transactions temporarily, to give them a chance to complete

2:29 tomoj: <amalloy> erohtar: it's cool, tomoj came up with a solution i liked earlier

2:29 *** freakazoid (~sean@2002:43b4:56b3:0:fa1e:dfff:fed9:2b0b) has quit: Quit:

2:29 Leaving.

2:29 <amalloy> search for conjunct in the logs if you wanna look at it

2:29 <erohtar> amalloy: if you use every, will that short-circuit? [01:03]

2:29 <amalloy> yes

2:29 <kmc> amalloy, i'm a pedant and i'm here to beat you up :D

2:29 <amalloy> it's only juxt that won't

2:29 <shachaf> kmc: You mean me?

2:29 amalloy: lol

2:30 kmc: those are the two points discussed in JoC, though i imagine if you looked through the java source you could find more points of interest

2:30 kmc: urk

2:30 where do i find this JoC of which you speak?

2:30 tomoj: did I stop the pasteflood?

2:30 (did I start one?)

2:31 amalloy: yes, and yes

2:31 i'm pleased to see you got over your tourettes to quickly, tomoj

2:31 tomoj: https://gist.github.com/2e218a0600cf73d19472

2:31 that's what I was trying to paste :(

2:31 amalloy: kmc: http://joyofclojure.com/

2:32 shachaf: tomoj: Get a smarter IRC client. :-)

2:32 amalloy: written by our very own chouser (and fogus who occasionally graces us with his presence)

2:34 don't go buying it because you want to learn more about the STM primitives, though; i parroted for you literally all of the information it contains

2:36 (implementation-wise, that is. it has a good chapter about how to use them)

2:37 kmc: would it be useful for learning the language? more so than online docs?

2:39 amalloy: well, JoC was the first clojure resource i really worked with

2:39 i haven't read any of the others, so i can't do a good comparison for you

2:40 but as i understand it JoC is less introductory, so as someone with functional-programming experience it's likely to be the one for you

2:41 you might also want to try labrepl, which is free and online. it's small, but it's hands-on and is useful for a few things

2:42 kmc: cool

2:42 i'm doing all right with the reference docs so far

2:42 amalloy: and now, i'm going to assume that the increasingly-louder yawns i'm emitting mean that it's bedtime

2:42 kmc: (and with asking annoying questions here)

2:42 sleep well :)

2:42 amalloy: night

2:43 oh, and pester LauJensen when he gets here (he's in germany, so he can take over if you stay up late)

2:43 or maybe he's in switzerland or something like that. whatever. european time

2:51 lypanov: lol

3:02 LauJensen: Good morning all

3:15 kmc: hi LauJensen

3:24 notsonerdysunny: good morning LauJensen

4:23 ossareh: what is a typical use case for constantly?

4:24 hiredman: (def always (constantly true))

4:24 if something is always, it's constantly true

4:25 raek: I don't use it very often. some functions like (swap! a (constantly x)) have alternatives for this case: (reset! a x)

4:25 ossareh: so in that case you are creating a var that can *never* be redefed?

4:26 hiredman: no

4:26 raek: no, #'always contains a function, that when given any argument returns true

4:26 hiredman: constantly creates a function

4:26 ((constantly true) :bleh)

4:26 ,((constantly true) :bleh)

4:26 clojurebot: true

4:27 hiredman: ,(update-in {:foo 1} [:foo] (constantly 5))

4:27 clojurebot: {:foo 5}

4:28 hiredman: my favorite is (repeatedly promise)

4:29 raek: I think it's perhaps only useful when an API requires you to pass an update function and you want it to do the same thing no matter what it gets

4:29 in other situations, there are most often another way of writing the code

4:29 e.g. assoc-in instead of update-in, reset! instead of swap!

4:40 tobiasraeder: morning

4:45 esj: mornin' all

4:48 tobiasraeder: hey esj :)

5:12 LauJensen: morning all ya'll

5:20 bartj: LauJensen, morning!

5:29 yayitswei: what's an idiomatic way to retry on error? currently using a (loop ... (if error recur))

5:35 AWizzArd: Java 6 Update 22 is out and contains some fixes for very serious bugs.

5:35 http://www.oracle.com/technetwork/java/javase/downloads/index.html

5:38 tobiasraeder: out of curiosity what fonts do all of you use for coding?

5:40 LauJensen: yayitswei: loop might be okay, depending on your scenario. A more stack-fragile approach would be (defn tst-retr [i] (try (/ 5 i) (catch Exception e (tst-retr (inc i))))) (tst-retry 0)

5:40 tobiasraeder: (set-default-font "-bitstream-Bitstream Vera Sans Mono-normal-normal-normal-*-12-*-*-*-m-0-iso10646-1")

5:41 _ato: tobiasraeder: (set-default-font "Inconsolata-12")

5:42 AWizzArd: Lau, not Times New Roman??

5:42 ;)

5:44 raek: tobiasraeder: Inconsolata <3

5:45 DejaVu Sans Mono is also good

5:45 bobo_: real men use Windwings

5:45 *wingdings

5:45 raek: (a superset of Bistream Vera Sans Mono)

5:45 yayitswei: LauJensen: what's the stack-fragile part? the try/catch?

5:46 or the manual recursion

5:46 LauJensen: yayitswei: No, the calling of itself. It grows the stack

5:46 yayitswei: gotcha. thanks

5:46 LauJensen: np

5:46 yayitswei: whereas recur uses a form of TCO right

5:47 LauJensen: Exactly

5:47 yayitswei: also meant to ask you Lau, in your Compojure/Emacs intro on Vimeo, you have Compojure logging displayed in the inferior lisp buffer. I don't see that in my Emacs, do you have some special configuration?

5:48 great screencast btw I learned a lot

5:48 LauJensen: yayitswei: thanks. Yea you're probably using cake swank ?

5:48 yayitswei: yep

5:48 LauJensen: yayitswei: alright, then my inferior-lisp, corresponds to your console output. I run everything within emacs using M-x swank-clojure-project

5:50 yayitswei: ok. but my console returns after the cake swank command, I think it runs in the background

5:50 tobiasraeder: @_ato how do you live with size 12 fonts? that seems so damn huge to me

5:51 yayitswei: is there a log file that it appends to?

5:51 LauJensen: yayitswei: Actually I dont know, you should check in #cake.clj

5:51 raek: I use inconsolata size 12 too. emacs seems to have its own unit system for fonts...

5:51 yayitswei: LauJensen: ah thanks

5:51 tobiasraeder: im trying 10 right now and that seems the biggest size i can really stand

5:52 raek: I would say that size 12 in emacs corresponds to ~10-11 in the rest of the OS

5:53 hrm, either that or Inconsolata size 12 is a bit smaller than <any other font> size 12

5:54 upon more consideration, the latter seems to be the case

5:55 LauJensen: emacs handling of font sizes seem undeterministic. Some fonts are great at 13, but take up half the screen at 14. Some only change 1 pixel

5:58 _ato: tobiasraeder: http://meshy.org/~ato/tmp/emacs.png

5:58 LauJensen: _ato: Can you send me your color theme?

5:58 tobiasraeder: _ato: i'd love that too

5:58 and seems to be about the same size as my size 10 font, weird

5:59 _ato: yeah, maybe the DPI is wrong on my PC or something, I dunno. I just fiddle it until it seems right to me :p

5:59 tobiasraeder: ^^

6:00 _ato: color theme is just zenburn: http://github.com/ato/emacs-starter-kit/raw/ato/elpa-to-submit/zenburn.el

6:01 I darken the background slightly from the default zenburn though

6:01 (setq zenburn-bg "#1f1f1f")

6:01 (zenburn)

6:02 LauJensen: zenburn is nice, but you have do run (zenburn) (zenburn) for all of it to work... Little to bright on the bg though

6:02 ah ok, you just said that .. :)

6:02 perfect, thanks to

6:02 ato

6:03 Is there a Ring middleware for parsing the parameters of an Ajax POST request?

6:05 tobiasraeder: since im such a clueless person, how do i integrate the color theme into emacs?

6:06 without using the complete starter kit ;)

6:06 LauJensen: tobiasraeder: put that file somewhere on your load-path, like ~/.emacs.d, then (require 'zenburn) (setq zenburn-bg "#1f1f1f") (zenburn) (zenburn)

6:06 tobiasraeder: @LauJensen thanks

6:06 LauJensen: or make a new folder if you like and do (add-to-list 'load-path "~/.that-folder") first

6:07 raek: LauJensen: are there any differences between an "Ajax POST request" and an ordinary POST request?

6:07 LauJensen: raek: Yes, the body comes as a stream

6:07 so both multipart-params and -params dont try to process it, even if it just contains "x=2"

6:08 raek: I see... then I don't know :)

6:20 yayitswei: just tried zenburn and I like the color scheme better. however I can't see my params helper anymore. any suggestions?

6:22 lypanov: anyone know a good testing framework for js that can be run from command line via eg rhino?

6:22 yayitswei: clarification- I can't see little marker that appears briefly over a corresponding paranthesis using zenburn

6:22 lypanov: ah, jspec. *tries it*

6:23 _ato: yayitswei: hmm, it's works for me

6:23 yayitswei: _ato: could it be because I'm using aquamacs?

6:24 _ato: I also use the paren-dimming stuff from the starter-kit, I doubt that'd cause the paren matching helper thing to break though http://github.com/ato/emacs-starter-kit/blob/ato/starter-kit-lisp.el

6:25 yayitswei: try M-x show-paren-mode

6:25 which should toggle it on or off

6:25 yayitswei: that's good to know. but it _was_ enabled

6:27 mrBliss: Here's what my Emacs looks like http://mrbliss.blinkenshell.org/emacs.png

6:27 _ato: yayitswei: I assume you've tried restarting emacs? I sometimes find after changing themes a few times the colours get messed up, presumably because not all themes set all the faces

6:29 yayitswei: these some docs here on how to set the color show-paren-mode uses, you could try setting it explicitly: http://www.emacswiki.org/emacs/ShowParenMode

6:31 yayitswei: _ato: thanks, just tried restarting emacs and I'm getting "Cannot open load file zenburn" so I'm investigating that

6:50 _ato: no errors now (thanks for the restart advice), but the background color doesn't change until I eval (zenburn) manually. any thoughts?

6:54 _ato: hmm.. only thing I can think of is that something later in your config might be overriding it

6:55 I just literally have (setq zenburn-bg "#1f1f1f") (zenburn) at the top of my config: http://github.com/ato/emacs-starter-kit/blob/ato/ato.el

6:56 (the file gets "required" automatically by starter kit, but I used to use a non-starter-kit emacs config and that was basically the same plus the require)

6:56 notsonerdysunny: scheme macros are supposedly more hygeinic .. is there a that would describe the difference from the lisper/clojurians perspective

6:58 yayitswei: _ato: well I'll keep poking around. thanks for your help

6:59 shanmu: Hi there, is there a clojure build tool which can do db-migrate stuff like rake (essentially, I am exploring for possibilties where I can maintain db objects/version them etc using clojure code)

7:02 notsonerdysunny: cake is clojure's rake .. I don't know anything beyond this or if it will address your problem ..

7:02 shanmu *

7:05 shanmu: notsonerdysunny: thanks! I saw cake, am using lein at the moment will think of migrating if it supports what I am looking for at the moment#

7:06 Is there any best practice/idomatic ways for maintaing db schemas using clojure?

7:06 _ato: notsonerdysunny: you know how in Clojure macros you use a trailing # on symbols? Like this: `(let [foo# ...] ...)

7:07 raek: notsonerdysunny: Scheme has a special expression rewriting language that Scheme macros are written in. In Lisps (including Clojure), macros are written in Lisp code.

7:07 _ato: the "foo#" symbol will be replaced with a automatically generated name so it doesn't collide with anything called "foo" in the surrounding code it's expanding into

7:09 As I understand it hygenic macro systems try to make it impossible to collide symbols like that. Clojure is sort of semi-hygenic, the idiomatic way of writing macros means it's easy to avoid symbol capture, but you can capture if you want to (useful in some obscure cases)

7:09 raek: notsonerdysunny: in Lisp macros it is also possible that "symbol capture" can happen

7:10 notsonerdysunny: for example, a macro generates a let form that binds variable y and wraps some code. if that wrapped code contains y, things break...

7:12 notsonerdysunny: Clojure elegantly solves this in most cases by letting syntax-quote resolve all symbols into fully qualified var names and providing the foo# gensym mechanism

7:12 LauJensen: yayitswei: did u fix your zenburn issue?

7:15 yayitswei: LauJensen: but I still can't figure out why my paren helper is broken. I'm shelving it for now (unless you have any ideas (: )

7:15 raek: (in most cases, since Clojure allows you to do unhygeinic macros if you want to: (defmacro evil [body] `(let [~'x 1] ~body)) )

7:15 LauJensen: If you got show-parens on, and its not working, try evaling the theme twice, or try a known good theme bfore zunburn

7:17 serp__: ,(+ 1 2)

7:17 clojurebot: 3

7:18 yayitswei: LauJensen: zenburn's my first theme

7:18 LauJensen: yayitswei: You might want to install color-themes from ELPA then

7:19 yayitswei: LauJensen: Ok- will try that tomorrow, thanks. It's late here in Cali!

7:20 LauJensen: alright :)

7:27 notsonerdysunny: thanks _ato and raek what you described clarifies things quiet a bit.

8:20 tobiasraeder: when you have a backtick quoted form is there a way to just create a symbol? (like 'mysymbol) would normally?

8:20 *(like 'mysymbol would normally)

8:21 pdk: ,`(1 ~'mysymbol)

8:21 clojurebot: (1 mysymbol)

8:21 pdk: hmm

8:21 ,`(1 mysymbol)

8:21 clojurebot: (1 sandbox/mysymbol)

8:22 tobiasraeder: yeah i dont want it to be resolved

8:22 but the first thing looks good

8:22 yeah works as i need it

8:22 thanks a ton :D

8:24 mhm maybe not

8:24 okay, its a bit more complicated but thats the problem caused by my code i think

8:28 raek: tobiasraeder: what does your code do?

8:29 (unresolved symbols in macros are used pretty rarely)

8:33 pdk: isn't there an equivalent to gensym for this

8:34 chouser: ,(gensym)

8:34 clojurebot: G__10167

8:35 raek: a symbol suffix that causes it not to be resolved? I'm not aware of such a thing.

8:35 chouser: `foo#

8:35 , `foo#

8:35 clojurebot: foo__10168__auto__

8:36 chouser: tobiasraeder: most of the time when you need an unresolved symbol you should use getsym or foo# Using ~'foo is usually an indication you're doing something tricky (or wrong)

8:37 fhd: Hi. How can I get a specific key from a map if I have the string? e.g. (let [m {:foo "Foo" :bar "Bar"} k "foo") ...?)

8:37 bobo_: ,(keyword "foo" {:foo "nils"})

8:37 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.lang.String

8:37 fhd: I forgot an ] after "foo"

8:37 bobo_: ah

8:37 bah

8:37 pdk: ,(symbol "foo")

8:37 clojurebot: foo

8:37 Chousuke: ,(keyword "foo")

8:37 clojurebot: :foo

8:37 pdk: ,(keyword "foo")

8:38 clojurebot: :foo

8:38 raek: (a suffix -- let's call it ¤ -- such that `(... foo¤ ...) is equivalent to `(... ~'foo ...), is what my answer was about)

8:38 fhd: Thanks, I see what you're getting at :)

8:38 First time I saw a ClassCastException from a bot :P

8:38 chouser: raek: oh right. nothing like that. :-)

8:38 fhd: Or any exception for that matter

8:39 ,("foobar")

8:39 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn

8:39 fhd: Awesome

8:40 tobiasraeder: @raek, chouser im still doing some pretty nasty java interop

8:40 ill look into getsym or use foo#

8:40 chouser: hm... java doesn't usually have any need for symbols of any kind, qualified or not

8:41 tobiasraeder: its combined with generation functions for deftype, alot of functions

8:41 and the function names for example are symbols, atleast thats what it looks to me

8:41 *generating

8:42 or am i getting that wrong?

8:43 _ato: your macro expands into (deftype foo ... SomeInterface (method [...] ...)) and you need to make sure the "method" symbol is unqualified?

8:43 that seems like an OK use of ~' to me

8:44 might be easier to implement using extend though

8:44 chouser: tobiasraeder: yeah, if you're generating named functions from some source other than the macro's caller passing them in directly, it's likely you'll need something like this

8:44 tobiasraeder: @chouser yeah thats what i have to do :/

8:44 @_ato how do i implement them using extend?

8:46 _ato: take a look at the doc-string for the "extend" function

8:46 it may or may not make it easier

8:46 might be able to avoid macro for some stuff and just write regular functions, depends on what exactly you're doing

8:47 tobiasraeder: ill look into it, thanks

8:48 _ato: ah wait.. looks like it only works with protocols, not interfaces

8:48 sorry my bad ;-)

8:48 tobiasraeder: okay :D

8:48 jarpiain: tobiasraeder: http://onclojure.com/2010/02/23/generating-deftype-forms-in-macros/

8:49 tobiasraeder: @jarpiain ill look into it

8:49 _ato: beware that post describes a prerelease version of deftype with slightly different syntax though

8:49 tobiasraeder: k

8:51 esj: tobiasraeder: at one point I used a macro to do a deftype: http://gist.github.com/448759

8:52 but it might be a simpler scenario than yours

8:52 tobiasraeder: @esj not really simpler, just a gazillion less methods ;)

8:53 how do i type hint the functions im implementing? the interface offers 3 functions with different types of parameters but the same name/amount of parameters

8:53 seems like im not getting it right

8:54 chouser: if you hint anything, you have to hint everything for that method, including the return value

8:55 tobiasraeder: that might be the problem

8:57 say i want to implement a method with the following signature public void doStuff (String arg0, Object arg1, Object arg2)

8:58 my try was (deftype mytype [] MyStupidInterface (^Void/TYPE doStuff [this ^String arg0# ^Object arg1# ^Object arg2#] (println "random stuff"))

8:59 but it tells me it cant resolve classname Void/TYPE which makes sense since its a type and not a class, anyone got a suggestion?

9:01 okay its just void not Void/TYPE and it works.

9:12 fhd: How can I convert a list to a vector?

9:12 chouser: vec

9:13 ,(vec (list 8 6 7 5 3 0 9))

9:13 clojurebot: [8 6 7 5 3 0 9]

9:13 fhd: chouser: Hm, I thought that was a shorthand to "vector". It isn't.

9:13 jfields: is there a fn that (x odd? [1 2 3 4]) ;=> [[1 3] [2 4]]

9:13 what is x?

9:14 chouser: fhd: right. vec is a bit like set and seq, in that it takes a collection not a series of args

9:15 while vector is like hash-set, list, hash-map, etc.

9:16 jfields: x is (juxt filter remove)

9:16 jfields: thanks chouser

9:16 chouser: np

9:27 lpetit: jfields: or it could be #(reduce (fn [[t f] e] (if (%1 e) [(conj t e) f] [t (conj f e)])) [[] []] %2) :)

9:27 ,(#(reduce (fn [[t f] e] (if (%1 e) [(conj t e) f] [t (conj f e)])) [[] []] %2) odd? [1 2 3 4])

9:27 clojurebot: [[1 3] [2 4]]

9:28 chouser: lpetit: is that just to get vectors?

9:29 lpetit: chouser: no, it's a horribly not time-tested premature optimization attempt to not traverse the list twice.

9:30 chouser: heh. ah.

9:35 fhd: Is there a function in Clojure that I can use to create a map from a list? Something like "map"? Here's an example: http://paste.lisp.org/display/115491

9:36 esj: ,(into #{} (1 2 3 4 5 6))

9:36 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

9:37 esj: boooo

9:37 ,(into #{} '(1 2 3 4 5 6))

9:37 clojurebot: #{1 2 3 4 5 6}

9:37 esj: ha !

9:37 kryft: esj: Serves you right for trying to call 1!

9:37 chouser: ,(let [s '(1 2 3)] (zipmap s (map #(str "Number: " %) s)))

9:37 clojurebot: {3 "Number: 3", 2 "Number: 2", 1 "Number: 1"}

9:38 fhd: chouser: wow that looks tough, give me a second...

9:38 chouser: ,(into {} (for [n [1 2 3]] [n (str "Number: " n)]))

9:38 clojurebot: {1 "Number: 1", 2 "Number: 2", 3 "Number: 3"}

9:39 raek: fhd: map + anonymous function is often more simply written with 'for'

9:39 chouser: ,(reduce #(assoc %1 %2 (str "Number: " %2)) {} [1 2 3])

9:39 clojurebot: {3 "Number: 3", 2 "Number: 2", 1 "Number: 1"}

9:39 fhd: raek: I'll try that, didn't know for

9:39 raek: I was kind of looking for a map version of "map" :)

9:39 lpetit: chouser: one more, one more ! :-) (you didn't show the version with transients :-p )

9:40 chouser: lpetit: into uses transients. :-P

9:40 lpetit: chouser: cheat

9:40 chouser: heh

9:41 (let [s [1 2 3]] (apply array-map (interleave s (for [n s] (str "Number: " n)))))

9:41 ,(let [s [1 2 3]] (apply array-map (interleave s (for [n s] (str "Number: " n)))))

9:41 clojurebot: {1 "Number: 1", 2 "Number: 2", 3 "Number: 3"}

9:42 raek: fhd: a version using into and for: http://paste.lisp.org/display/115491#1

9:42 lpetit: it's kind of a complement to the golf game. Start with the tiniest version, expand to the largest one :-)

9:42 chouser: hehe

9:42 esj: :)

9:42 fhd: raek, chouser: Nice, thank you. I like (for a lot :)

9:42 raek: fhd: but since you don't do anything with the keys, zipmap might be more elegant

9:43 chouser: ,(apply merge (for [n [1 2 3]] {n (str "Number: " n)}))

9:43 clojurebot: {3 "Number: 3", 2 "Number: 2", 1 "Number: 1"}

9:43 lpetit: Now please rhickey come in and show us how to abuse pods for creating a map from a list please :-)

9:43 raek: as chouser previously demonstrated

9:43 fhd: raek: I actually do, in my real code :P

9:43 chouser: hm. zipmap could be most efficient, but it doesn't use transients.

9:44 jfields: ,(apply assoc {} [1 2 3 4])

9:44 clojurebot: {3 4, 1 2}

9:44 chouser: into+for seems like a nice option

9:44 fhd: chouser: I'm going to have nightmares tonight for sure :) But nice to see 100 ways to solve this.

9:44 chouser: fhd: ok, I'll try, but 100 is a lot...

9:44 fhd: chouser: :P

9:45 raek: zipmap has a simplistic appeal if the keys and vals are processed isolated from each other

9:46 into+for is perhaps more elegant if the computation of the new key and val pairs share some part of the process

9:47 fhd: raek: That's the case for me. I'm actually iterating through a list of files and then saving them in a map, filenames as key, content as value

9:48 raek: Tried to use zipmap for that, but it was a nightmare

9:48 raek: The filenames are progressed too, in fact.

9:49 What does #{} do btw? I've done it like this: (into {} ...) and it works fine.

9:50 raek: #{} is the literal syntax for sets

9:50 (contains? #{:a :b :c} :a)

9:51 fhd: raek: Okay, thanks.

9:52 raek: np :)

9:56 lpetit: ,(contains? [4 5 6] 1)

9:56 clojurebot: true

10:04 fhd: What do you use for constants BTW? (def ) or something more fancy?

10:06 lpetit: def or defonce

10:10 AWizzArd: A def- and defonce- would be useful.

10:11 And a defconstant and defconstant- too.

10:11 chouser: I like ^:private

10:16 lpetit: chouser: so who's doing the foreword of JOC, finally ?

10:16 chouser: lpetit: oh, it's going to be great!

10:16 gotta run. bbl.

10:16 lpetit: chouser: I've had another idea ...

10:16 chouser: run coward, run :-)

10:17 * chouser beams

10:52 bartj: can anyone please tell the difference between the "package" keyword in Java and the "ns" function in Clojure

10:53 package generally doesn't include the class name

10:53 Chousuke: the package keyword doesn't do much

10:53 bartj: but while specifying the Clojure class name using the ns function, the class name seems to be included

10:53 Chousuke: ns actually creates a namespace object

10:54 It's not really a clojure "class". It's a namespace.

10:54 bartj: Chousuke, I am mostly concerned with the class-name definition

10:54 Chousuke: I suppose I should just say they're completely unrelated :P

10:56 Clojure namespaces just become named classes if you use gen-class

10:57 with the last segment of the namespace determining the class name, and the previous ones the packae

10:57 package*

10:58 bartj: Chousuke, thanks!

12:09 Licenser: this sounds bad: clojure.core/unquote-splicing

12:17 lpetit: Licenser: huh ?

12:17 Licenser: lpetit: never mind the bug was 50 cm infront of the screen ;)

12:18 lpetit: ok, cu

12:18 Licenser: :)

12:54 jfields: opinions? which is better? http://paste.lisp.org/display/115505

12:55 ohpauleez: as long as app-name is always constant, #2

12:56 kotarak: Dunno which is "better", but I'd prefer #2

13:18 LauJensen: #2

13:22 amalloy: really? i like #1

13:22 raek: the voting is till open? :) the I'd pick #2. maybe with defvar- instead of def

13:22 LauJensen: amalloy: I dont like using let to bind something to the global scope

13:22 raek: * still, then

13:23 amalloy: LauJensen: i guess that's true. i think i read the intro to LoL too recently

13:23 jfields: so no real benefit, it's just a personal pref?

13:23 raek: I most often put helper functions and magic numbers in private vars

13:24 jfields: is there a clojure "standard"?

13:24 ordnungswidrig: anybody here with experience in implementing TSP and m-TSP, and derived problems?

13:24 LauJensen: amalloy: lol? Lord of Lisp

13:24 raek: that way I can access them in my tests

13:24 LauJensen: ?

13:24 raek: LauJensen: was that questionmark pointed at me?

13:24 LauJensen: yea

13:24 no

13:25 KirinDave: Ha.

13:25 LauJensen: pointed at amalloy

13:25 sorry

13:25 little tired today :)

13:25 ordnungswidrig: heisenmark

13:25 raek: you're not the only one... :)

13:25 * ordnungswidrig had 3h of sleep and that's 12h ago...

13:26 ordnungswidrig: oh, bbl. sorry guys

13:26 LauJensen: he just remembered he needed to go get more sleep

13:27 KirinDave: /me grumbles.

13:27 raek: cold + Programming Theory homework...

13:27 KirinDave: News.ycomb is such a trashy hacker news outlet now.

13:27 LauJensen: KirinDave: yea I never read it, except when they commit half a day to flaming me, then I try to keep up with the fun :)

13:28 KirinDave: LauJensen: For a short while it was nice.

13:30 LauJensen: KirinDave: I think its hard to keep a community which is above 500 people. Would be nice to see some smaller groups ala #clojure

13:31 KirinDave: There is a special threshold for sites like that

13:31 Too small and the low volume keeps it from being worthwhile. Too high and you start to get node.js assholes demanding that you learn javascript because it's the best™.

13:32 E.g., http://news.ycombinator.com/item?id=1786161

13:32 That guy.

13:33 "I know javascript. What more do you want? I have *code to write!*"

13:33 LauJensen: woot? Ive never heard of anything such thing from the node.js community

13:33 KirinDave: LauJensen: Then you are not listening to the wretched masses.

13:33 "Write once, never rewrite for scale"

13:33 LauJensen: KirinDave: Yes I am, when they flame me :)

13:33 Though I haven't taken any shots for not using node.js yet

13:34 KirinDave: I ahve.

13:34 And I don't really have a public presence the way you do.

13:34 LauJensen: Well. Node.js still looks cool, its on my list of things to play with

13:34 KirinDave: But really, it's depressing to watch as people seem to forget _why_ they're doing what they're doing.

13:34 In that Lua thread, someone immediately asked, "Is there a framework for writing asynchronous servers with Lua?"

13:35 Which is just painful.

13:35 LauJensen: hehe

13:35 KirinDave: Synchronous, asynchronous, who cares? The right question is, "Is there a good framework for writing servers?"

13:36 LauJensen: KirinDave: So you're saying you dont care about the differences?

13:36 KirinDave: I suppose that the node.js masses have enough cargo-culting rubyists that this kind of nonsense was inevitable.

13:36 LauJensen: I do care about the differences.

13:36 If I can write threaded servers, I'd prefer to. The code is much more natural.

13:36 But I can and did write huge async stuff.

13:36 LauJensen: Did you ever see that epic ruby conversation I posted once?

13:37 It made the rounds.

13:37 LauJensen: No, please share

13:37 KirinDave: LauJensen: http://kirindave.tumblr.com/post/24570389/incredibly-stupid-people-on-freenode-ruby

13:37 LauJensen: wow, you really are harsh

13:37 Did you at least blur their names or something?

13:37 KirinDave: LauJensen: Read the log.

13:37 No

13:38 read the log tho.

13:38 I usually ablate my ire somewhat.

13:38 Not in this case, I still feel good about calling these people out.

13:38 LauJensen: Okay I'll read. Just the other day I said "Hey, I think this can be done better" and I got flamed for the better part of 4 hours, so Im assuming you'll take some heat for that URL as well :)

13:38 KirinDave: "because of closures, and scope"

13:38 Thats what my friends use to put each other down when we're talking out of our asses. :)

13:39 Seriously, read the transcript. It's pretty amazing.

13:40 _fogus_: "I was under the impression that ruby was a garbage collected language." <-- best line ever!

13:40 LauJensen: "kirindave: the most common reason for "leaking" is, it's not really leaking, there is a loop, and, I know this doesn't sound right, but please trust enough to try it... you have to paste the inside of the loop into a method, and just call the method from inside the loop, without doing any work inside the loop that isn't in a method " epic memory leak fix

13:40 KirinDave: _fogus_: It was like talking to Moai heads.

13:41 LauJensen: Irony tho, he was right.

13:41 LauJensen: Yea I fugred

13:41 Figured!

13:41 KirinDave: The bug was that ruby 1.8.4 had an optimization for purely functional calls.

13:41 _fogus_: KirinDave: You mean those things on Easter Island?

13:41 KirinDave: _fogus_: yes

13:41 * _fogus_ lol

13:42 KirinDave: It'd share a pre-allocated stack frame. The regex compiler pushed data into the local context with the assumption the stack frame would get collected.

13:42 And if you did this twice in these methods, the pointer would just get overwritten and lost to the collector.

13:42 LauJensen: KirinDave: You seriously think those guys were stupid in that conversation? I thought they were very helpful and accurate in pinpointing the problem, despite that the fact that you walk in there with an attitude

13:42 KirinDave: LauJensen: Oh they were incredibly stupid.

13:43 zaphar_ps: KirinDave: at least you've brightened my day a little with that link :-)

13:43 KirinDave: RubyPanther was correct the way any clock-shaped-object is right twice a day.

13:43 He's not even a whole clock, just a child's scribble of two intersecting lines.

13:43 LauJensen: And his fix wouldn't work.

13:43 The fix was to put x = 1 at the top of the method.

13:43 LauJensen: Calm down buddy, you're backbiting against someone who actually tried to help you

13:43 KirinDave: This told the ruby interpreter to make a new stack frame. :)

13:44 LauJensen: Isn't this the party where you go, “Problem?” :)

13:44 LauJensen: I dont think so :)

13:45 KirinDave: Part of interacting with people in a technical sense is realizing when you're out of your depth.

13:46 For example, if I began to lecture Chouser on how to do a bunch of clojure implementation shit out of my ass and then said, "But I am trying to help!" My intentions might be great, but in reality I'm just wasting his time and wasting Chouser's.

13:46 zaphar_ps: Glad you liked it.

13:46 zaphar_ps: KirinDave: the fix was to put x = 1 at the top of the method?

13:46 KirinDave: LauJensen: They didn't argue how to fix it, they argued it *wasn't a memory leak.*

13:46 zaphar_ps: that seems kludgy

13:46 KirinDave: zaphar_ps: it was. a later release of 1.8.4 corrected the problem.

13:46 LauJensen: KirinDave: They were right though ? It was an implementation of Ruby itself that leaked

13:47 KirinDave: zaphar_ps: But we had cod eot ship.

13:47 LauJensen: They were arguing it wasn't a leak.

13:47 But rather expected behavior. Since we fixed the leak, I suspect I was right and it was not desired behavior.

13:48 LauJensen: KirinDave: Well, its difficult to reason about 'desired behavior' in Ruby

13:48 KirinDave: That may be true.

13:48 LauJensen: I guess if you want desired behavior, you should consider not using Ruby

13:48 lypanov: ;)

13:48 zaphar_ps: KirinDave: since it was fixed in a later release that would support your supposition as well

13:48 KirinDave: But it was pretty obvious it was a leak. If you ran the gc after every call, it wouldn't keep that memory around

13:48 lypanov: ruby people don't like logic.

13:48 KirinDave: lypanov: Hey, i was a ruby person for years.

13:49 LauJensen: eww

13:49 :)

13:49 _fogus_: KirinDave: "The other reality you're facing here is your career. While it is gradually slowing, our field moves quickly. You need to be constantly studying and reading and learning to be any good at it at all. The reality is: grow and keep up or stop and be left behind." -- Couldn't have said it better myself.

13:49 KirinDave: There are smart dudes in the ruby community. They're just crowded by hangers-on and get-rich-quick folks.

13:49 * zaphar_ps has never been a ruby person largely because of stories like this

13:49 KirinDave: _fogus_: Thanks.

13:49 lypanov: KirinDave: i joined #ruby in '00

13:49 KirinDave: lypanov: Oh dear, quite early.

13:49 I was in 02.

13:49 lypanov: KirinDave: but rails killed everything that was ever good about it.

13:49 KirinDave: lypanov: Ha.

13:49 technomancy: KirinDave: you mean #ruby-lang?

13:49 KirinDave: No comment. I try to keep out of scuffles with DHH and the rails core team these days. I like Rick too much.

13:50 technomancy: In which context?

13:50 technomancy: In my post title, it was #ruby

13:50 technomancy: And I assumed he meant ruby-lang.

13:50 technomancy: KirinDave: the freenode channel is called #ruby-lang, maybe you got a crap answer because you were in the wrong channel? =)

13:50 LauJensen: hehe

13:50 KirinDave: technomancy: Oh no, #ruby exists. I was asking in #ruby-lang, too.

13:50 LauJensen: yea KirinDave, why does it say #php at the top? :)

13:50 KirinDave: But everyone who could help was out.

13:51 Dunno what it is now. This was in 2008.

13:51 lypanov: #ruby-lang has also been useless for a fair few years unless you have a rails q

13:52 technomancy: I quit that channel in 06 or so, it was high-quality-but-headed-downward around then.

13:52 lypanov: aye.

13:52 KirinDave: technomancy: I had largely withdrawn from everything but #caboose at that point, which is probably why i bothered to go into #ruby. Hadn't been burned yet.

13:52 lypanov: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/113779

13:52 ahhh memories

13:53 KirinDave: ha

13:53 "A new faster ruby... by christmas!"

13:53 * lypanov notes thats his project

13:53 KirinDave: -- Someone, 2004, 2005, 2006, 2007, 2008, 2009, 2010

13:54 lypanov: KirinDave: its... hard. :P

13:54 KirinDave: Ha.

13:54 ;)

13:54 I know.

13:57 jjido: I am looking for an example of blowing the stack by using large data and recursion instead of just recursion.

13:58 does Clojure allocate on the stack?

13:58 lypanov: large data?

13:58 any recursion unless its using proper tail call semantics will cause stack bloweruperage eventually

14:00 jjido: lypanov: yes a simple factorial function does it

14:01 tomoj: ,(reduce #(map + %1 %2) (repeatedly 10 (fn [] (repeatedly 10 #(rand-int 100)))))

14:01 clojurebot: (602 429 369 459 410 504 604 499 498 383)

14:01 rickmode: jjido: Unlike for example C and C++, JVM languages do not allow stack allocation of variables within procedures - only with formal parameters.

14:01 tomoj: ,(reduce #(map + %1 %2) (repeatedly 10000 (fn [] (repeatedly 10 #(rand-int 100)))))

14:01 clojurebot: Eval-in-box threw an exception:java.lang.StackOverflowError

14:02 rickmode: jjido: and those formal parameters are either primitives (like int, long, double) or a pointer (reference)

14:02 jjido: tomoj: thank you

14:02 tomoj: dunno if that counts

14:02 amalloy: LauJensen: sorry, was in a meeting. Let over Lambda

14:02 KirinDave: LoL is a rad book.

14:02 tomoj: it causes the lazy seqs to be realized in a way that blows the stack

14:02 KirinDave: I can still only understand about 2/3 of it, after 3 reads.

14:02 tomoj: ,(reduce #(vec (map + %1 %2)) (repeatedly 10000 (fn [] (repeatedly 10 #(rand-int 100)))))

14:02 clojurebot: [493931 495802 492457 493838 493937 499825 497226 499613 496431 498065]

14:03 tomoj: whereas that works

14:03 KirinDave: tomoj: Weird.

14:03 tomoj: I thought so too at first

14:03 and again now, since I can't really remember this :/

14:04 dnolen: tomoj: vec is strict

14:04 tomoj: yeah

14:04 * KirinDave sighs.

14:05 KirinDave: I'd better read these wsdl files.

14:05 tomoj: oh, I guess you end up with (map + (map + (map + (map + (map + (map + .....))))))

14:05 without the vec

14:25 kryft: O Matlab, how I hate thee. Let me count the ways..

14:39 LauJensen: btw, Conj Labs Frankfurt is sold out, so keep your eyes on the website for the next event

14:40 ohpauleez: LauJensen: Do you do those solo or with cgrande?

14:40 LauJensen: ohpauleez: Always with cgrand

14:41 ohpauleez: Ah, awesome. (cgrand* I don't know why I always add the /e)

14:42 shoover: man, these clojure events are going to start needing bigger venues

14:42 LauJensen: Yea he's a superb partner for this kind of thing.. or any kind of thing I guess :)

14:47 jjido: tomoj: I simplified your code

14:48 ,(reduce (fn [a, b] (map + a b)) (repeat 10000 [1]))

14:48 clojurebot: Eval-in-box threw an exception:java.lang.StackOverflowError

14:48 jjido: ;)

14:49 kotarak: Is it possible to extend a protocol to arrays?

14:54 _fogus_: kotarak: LIke this? http://gist.github.com/624638

14:55 kotarak: _fogus_: Ah. Yes. I fiddled with (extend-protocol Foo ....) But there neither "[L..." etc. works

14:55 Maybe strings for classnames should also be allowed?

14:55 They also work for types.

14:55 type hints, I mean

14:56 _fogus_: I could live with some sugar around the Class/forName thing

14:57 kotarak: _fogus_: Well, I consider ^"[Ljava.lang.String;" as sugar. (extend-protocol Foo "[Ljava.lang.String;" ...) could work similar.

15:01 _fogus_: I was thinking of sweeter sugar... but alas I have no better alternative.

15:12 KirinDave: _fogus_: Is that [[ a typo or necessary?

15:13 _fogus_: KirinDave: "[[" means 2D

15:13 KirinDave: Ah

15:14 _fogus_: "[[[" 3D etc...

15:14 It's a little DSL for Java arrays :p

15:14 KirinDave: Haha. Domain specific lunacy.

15:16 _fogus_: KirinDave: Section 10.3 of JoC has more information. :-)

15:17 KirinDave: I was reading that chapter on the train this morning.

15:19 jjido: Why does this work: (letfn [(later [& form] #(eval form))] ((later vector 1 2 3)))

15:19 and this fails: (letfn [(later [& form] #(eval form))] ((later list 1 2 3)))

15:21 Chousuke: jjido: try 'vector and 'list? :/

15:22 raek: jjido: hrm, not sure... but do you know about 'delay'?

15:22 jjido: Chousuke: yes that works

15:22 raek: I need a function not a ref

15:24 _fogus_: ,(letfn [(later [& form] #(do (println form) (eval form)))] ((later #(list % %2 %3) 1 2 3)))

15:24 clojurebot: DENIED

15:24 _fogus_: Grrr. Anyway, that worksa

15:24 raek: (defmacro make-thunk [& form] `(fn [] ~@form))

15:25 jjido: raek: you guys are great at macros ;)

15:27 raek: hrm, why does the first example work?

15:27 ,(eval (list vector 1 2 3))

15:27 clojurebot: DENIED

15:28 _fogus_: This works also: (letfn [(later [& form] #(eval form))] ((later (var list) 1 2 3)))

15:28 jjido: is there a special meaning to "!" in the Lisp culture?

15:29 list a special beast.

15:29 ohpauleez: jjido: In Clojure it means that it's destructive or will modify something

15:29 jjido: also cons

15:29 ohpauleez: like set!

15:29 jjido: ohpauleez: and on its own? I want a short name for the later or make-thunk macro

15:30 _fogus_: jjido: Using the (var _) technique should work for anything

15:31 ohpauleez: jjido: Nothing comes to mind, but

15:31 don't quote me :)

15:31 jjido: _fogus_: (letfn [(later [& form] #(eval form))] ((later (var cons) 1 '(2 3))))

15:35 _fogus_: jjido: In that case the problem is elsewhere. '(2 3)

15:36 (letfn [(later [& form] #(eval form))] ((later (var cons) 1 '(list 2 3))))

15:36 This is why people think eval is evil

15:36 jjido: isn't it? ;)

15:36 _fogus_: It is us who are evil. ;-)

15:49 jaley: hey guys, does anyone know if there's a util function in leiningen (or anywhere) for launching processes with provided args, or will it probably be just as easy to use java APIs for this type of thing?

15:50 dnolen: jaley: do you want to shell out or something?

15:50 jaley: dnolen: actually I want to run a java tool

15:51 dnolen: jaley: yeah I believe Java has some process APIs

15:51 jaley: dnolen: with the same classpath as the leiningen process in fact: calling package.class.main() would be nice if it didn't call exit() :)

15:52 dnolen: jaley: I definitely don't much about doing that kind of thing, perhaps someone else can chime in.

15:52 s/don't much/don't know much

15:52 jaley: dnolen: thanks anyway, i'll probably just call exec() from java

15:53 drewr: c.c.shell-utils/sh is decent

15:53 ordnungswidrig: anybody here, who know about TSP variations? Or optimization algorithms in general. I'm asking here because our beloved channel might attract those kind of people.

15:54 jaley: drewr: ah cool - thanks for the suggestion, will look into it

15:59 raek: I think that has been moved to clojure.java.sh in 1.2 (the old one is still functional, of course)

15:59 jaley: raek: found it in c.c.shell with no deprecation notes..?

16:00 raek: unless i'm blind, which i am, but still can't see it

16:01 raek: I don't know why. maybe c.j.shell does not replace c.c.shell-utils completely

16:02 jaley: raek: hmm.. looks extremely similar, i guess I should use the c.j version anyway

16:02 raek: saves me a contrib dependency

16:03 plathrop: Is lazytest broken or am I stupid? http://gist.github.com/624781

16:03 jaley: anyone know if there are plans for a clojure.math (or equivalent) to tidy up the math and math-functions etc in contrib?

16:05 jjido: plathrop: why the underscores?

16:06 plathrop: jjido: The funtion I'm attempting to test, one of the tranformations it needs to do is convert CamelCase to camel_case

16:08 Which it currently does by replacing #"[A-Z]" with (str "_" (lower-case c)) (where c is the matching character)

16:10 I plan on adding tests for that part too :-)

16:10 but I thought I'd start learning lazytest with something simple like "all the characters in the results are lowercase"

16:14 amalloy: ,(map #(Character/isLowerCase %) [\a \A \-])

16:14 clojurebot: (true false false)

16:14 amalloy: plathrop: ^^ seems to be why?

16:15 ,(map #(not (Character/isUpperCase %)) [\a \A \-])

16:15 clojurebot: (true false true)

16:17 plathrop: amalloy: ah, thanks

16:17 well... but why does it work at the repl?

16:18 amalloy: ummmm, does it? i don't see that in your gist

16:18 raek: it's too bad that 'complement' has such a long name...

16:20 dnolen: raek: and too nice that renaming it is so easy :)

16:21 amalloy: yeah. i don't thhink composition is so much more command than complement that it's worth messing up abbrevs. compose+comp seems to make more sense than comp/complement

16:22 _fogus_: ,(every? #(Character/isLowerCase %) (filter #(Character/isLetter %) "b-aa123&&b_b"))

16:22 clojurebot: true

16:22 plathrop: amalloy: It's the third section of the gist, scroll down.

16:22 amalloy: shachaf: if i were cleverer, i'd have found a way to use juxt to do both of my maps :)

16:23 plathrop: _fogus_: probably a better way of doing it, for sure. I'm just curious why it is different between REPL and command-line at this point

16:23 _rata__: hi

16:25 how do I start a repl in vimclojure?

16:26 _fogus_: plathrop: difference in char encoding between one and the other? :-( I got nothing

16:26 amalloy: plathrop: i'm not sure either

16:29 plathrop: you could try running just map canonicalize at the repl, see what the output is

16:29 or (some (complement lower-case?) (map canon blah)) to see which some fails

16:31 _rata__: does anyone use vimclojure?

16:35 raek: plathrop: beware that jline (which leiningen uses/used for lein repl) breaks UTF-8... :(

16:35 lypanov: _rata__: thinking about it.

16:35 raek: plathrop: try to do (seq "string containing the interesting chars")

16:35 * lypanov tries

16:36 raek: ,(seq "åäö")

16:36 clojurebot: (\å \ä \ö)

16:36 _rata__: lypanov, ah ok... haven't you used it yet then?

16:38 lypanov: _rata__: not yet no. but its sitting here in my directory waiting for me to use it.

16:40 okay. gonna try it now.

16:40 _rata__: lypanov, hahahaha ok... tell me please if you get to run a repl inside a vim buffer :)

16:41 lypanov: shall.

16:41 plathrop: Okay, thanks everyone

16:42 Big-time learning is fun

16:42 raek: plathrop: (explanation: the seq-of-string thingy is a test to check whether the terminal encoding and the repl encoding are the same. if they are not, the sequence will appear to have other characters than the string)

16:43 lypanov: _rata__: :ClojureRepl

16:46 ohpauleez: cool email on the list about the maybe-monad. Clean design, a little more verbose

16:46 LauJensen: ohpauleez: link?

16:46 _rata__: lypanov, thanks

16:47 ohpauleez: LauJensen: http://groups.google.com/group/clojure/browse_thread/thread/8b77bece19b0bba0/c9960c69ca059ff6?show_docid=c9960c69ca059ff6

16:47 LauJensen: Thanks

16:47 _rata__: but it doesn't work well for me... it tries to open the repl, but I get an error

16:49 amalloy: heh. almost like the link was to some malware that crashed LauJensen's computer

16:51 _rata__: what's nailgun?

16:51 lypanov: _rata__: you read the install instructions?

16:51 amalloy: clojurebot: nailgun?

16:51 clojurebot: I don't understand.

16:51 _rata__: this instructions? http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Vim

16:52 amalloy: clojurebot: nailgun is http://martiansoftware.com/nailgun/

16:52 clojurebot: Roger.

16:52 amalloy: good boy. _rata__, see above?

16:53 _rata__: yes

16:53 thanks

16:54 amalloy: actually this one's even better

16:54 clojurebot: nailgun is http://www.ruby-forum.com/topic/186850#815956

16:54 clojurebot: You don't have to tell me twice.

16:54 amalloy: lol. very apt randomly-chosen ack there, clojurebot

17:12 * lypanov beats nailgun with a stick

17:17 amalloy: lypanov: cake uses something nailgun-like; you could try using that

17:18 lypanov: amalloy: vimclojure needs nailgun itself so forcing it to work by repeatedly hammering it with a metal coated stick

17:19 amalloy: lypanov: might be cheaper to get a regular wooden stick, but put a heavy, flat, metallic object on one side

17:20 lypanov: awesome. actually works.

17:20 amalloy: my expensive metal plated stick really did the trick.

17:21 amalloy: well done. you should patent that

17:21 arkh: this may not be the right place to ask, but I have a memory leak in some clojure/java/networking code and I haven't been able to figure out why: http://gist.github.com/624930

17:22 * technomancy resists the urge to say "that's not a memory leak, it's supposed to work that way" a la KirinDave's earlier story

17:23 KirinDave: technomancy: Resist. :)

17:23 technomancy: But the joke is canonically, "Because of closures, and scope."

17:23 lypanov: you have to put it in a method in a method in a method and then say "bazam" and it'll work.

17:23 thats by design. you idiot.

17:23 amalloy: arkh: aren't you sending things to the agent faster than it can process them?

17:24 plathrop: "memory leaks don't happen in Ruby by definition" *facepalm*

17:24 arkh: amalloy: the listen() method blocks until it receives data

17:24 amalloy: but send-off doesn't

17:24 lypanov: obviously the guy was too young to have been around in '00

17:25 arkh: amalloy: it queues and sends fifo as its able

17:25 lypanov: in '00 ruby didn't have memleaks. it just crashed.

17:25 amalloy: arkh: but it has to hold that queue internally

17:25 and you're filling it up super-fast

17:26 arkh: amalloy: it queues it internally, true, but the actually runtime environment has packets arriving pretty slowly

17:26 amalloy: agent: please do a billion things for me. take your time with each thing, it's no problem, but i need you to write down this list of a billion things right now so you can do them later

17:26 arkh: *actual

17:26 amalloy: right? that's essentially what you're doing

17:26 arkh: amalloy: yes

17:27 amalloy: it's kind of a quickie setup. I would ordinarily set aside a buffer with an upper-bound so it doesn't consume all memory

17:27 amalloy: right. well, that's why it's consuming all memory :P

17:27 arkh: is it??

17:28 amalloy: you said the memory is leaking, right?

17:28 arkh: why wouldn't those objects get gc'ed?

17:28 lypanov: omgodz. i'm all repl-y and vim-y at the same time.

17:28 arkh: memory is leaking, yes

17:28 amalloy: because the agent isn't done with them yet

17:28 arkh: oh.

17:28 amalloy: it's falling out right there: creating an enormous to-do list for the agent, which it processes slowly

17:29 arkh: I guess I assumed agents would clean up their todo list as it was consumed. Not the case?

17:29 hiredman: you can use a future + a linkedblockingqueue

17:29 amalloy: (in fact an infinite to-do list, which you require the agent to realize all at once)

17:29 raek: a LinkedBlockingQueue can have an upper limit

17:29 http://download.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html

17:29 amalloy: arkh: they do clean up as they're consumed. but you write them faster than it consumes them

17:29 since as you say, the packets arrive slowly

17:30 and since agents are coordinated, it can only do one task at a time; the rest are buffered in the to-do list

17:30 arkh: amalloy, hiredman, raek : thank you

17:30 amalloy: I guess I should have read the agent code : (

17:30 hiredman: java.util.concurrent is good, use what is in it

17:31 amalloy: you probably don't want an agent at all. just (loop [] (do-my-packet-thing) (recur))

17:31 then do-my-thing will block, and you're all set

17:31 KirinDave: Agents seem widely misused.

17:31 raek: arkh: hrm, do you send-off upd-sends constantly? have you tried to let the upd-send function send itself to the agent?

17:31 arkh: I should do that for now - I just didn't want the read side blocked by the send side

17:31 KirinDave: They are more valuable for asychronicity than for bulk processing

17:31 hiredman: I have to say, I almost never use agents

17:31 I use futures and queues and promises

17:32 raek: someday I will finish http://github.com/raek/stream-seq, a more clojur-y abstraction that includes blocking queues

17:32 hiredman: I have an implementation of a blocking queue using promises

17:33 * lypanov wants a future/promise/based web framework which sends data in first req if within 500ms else streams via websockets if fails to meet the 500ms

17:33 hiredman: but it was just for fun

17:33 lbq

17:33 arkh: So agents can't be my asynchronous magic to sprinkle on my IO, huh? /s ; )

17:34 lypanov: you need a +2 blade of Awesome Agency

17:34 raek: hiredman: similar to this? http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/

17:34 arkh: ... I still have much to learn

17:35 raek: arkh: I think they can be used (but perhaps not ideomatically) in your case too

17:35 arkh: lypanov: I need my Agent of the Mongoose with +8 queue length

17:35 amalloy: arkh: udp is pretty fast though, right? i mean, it's not like tcp where it might block for seconds

17:36 arkh: amalloy: it's something to process and relay syslog messages so the packets aren't coming in that fast

17:37 amalloy: arkh: so have one, blocking, listening process, and an agent for sends

17:37 then you won't overflow the agent, and you can send without blocking on receive

17:37 arkh: raek: I do want to stick with what's idiomatic - still sometimes difficult to discern what is and isn't in clojure (when bending the guidelines becomes too much)

17:39 raek: well, rhickey uses an agent whose transition function sends itself to the agent as a way of looping in another thread in his ants.clj demo

17:39 arkh: amalloy: I'll look into some non-agent options, too. I

17:39 raek: ...probably why that solution pops up every now and then

17:40 arkh: raek: see? that's where I kind of got the idea it might be idiomatic

17:40 hiredman: raek: mine was much simpler

17:41 raek: but the ant agents actually keep state in them, so agents for ants seems motivated

17:41 arkh: hiredman: did you do an ants implementation?

17:41 hiredman: no

17:41 raek: I think he was referring to his LinkedBlockingQueue implementation

17:41 amalloy: (def outgoing (agent nil)) (loop [incoming nil] (when incoming (send-off outgoing (fn [] (udp-send sender incoming)))) (recur (udp-listen listener)))

17:41 arkh: something like that

17:42 arkh: amalloy: I'll check that out

17:42 raek: anyone have any comments on the examples on http://github.com/raek/stream-seq/, btw?

17:45 I hade this idea of making all handling logic of request-response servers pure functions that take seqs of requests and return seqs of responses

17:46 and that these handling logic functions could be swapped while the server is running

17:46 (not only by redefining the functions)

17:47 and a graph of pipes and filters could be built up from a DSL or something

17:49 _rata__: how do I check if an object is a ref? it can't find "ref?" or something like that

17:50 amalloy: _rata__: a hacky way would be to see if it's an instance of clojure.lang.Ref

17:51 (or clojure.lang.IDeref if you're checking against all ref types)

17:51 _rata__: ,(instance? (ref nil) clojure.lang.Ref)

17:51 clojurebot: java.lang.ClassCastException: clojure.lang.Ref cannot be cast to java.lang.Class

17:51 amalloy: ,(instance? clojure.lang.Ref (ref 1))

17:51 clojurebot: true

17:51 _rata__: ahh... it was the other way around

17:51 amalloy: ,(instance? clojure.lang.IDeref (ref 1))

17:51 clojurebot: true

17:52 _rata__: ok, thanks

17:52 raek: ,(map #(instance? clojure.lang.IDeref %) [(future 1) (delay 1) (promise)])

17:52 clojurebot: (true true true)

17:53 raek: ,(supers clojure.lang.Ref)

17:53 clojurebot: #{clojure.lang.IReference java.util.concurrent.Callable clojure.lang.IMeta java.lang.Runnable java.lang.Object clojure.lang.AReference clojure.lang.IRef clojure.lang.ARef java.lang.Comparable clojure.lang.IDeref clojure.lang.IFn}

17:53 raek: ,(supers clojure.lang.Atom)

17:53 clojurebot: #{clojure.lang.IReference clojure.lang.IMeta java.lang.Object clojure.lang.AReference clojure.lang.IRef clojure.lang.ARef clojure.lang.IDeref}

17:54 _rata__: and the best way to have mutually referencing objects is to use refs, right?

17:55 amalloy: ,(map (juxt #(instance? clojure.lang.Ref $) #(instance? clojure.lang.IDeref %)) [(ref 1) (promise 1) (atom 1)])

17:55 clojurebot: java.lang.Exception: Unable to resolve symbol: $ in this context

17:55 amalloy: ,(map (juxt #(instance? clojure.lang.Ref %) #(instance? clojure.lang.IDeref %)) [(ref 1) (promise 1) (atom 1)])

17:55 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$promise

17:55 amalloy: ,(map (juxt #(instance? clojure.lang.Ref %) #(instance? clojure.lang.IDeref %)) [(ref 1) (promise) (atom 1)])

17:55 clojurebot: ([true true] [false true] [false true])

17:55 amalloy: mutter

17:55 raek: if the objects are mutable, then yes. you'll need to use a reference primitive (ref/atom/agent/var)

17:56 amalloy: _rata__: often you can instead use one atom around the whole group of mutally-referring objects

17:56 but as raek says, if the objects are mutable that won't work

17:56 _rata__: no, objects need not be mutable

17:57 amalloy: then i think an atom is the preferable solution. it's certainly what *I* would prefer

17:57 raek: refs are fine. you can use atoms if updating multiple references atomically isn't important

17:58 amalloy: ,(let [x (atom [1 2])] (swap! x (fn [[a b]] [b a])))

17:58 clojurebot: [2 1]

17:59 _rata__: I need to read about atoms... I don't remember well what they are for

17:59 plathrop: hrm. how best to trim the first character of a string...

17:59 amalloy: they're the simplest mutable type: they perform a single read/write atomically

18:00 ,(.substring 1 "hello")

18:00 clojurebot: java.lang.IllegalArgumentException: No matching method found: substring for class java.lang.Integer

18:00 amalloy: ,(.substring "hello" 1)

18:00 clojurebot: "ello"

18:00 plathrop: nice

18:00 thanks

18:01 ,(subs "Hello" 1)

18:01 clojurebot: "ello"

18:01 amalloy: ~source subs

18:02 it just calls .substring, so use whichever makes you happier

18:02 _rata__: ok, but if I want to change later to use atoms, it's easy to refactor

18:02 isn't it?

18:02 amalloy: _rata__: depends on whether you've chosen to depend on updating multiple refs

18:02 if you have only one ref, it is very easy to change it to an atom

18:03 _rata__: amalloy, no, I have multiple mutually-referencing refs

18:05 amalloy: right. so then the refactor will basically be: define a new atom which is a seq of all the objects that are currently individual refs

18:05 if you wanted to change

18:05 if that's hard, or you often mutate some smaller subset of your refs, then stick with refs

18:06 raek: _rata__: atoms are just like refs, but more lightweight and without the transaction stuff

18:07 _rata__: also, be sure to have discovered get-in, assoc-in and update-in (might be handy to know about)

18:08 arkh: raek: I like your vision of stream-seq

18:08 plathrop: These seems ugly to me. Is this the best way to do this? http://gist.github.com/625027

18:08 _rata__: amalloy, ok, thanks... I think I'll stick with refs for a while

18:09 raek, yes, I commonly use assoc and assoc-in

18:09 amalloy: plathrop: yeah, i think you can do better

18:10 try a single replace on #"(?<!^)[A-Z]"

18:10 that should be the regex magic to say "don't match at the start of the string"

18:11 erikcw1: what is the preferred way to store project settings such as database logins and hosts so that they can easily be changed for production/testing? Property files, JSON, clojure?

18:11 plathrop: amalloy: ooh. I didn't know that one

18:12 zakwilson: plathrop: see ->

18:12 amalloy: plathrop: ?<! amd ?<= are very useful

18:12 plathrop: zakwilson: that's hard to google for, got a link?

18:12 zakwilson: plathrop: http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/->

18:12 plathrop: amalloy: I presume ?<= is the opposite of ?<! ?

18:13 amalloy: yes

18:13 A13aA4

18:13 s/(?<!^)[A-Z]/q/

18:13 sexpbot: <amalloy> A13qq4

18:13 amalloy: hm, sexpbot isn't case-sensitive, but you see how the lookbehind worked

18:14 plathrop: yeah

18:14 thanks, amalloy

18:14 Raynes: amalloy: It's just a Java .replace. :p

18:14 amalloy: s/(?i)(?<!^)[A-Z]/q/

18:14 sexpbot: <amalloy> hq, qqqqqqq qqq'q qqqq-qqqqqqqqq, qqq qqq qqq qqq qqq qqqqqqqqqq qqqqqq

18:14 amalloy: heh. worked

18:14 or the opposite of worked

18:15 s/(?I)(?<!^)[A-Z]/q/

18:15 ossareh: I've stumbled on some code I think is interesting: http://github.com/somnium/congomongo/blob/master/test/congomongo_test.clj - on line 16 what is the :let and the :when on line 22 - does for really have some form of "when" clause?

18:15 amalloy: ossareh: yes

18:15 ossareh: I need to read other people's code so much more than I do.

18:16 ,(doc for)

18:16 clojurebot: "([seq-exprs body-expr]); List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test. (

18:16 amalloy: ,(for [x (range 10)] :when (even? x) x)

18:16 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (6) passed to: core$for

18:16 amalloy: ,(for [x (range 10) :when (even? x)] x)

18:16 clojurebot: (0 2 4 6 8)

18:16 ossareh: wow

18:16 that kinda changes my life a little

18:16 thanks amalloy

18:17 amalloy: ,(macroexpand '(for [x (range 10) :when (even? x)] x)) ; now i'm curious

18:17 clojurebot: (let* [iter__4059__auto__ (clojure.core/fn iter__10443 [s__10444] (clojure.core/lazy-seq (clojure.core/loop [s__10444 s__10444] (clojure.core/when-let [s__10444 (clojure.core/seq s__10444)] (if (clojure.core/chunked-seq? s__10444) (clojure.core/let [c__4057__auto__ (clojure.core/chunk-first s__10444) size__4058__auto__ (clojure.core/int (clojure.core/count c__4057__auto__)) b__10446 (clojure.core/chunk-buffer size__4058__a

18:17 amalloy: haha, changed my mind :P

18:18 clojurebot: regular expressions?

18:18 clojurebot: Huh?

18:18 zakwilson: List comprehensions aren't really part of my usual thinking yet. I'd have used filter there.

18:18 amalloy: clojurebot: regular expressions is http://www.regular-expressions.info/tutorial.html

18:18 clojurebot: Ik begrijp

18:18 amalloy: clojurebot: regular expressions?

18:18 clojurebot: regular expressions is http://www.regular-expressions.info/tutorial.html

18:18 zakwilson: ,(filter even? (range 10)

18:18 clojurebot: EOF while reading

18:18 zakwilson: ,(filter even? (range 10))

18:18 clojurebot: (0 2 4 6 8)

18:19 amalloy: zakwilson: that's because filter is better there :)

18:19 but i wanted to demonstrate :when

18:20 * ossareh goes and fixes a nasty for that he has

18:22 plathrop: okay, so clojure.string or clojure.contrib.string or clojure.contrib.str-utils or clojure.contrib.str-utils2 ?

18:24 raek: plathrop: if you are on 1.2 and what you need is in clojure.string, then clojure.string

18:24 plathrop: Cool, thanks

18:24 When what I need isn't there?

18:24 lypanov: clojure with vimclojure is exactly what i thought ruby might well become 5 years ago and counting.

18:25 * lypanov does a happy happy joy joy dance

18:25 amalloy: lypanov: well, you can't win them all. maybe one day it'll be like emacs instead :)

18:26 * plathrop wants map-str but doesn't know which version of it to use

18:27 lypanov: amalloy: as i'm not a big fan of emacs, if it had become emacs like i'd not like it :)

18:27 amalloy: so while i enjoyed the joke, logically speaking... ;)

18:28 amalloy: yes, i would be astonished if there were any vim users who wished things were more like emacs

18:28 lypanov: amalloy: you mean in clojure or vim?

18:28 plathrop: Sometimes I wish vim were more like emacs, sometimes I wish emacs were more like vim. Depends which I'm using at the time.

18:28 amalloy: oh, either

18:29 lypanov: amalloy: wrt vim, the vast majority of people i think wish for something even vaguely as good as elisp.

18:29 zakwilson: For non-critical (but not entirely experimental) stuff, do I want to be using 1.3 yet?

18:29 lypanov: (i just keep praying for a minimal editor with damn good lang integration, but been doing that for > 5 years and still no answer...)

18:30 zakwilson: Emacs is minimal compared to the average IDE these days.

18:33 lypanov: zakwilson: from my perspective anything that i don't use is bloat so its got more to do with "can i easily turn it off. and is turning it off part of using it"

18:33 thats what i'm waiting for.

18:33 anyway. bed :) night *

18:33 zakwilson: lypanov: doesn't every programmer eventually write an editor? Now may be your time.

18:47 ohpauleez: vimclojure + paredit.vim has been a blast for me as well

18:48 That said I use emacs for CL, but Clojure felt pretty natural in vim

18:48 I think this is in part to lein

18:49 tmux/awesomewm + leiningen + vimclojure/paredit.vim

18:57 * ossareh is a proud use of emacs and vim for where they both excel

18:57 KirinDave: I wonder if yayitswei is going to show up...

18:58 amalloy: he threatened to show up at your coffee thing, right?

18:59 hey shachaf, i just reinvented the wheel in a silly way again, but this time in java

19:02 Derander: ossareh: me too

19:02 ohpauleez: does vimclojure have an repl mechanism?

19:02 I learned emacs to do clojure dev, never did the vim side of things

19:02 ohpauleez: Derander: it does

19:02 I rarely use it

19:02 Derander: mm

19:03 ohpauleez: I typical eval file or paragraph, doc lookup, and auto-complete

19:03 typically*

19:03 Derander: yeah

19:03 ohpauleez: sometimes I macro expand

19:03 Derander: I use the repl for testing out ideas.

19:03 ohpauleez: I have a running repl in another tile

19:03 but I don't use the repl via vim

19:04 Derander: http://github.com/ohpauleez/net-ns/blob/master/README.md

19:04 there's a poorly formatted section about the vimclojure stuff I use

19:08 Derander: ohpauleez: thanks

19:09 ohpauleez: np

19:10 jjl: Is there any better way to set global function across all namespaces? E.g in user.clj, (use 'clojure.contrib.repl-utils :only [show]). It works great in user=> when I call (show xx), but when I switch to another namespace foo=>, I have to do it again. It is annoying …

19:10 _rata__: thank you guys... see you later

19:12 technomancy: jjl: not really. it's sort of possible with ns-tools, but it's a bit awkward to set up. if you just want show, you're better off using slime-inspect (C-c S-i) in Emacs, presumably other tools have similar functions

19:14 jjl: technomancy: thanks for your hint. But I am using vim and I want to use other functions more than show such as pst+ clj-stacktrace.repl

19:15 Is any better way to enable stacktrace all the time instead of only showing one line. After that, I have to (pst+) ...

19:42 jjido: can you do a var from a 'name?

19:48 ,(var 'first)

19:48 clojurebot: java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.Symbol

19:57 jjido: Are there no more macro experts around?

20:00 kmc: ,(eval 'first)

20:00 clojurebot: DENIED

20:00 kmc: ;P

20:01 jjido: kmc: I tried (let [v (eval 'first)] (var v)), but it says v is not known

20:01 kmc: wouldn't (eval 'first) evaluate to a function?

20:02 ,(var first)

20:02 clojurebot: #'clojure.core/first

20:04 jjido: ,(let [v 'clojure.core/first] (deref v))

20:04 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IDeref

20:04 jjido: ,(let [v 'clojure.core/first] (deref (var v)))

20:04 clojurebot: java.lang.Exception: Unable to resolve var: v in this context

20:12 amalloy: ,(supers (var first))

20:12 clojurebot: java.lang.ClassCastException: clojure.lang.Var cannot be cast to java.lang.Class

20:12 amalloy: ,(supers (class (var first)))

20:12 clojurebot: #{clojure.lang.Settable clojure.lang.IReference java.util.concurrent.Callable clojure.lang.IMeta java.lang.Runnable java.lang.Object clojure.lang.AReference clojure.lang.IRef clojure.lang.ARef clojure.lang.IDeref clojure.lang.IFn}

20:13 amalloy: ,(let [v first] (deref (var v)))

20:13 clojurebot: java.lang.Exception: Unable to resolve var: v in this context

20:13 amalloy: oh sure

20:14 ,(let [v (var first)] (deref v))

20:14 clojurebot: #<core$first clojure.core$first@1b5dade>

20:15 amalloy: i missed the beginning. is that anything like what jjido was trying to do?

20:15 jjido: amalloy: I would like the ref, but I don't have the variable

20:16 amalloy: I was trying with (var 'first)

20:16 amalloy: jjido: do you have its namespace?

20:16 jjido: amalloy: yes I think so

20:17 amalloy: ,(find-var 'clojure.core/first)

20:17 clojurebot: #'clojure.core/first

20:17 jjido: amalloy: great!!!

20:18 amalloy: see also intern if you don't want to glue the symbol together yourself

20:18 ,(intern 'clojure.core 'first)

20:18 clojurebot: DENIED

20:18 amalloy: awww

20:18 well, that would work in real life

20:22 ,(ns-resolve 'clojure.core 'first)

20:22 clojurebot: #'clojure.core/first

20:23 amalloy: jjido: ^^ is a better solution than intern, though feel free to use find-var if it's more convenient

20:24 jjido: what is the difference between them?

20:24 amalloy: if the var doesn't exist, intern will create it and ns-resolve will return nil

20:26 jjido: ok

20:26 the name makes sense :)

20:47 bhenry: hello

20:48 is there something like this built into clojure or contrib for maps? https://gist.github.com/fef21fec41dd21dfa107

20:49 amalloy: ,(doc get)

20:49 clojurebot: "([map key] [map key not-found]); Returns the value mapped to key, not-found or nil if key not present."

20:50 amalloy: ,(let [v [:bar 1] e [:"bar is" :bar]] (map e #(get v % %)))

20:50 clojurebot: Invalid token: :

20:51 amalloy: ,(let [v [:bar 1] e ["bar is" :bar]] (map e #(get v % %)))

20:51 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: sandbox$eval10486$fn__10487

20:51 amalloy: bhenry: it's something like that anyway :P

20:51 ,(let [v {:bar 1} e ["bar is" :bar]] (map #(get v % %) e))

20:51 clojurebot: ("bar is" 1)

20:52 bhenry: amalloy, i had just changed my implementation to use get, but i was wondering if there was some kind of turn map into string function like that

20:52 amalloy: there might be, but if there were you would still have to iterate over the vector, since the map isn't sorted

20:53 bhenry: okay. i was mainly trying to make sure i wasn't reinventing the wheel. i find myself doing that a lot. mostly from ignorance.

20:53 the bonus is that lately i find that my solutions are getting more and more similar to the idiomatic ones out there.

20:54 amalloy: bhenry: ot

20:54 damn it

20:54 bhenry: it's a nice little semi-printf you have there

21:22 jjido: do you get a new namespace when you do (eval (read-string))?

21:38 it is clear that you get a new namespace when you do (eval (read-string)) but what is its name?

21:39 oh, symbols that are function arg names do not pertain to a namespace

21:39 :(

21:41 amalloy: jjido: right. binding forms don't have namespaces

21:43 ,`(let [x 1] x)

21:43 clojurebot: (clojure.core/let [sandbox/x 1] sandbox/x)

21:43 amalloy: ,`(let ['x 1] 'x)

21:43 clojurebot: (clojure.core/let [(quote sandbox/x) 1] (quote sandbox/x))

21:43 amalloy: hm

21:44 oh right. it's a valid syntax-quote, but if you expand it as a macro it will fail

21:44 ,(clojure.core/let [sandbox/x 1] sandbox/x)

21:44 clojurebot: java.lang.Exception: Can't let qualified name: sandbox/x

21:46 amalloy: jjido: i assume you have some interesting example where it would be convenient for lexically-bound symbols to have a var; what is it?

21:47 jjido: amalloy: still the same story, I want a container object with a reference to the item, and a reference back from the item to the container

21:47 amalloy: ah

21:48 i'm still not sure it's possible without mutation

21:48 jjido: before I used var/deref but that route seems closed now

21:51 amalloy: what do you mean? you can do it with an atom

21:53 jjido: yes I need to use that. How about a mutable map otherwise? there are not that many containers to track

21:55 amalloy: ,(let [x {:holder (atom nil)} x-holder [x]] (swap! (:holder x) (constantly x-holder)) (identical? x-holder (:holder x)))

21:55 clojurebot: false

21:55 amalloy: hm

21:56 oh

21:56 ,(let [x {:holder (atom nil)} x-holder [x]] (swap! (:holder x) (constantly x-holder)) (identical? x-holder @(:holder x)))

21:56 clojurebot: true

21:56 amalloy: jjido: is this useful?

22:14 jjido: amalloy: I don't really see the point you make, too sleepy. I need a new atom for each container right?

22:15 amalloy: i think you can do it either with each container or with each held object

22:15 the way i did it puts an atom in each object, pointing at its container

22:44 shachaf: amalloy: Pong?

22:44 amalloy: gnip

22:44 shachaf: amalloy: Which wheel was it this time?

22:46 amalloy: oh, i had some Configuration class from a third party, and i needed it to store a List<String>, but it only accepted Strings

22:46 so i hacked around for a while and converted my list to a single string, then looked at the api and saw they had a setStrings convenience method that turns a String[] into String

22:50 rplevy: basic question that is hard to google: what predict distinguishes between all collectionish things and symbolish things? it's not symbol because number are not symbols for example

22:51 *predicate I mean

22:51 amalloy: ,(map coll? [[1] () 1 'a])

22:51 clojurebot: (true true false false)

22:51 amalloy: rplevy: ^^

22:52 alsocasey: could anyone point me towards my serialization options in clojure? Is there such functionality in the core or contrib?

22:53 rplevy: amalloy: I thought of that but what about (coll? (seq []))

22:53 amalloy: ,(seq []) ;is nil. not a collection

22:53 clojurebot: nil

22:53 rplevy: amalloy: oh that explains it, thanks :)

22:58 lancepantz: does anyone know if maven implements a dependency task model ala ant, rake, cake, etc?

22:58 tough to google for against results for library dependencies

23:02 technomancy: it uses a "lifecycle" model: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

23:03 amalloy: lancepantz: wikipedia has a decent summary of maven, too

23:05 lancepantz: good link, looks as if it does not

23:14 kmc: so are [ ] part of the fundamental syntax of s-expressions in clojure?

23:14 or are they, at some level, sugar for an ordinary ()-based combination?

23:15 i kind of expected that [ x y ] would get read as, like, (vector x y), but it seems not

23:15 amalloy: kmc: i believe they're part of the syntax

23:16 you can check out the asm/ directory of the java source to be sure; the compiler's in there somewhere

23:16 though maybe i'm not sure what you're asking

23:17 technomancy: ,(macroexpand-1 [:a])

23:17 clojurebot: [:a]

23:21 kmc: mm

23:21 any idea why this design decision was made?

23:45 amalloy: kmc: perhaps it's because the fundamental type in clojure is an Object? then there's no reason to favor lists over vectors, at the compiler level

23:46 kmc: but it seems valuable to have only one kind of thing, syntactically

23:47 amalloy: well, i guess it's possible there is

23:47 after all, we do *have* vector and hash-map functions

23:47 kmc: i mean this is one of the selling points of Lisp

23:47 but the [] syntax seems to work out ok — you can still quote it, etc.

23:47 amalloy: ,(map class [[1] (vector 1)])

23:47 clojurebot: (clojure.lang.PersistentVector clojure.lang.PersistentVector)

23:48 kmc: and what do i know, i've never implemented Clojure

23:48 btw has anyone worked on a native-code-compiling implementation?

23:49 amalloy: kmc: someone muttered about translating to scheme, and then passing that through the scheme-to-C compiler

23:49 kmc: a specific one?

23:49 there's more than one scheme native compiler, afaik

23:49 amalloy: hell if i know

23:49 kmc: anyway that's a cool idea

23:49 chouser: kmc: most such efforts will be dramatically easier after we've got clojure-in-clojure

23:49 amalloy: there's clojure-clr though

23:49 kmc: should work all right, except for the Java interop parts

23:49 for which you could a) use gcj java b) generate JNI c) do some RPC d) punt

23:50 chouser: kmc: I did peek at using gcj to AOT-compile to native code

23:50 amalloy: (a) is a fate worse than death. any of the others might be reasonable

23:50 chouser: but clojure's core classes use some parts of the java std lib that gnu classpath hasn't implemented

23:51 I started trying to hack those parts out, but ... got distracted ...

23:51 amalloy: though (d) seems pretty impossible for any definition of "punt", since even the most basic parts of clojure use forms like (. someObj somefunc)

23:52 kmc: well you could reimplement those?

23:55 amalloy: sure

23:56 kmc: though, i'm more and more of the opinion that for implementing a dynamic language efficiently, you need tracing JIT and not AOT compilation

23:56 i'm not sure if HotSpot's JIT-fu is powerful enough

Logging service provided by n01se.net