#clojure log - Jan 25 2011

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

0:00 brehaut: dnolen: i grabbed the miniKanren thesis and the ~dec23rd copy of the repo and took it away over the holiday

0:00 dnolen: brehaut: rad. it's come a long way since then :)

0:00 brehaut: frankly its very exciting, but i did have some trouble translating between the scheme notation and the clojure notation

0:00 yeah so i see :)

0:01 dnolen: brehaut: notation is not set in stone. I'm open to changing some of that around.

0:01 brehaut: i want to write a little blog post about it at some point; taking an algorithm from straight clojure, through a nondeterministic monad and then finally proper logical programming

0:01 dnolen: brehaut: I look forward to that.

0:02 brehaut: dnolen: the notation looked fine; i just had some trouble doing the translation

0:02 lead to more than one infinite loop

0:04 dnolen: brehaut: the next few things will give a few more knobs to prevent common cases of divergence. but first I'm focusing on pattern matching so writing logic programs in miniKanren isn't so tedious.

0:04 brehaut: dnolen: that sounds sensible

0:05 scottj: are there more/bigger logos examples than examples.clj?

0:05 brehaut: right, i better go cook some dinner

0:07 dnolen: scottj: sadly not really. I can't say I'm an experienced LP programmer. Been focusing more on the details of implementing a logic engine. But key goal though is to make sure that I can easily convert most of Bratko's Prolog book into miniKanren.

0:08 plenty of juicy real-world stuff in the Bratko book.

0:57 scottj: re discussion earlier about type inference/static typechecking in clojure, https://bitbucket.org/tarballs_are_good/lisp-random/src/e3c23510d062/HindleyMilner/tests.lisp

2:19 amalloy: i just had a probably-crazy idea. is it feasible to make j.u.regex.Pattern act like a predicate? eg (let [filters [#"puts" #"string"]] (some #(% "input string") filters)) to try a set of matches

2:21 i realize that in this example it's not hard to change it to (re-find % "input string") but if you want to use them as HOFs it's inconvenient to create anonymous functions all the time

2:23 brehaut: that does seem sensible

2:23 amalloy: brehaut: i seem to recall that it's actually not feasible but i just wanted to check

2:23 brehaut: really?

2:23 huh

2:24 amalloy: on account if IFn being an interface rather than protocol, for apparently-huge performance reasons

2:24 brehaut: was about to ask that

2:24 amalloy: and we can't make Pattern implement IFn

2:24 brehaut: yeah

2:26 LauJensen: Morning

2:26 brehaut: Morning Lau

2:26 amalloy: bonjour lau

2:28 brehaut: i really look forward to infoq not using flash for its videos

2:29 my laptop is toasty warm now

2:32 LauJensen: brehaut: What could change that?

2:32 brehaut: html5 video tag

2:32 so my browser could offload to the hardware to decode

2:33 this is at least partly apples fault for not letting adobe access its hardware api for video decoding

2:33 LauJensen: That would be nice. Though in my experience I dont recall seeing less CPU usage

2:34 brehaut: oh well

2:36 the clojure website should probably link 'dev' (in the top right) to dev.clojure.org raher than the old assembla shouldnt it

2:39 LauJensen: Yea

2:45 brehaut: i should probably make a ticket or rsomething then

2:49 amalloy: brehaut: i am dazzled by your enthusiasm

2:55 so dazzled that i'm falling asleep. night folks

2:57 LauJensen: brehaut: man you dazzled him to sleep :(

3:07 brehaut: thats how i roll

4:01 kanzeon: #MacPorts

4:40 TobiasRaeder: morning

4:40 LauJensen: morning

4:44 ejackson: Hello everybody

6:49 Licenser: aloa

7:49 Hali_303: what's the closest concept in Clojure what's Enum in Java?

7:50 many cases I'd need keywords from a restricted set

7:53 clgv: Keywords would fit.

7:54 like :foo or :bar or :foobar

7:55 &:foo

7:55 sexpbot: ⟹ :foo

7:55 Hali_303: clgv: sure, however in that case there is no compile time check that the value is indeed a part of an enumeration

7:55 clgv: you won't get a compile time check for that in a dynamic typed language, I suppose

7:56 Hali_303: clgv: yeah the problem is however, that it is very easy to mistype all these enumeration values and it would be cool if the compiler could catch that

7:56 so I know that even tough clojure is dynamic, there would be an enumeration type

7:57 clgv: you might use java enumerations if you really need to

7:57 Hali_303: how else could someone catch all these mistyped keywords?

7:58 clgv: no idea. I had that problem too. I guess your IDE should support you in that matter.. that would be possible to a certain degree...

7:59 atm I try to copy the keywords to avoid typos

7:59 Hali_303: i see

7:59 clgv: or in some cases I can encapsulate the usage of keywords behing my function api

7:59 s/behing/behind/

8:00 sexpbot: <clgv> or in some cases I can encapsulate the usage of keywords behind my function api

8:02 clgv: as conclusion I'd say use the Java Enums in case you really need their strict behavior. you will have compiler checks with them.

8:03 Hali_303: clgv: I see, thank you

8:08 LauJensen: Is this still the best way to round up? ##(int (+ 0.5 (/ 11 2)))

8:08 sexpbot: ⟹ 6

8:09 mduerksen: int isn't round, to be exact

8:09 LauJensen: mduerksen: Its an old trick for rouding, legendary

8:10 mduerksen: ah, now i get you ^^

8:11 which rounding do you mean then? math rounding wouldn't be accomplished by that trick, economic rounding would (i'm not sure if it's called that way in english)

8:13 LauJensen: The above rounds to 5 with (/ 10 2) and 6 with (/ 11 2) which is what I need for pagination, ie. round up if theres a remainder

8:13 mduerksen: ok, then that should be okay. if you need something stochastically stable, it wouldn't be the right way

9:05 fliebel: morning

9:08 bsteuber: do type hints on protocols get used in the generated interface declaration?

9:14 zmyrgel: I'm making chess engine and it's still pretty slow

9:15 It takes about 15sec to calculate legal moves to depth of 4

9:16 I was thinking that memoize could give nice boost in move generation and in check detection but I just can't seem to figure out how to accomplish that

9:17 chouser: bsteuber: hm, it doesn't look like it. I thought at least primitives would be generated where hinted, but apparently not. Everything is Object.

9:24 robonobo: zmyrgel: is it a large codebase? I tried to write one in python last summer, but I didn't know enough about branch and bound to make it performant. What algorithm do you use?

9:26 zmyrgel: robonobo: it's about 2000 lines at the moment

9:27 chouser: zmyrgel: are you aware of the memoize function?

9:27 zmyrgel: chouser: as I pointed out I'm aware of memoize, not enough to make it work :)

9:28 some peer review would be nice

9:28 jweiss: i'm having an issue with leiningen where there's a newer SNAPSHOT on clojars, but it keeps copying in the old one from the local repository. is there a way to force it to update?

9:29 (i know i can manually delete from my local repo, but i mean something in leiningen)

9:30 robonobo: i'm not sure dynamic programming would work with a set of possibities a large as with a chess game

9:30 zmyrgel: robonobo: what do you mean/

9:30 ?

9:31 robonobo: if i' not mistaken, memoize is like automatic dynamic programming (if i am, just shout at me)

9:32 zmyrgel: I gotta admit that the term automatic dynamic programming doesn't ring a bell for me

9:32 chouser: memoize just maintains a map of function args to values for you

9:32 robonobo: dynamic programming is keeping the values you already calculated in memory so you don't have to calculate them again

9:33 chouser: certinaly there are functions that can compute their results faster than memoize can look them up, in which cases it would be a poor choice.

9:33 robonobo: I don't think that definition is quite right. That sounds specifically like memoization to me.

9:33 zmyrgel: I thought the 'sliders

9:34 I thought memoize would help generating slider and knight movements on the game board

9:34 chouser: zmyrgel: for a function f that isn't self-recursive, these days I like: (defn f ...) (alter-var-root #'f memoize)

9:35 robonobo: chouser: Isn't the difference that in what you would call dynamic programming you store them yourself, in memoization it does it for you?

9:36 chouser: robonobo: "dynamic programming" to me sounds more like generating code at runtime, which is unrelated to memoization

9:36 zmyrgel: chouser: ok, lemme try that

9:37 chouser: zmyrgel: if f is self-recursize that probably won't do what you want. And also note that with stock memoize there's no control on the cache size -- it just grows.

9:37 robonobo: chouser: i might be translating wrong (from dutch) , but that's what we call it in my algortihms class

9:37 zmyrgel: chouser: yep, that could be an issue with chess :)

9:38 chouser: robonobo: interesting. saving previous results of a function for use later so you don't have to re-calculate sounds like exactly the definition of "memoize", and I don't think I've heard another word for it.

9:38 hm, though http://en.wikipedia.org/wiki/Memoization does at least mention dynamic programming

9:38 robonobo: from wikipedia: The key idea behind dynamic programming is quite simple. In general, to solve a given problem, we need to solve different parts of the problem (subproblems), then combine the solutions of the subproblems to reach an overall solution.

9:40 chouser: robonobo: well. You appear to be exactly correct.

9:40 robonobo: thanks for teaching me something!

9:40 robonobo: \o/

9:41 now I don't think memoization would do a lot of speeding up of a chess game

9:42 i would think the nr of possibilities is just too big

9:43 clgv: robonobo: you could use it with a caching strategy instead of storing everything and see if that speeds it up a bit. could be likely

9:44 zmyrgel: I was planning to see if I could cache the calls to slider move-generation and threaten checks

9:45 as sliders can return to positions they have already occupied so I wouldn't need to re-calculate their moves again

9:46 robonobo: sliders?

9:47 zmyrgel: bishop and queen moves as they 'slide' in the board

9:47 clgv: zmyrgel: what is your general approach? are you using a game tree?

9:47 zmyrgel: and rooks

9:48 clgv: sort of, my ultimate plan would be to have lazy gametree and progress that once the game proceeds

9:48 the code is in github: https://github.com/zmyrgel/tursas

9:49 clgv: uhm does that make sense to try to get a lazy game tree? you have to evaluate it in some specified depth to be able to choose the current move.

9:50 zmyrgel: yes, it would make sense

9:50 at least that's what I gathered from John Hughes 'Why Functional Programming Matters' paper

9:51 also, Land of Lisp seems to refer to same paper when making game tree though I haven't yet gotten to the lazy programming section

9:52 its kinda difficult for a first lisp/functional programming project

9:54 robonobo: zmyrgel: i would say so

9:54 zmyrgel: well, its my bachelors thesis project, still have about 2 months to work on it

9:56 robonobo: is there a reason you use (== x y) in stead of (= x y) ?

9:57 zmyrgel: only my assumption that == would be faster as it only works for numbers

9:57 raek: "The word dynamic was chosen by Bellman because it sounded impressive, not because it described how the method worked."

9:57 re. "Dynamic Programming"

9:57 chouser: heh

9:58 == is correct for numbers

9:58 raek: is there any difference between = and == for numbers in Clojure?

9:59 chouser: yes, though the specific differences depend on the Clojure version.

9:59 raek: ,((juxt = ==) (int 1) (long 1))

9:59 clojurebot: [true true]

10:00 chouser: In 1.3, ((juxt = ==) 1 1.0) returns [false true]

10:01 raek: = has clojure semantics and == java semantics?

10:01 fliebel: chouser: Why is that?

10:01 chouser: In 1.2, == is much faster for numbers than = is.

10:01 robonobo: = calls .equals according to doc

10:01 &(doc =)

10:01 sexpbot: ⟹ "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) a... http://gist.github.com/795023

10:02 raek: ,(.equals (int 1) (long 1))

10:02 clojurebot: false

10:03 chouser: http://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support -- I think "Update redux" is what's currently in 1.3

10:14 fliebel: Has anyone tried Amazon Beanstalk with Clojure? I'm still looking for my Heroku for Clojure. GAE is close, but I don't want to be tied to their API.

10:17 chouser: fliebel: tell me when you find it

10:18 fliebel: chouser: Beanstalk + lein war + AWS free tier, sounds okay...

10:20 ejackson: Yeah - I thought it was a pretty interesting development

10:20 they apparently give you a tomcat to deploy right into

10:21 chouser: 1 year limit?

10:21 fliebel: yes, after that, you start to pay €10/mo I think.

10:21 ejackson: thats not much money

10:22 fliebel: That's only the micro instance, last time I calculated, so I think you'll have to pay for S3 and what more as well.

10:24 clgv: Provided I have lazy sequence where entries 1 to n are already evaluated and the sequence is infinite, can I only iterate over the already evaluated entries?

10:25 chouser: It looks like a reserved micro instance running constantly would cost $115.32 per year

10:25 clgv: you want to be able to detect what has been unrealized?

10:25 fliebel: chouser: Including all the extra bits required to boot it?

10:25 clgv: chouser: yes. it's for debugging purpose

10:28 fliebel: Now that I think about it, if lazy seqs are immutable, how does Clojure *not* evaluate them every time you do (take 10)?

10:28 chouser: clgv: for debugging I wrote this: https://gist.github.com/589694

10:28 clgv: chouser: well mnot really what has been unrealized. I want to know what has been realized and iterate over it to print it for example

10:28 raek: fliebel: they contain something mutable internally

10:29 but the user can only affect it indirectly

10:29 chouser: clgv: note that code is a giant hack and could break at any moment, but I sometimes find it useful

10:29 dnolen: interesting. is it possible to get the following behavior from vectors or list?

10:30 ,(let [x '(2) y (cons 1 x)] (identical? x (rest y)))

10:30 clojurebot: true

10:30 chouser: fliebel: it looks like that price does not include storage after the first year. :-P

10:31 raek: ,(let [x (list 2) y (conj x 1)] (identical? x (rest y)))

10:31 clojurebot: true

10:31 chouser: ,(let [x (list 1 2)] (identical? (pop x) (pop x)))

10:31 clojurebot: true

10:31 fliebel: chouser: That deems it as expensive for me. (I'd call myself a self-employed student)

10:31 chouser: fliebel: yeah, it's more than I'd like.

10:32 raek: ,(let [x (vec (range 32)) y (conj x 1)] (identical? x (pop y)))

10:32 clojurebot: false

10:33 chouser: lists and Cons' retain the original "rest" value internally. vectors and maps don't, so that behavior is impossible for them.

10:33 fliebel: chouser: I can only hope to have a profitable web service by then.

10:33 chouser: :-)

10:35 raek: I don't think it's possible for vectors. in some cases, they can probably share the same tree, but iirc there's a "header" object that holds a reference to that tree and a new instance of that is constructed for each operation

10:35 s/instance of that/header/

10:35 sexpbot: <raek> I don't think it's possible for vectors. in some cases, they can probably share the same tree, but iirc there's a "header" object that holds a reference to that tree and a new header is constructed for each operation

10:37 fliebel: Hrm, so all of RoR, Django and CouchDB have IaaS with a basic free plan. How hard would it be to do Clojure? Even sexpbot can run my code ;)

10:37 chouser: right. and even if there's an identical tree inside, you never get to see that -- you only have access to the wrapper or root object which is different every time.

10:37 clgv: chouser: having checked the java-implementation I now udnerstand what your hack is doing.

10:38 chouser: clgv: great!

10:38 clgv: chouser: I think that "feature" could be easily supported by default

10:40 chouser: well, my code demonstrates it can be done. The question then is should it?

10:41 clgv: I guess for general purpose you wont need it really often

10:41 I can think of anything else than debugging right now

10:41 s/can/can't/

10:41 sexpbot: <clgv> I can't think of anything else than debugging right now

10:44 fliebel: clgv: You could have a loop of growing size :) Not sure what that is good for...

10:45 clgv: fliebel: I am writing a debugging tool for myself and run into the issue that I used infinite lazy loops which is totally reasonable for the program but which the debuggingtool couldn't handle until now.

10:49 *lazy seqs I meant

11:04 dnolen: chouser: raek: very interesting. I suppose that's yet another reason for list and cons to exist. That's a very useful property for some applications.

11:34 hoggarth: anyone care to help me understand recur ?

11:34 trying to implement sieve of eratosthenes

11:35 (defn seive [lst]

11:35 (lazy-seq

11:35 (cons

11:35 (first lst)

11:35 (seive (remove #(zero? (mod % (first lst))) (rest lst))))))

11:35 (defn primes []

11:35 (seive (map #(+ 2 %) (range))))

11:36 it works, but will give stack overflow with large numbers

11:36 robonobo: hoggarth not an expert: recur works differently than recursion would work in other languages

11:37 (i mean i'm not the expert)

11:37 when you do it the way you did, a new function gets put on the stack every time you call it

11:38 hoggarth: yep

11:38 chouser: hoggarth: the problem is that as you progress down the input seq, each element of your returned seq has more and more layers of (remove ...) around it

11:38 robonobo: if you would use (loop [...] ... (recur)), the program just 'rewinds' to that position with the new values given to recur and starts over

11:38 clgv: or you could use successive calls to filter

11:39 pdk: you're trying to apply remove to the whole list after the current call to sieve

11:39 robonobo: the simplest example would be (loop [i 0] (if (< i 5) (recur (inc i)))

11:39 pdk: and again after the call after that etc etc

11:39 chouser: what he's got is essentially successive (that is, wrapped) calls to filter (remove in this case)

11:39 robonobo: which does nothing but count to five internally

11:40 chouser: hoggarth: doing a *real* sieve of eratosthenes on an infinite lazy sequence is acutally rather tricky (in any language I'm aware of)

11:41 hoggarth: figures

11:41 fliebel: Okay, now even I — who knows how recur works — lost track of 4 people explaining it at the same time ;)

11:41 chouser: :-)

11:41 robonobo: haha

11:42 * chouser bows out and writes some docs

11:42 robonobo: maybe just a pointer to some good tutorial would be in order

11:42 hoggarth: the take away I got was use loop with recur

11:42 robonobo: hoggarth: yes

11:42 hoggarth: then you use that loop recur as you would any other recursive function

11:42 fliebel: Now I'd like to know what a *real* sieve of eratosthenes os… *googles*

11:43 chouser: http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf

11:44 robonobo: i think wikipedia has a nice animation

11:44 fliebel: I'm looking at it now...

11:44 robonobo: maaagical

11:49 fliebel: So, why would it be tricky to implement a real one in a lazy manner, and what is the one posted above doing?

11:49 clgv: small version with loop-recur:

11:49 (defn sieve

11:50 [max]

11:50 (loop [primes [2] left-numbers (range 2 (inc max))]

11:50 (if (empty? left-numbers)

11:50 primes

11:50 (let [last-prime (last primes),

11:50 non-div (filter #(-> % (mod last-prime) zero? not) left-numbers)]

11:50 (if (empty? non-div)

11:50 primes

11:50 (recur (conj primes (first non-div)) non-div))))))

11:52 fliebel: I see...

11:54 It should be possible to do lazily, without the p^2 check of course.

11:55 amalloy: doesn't c.c.lazy-seq already do lazy primes, fliebel?

11:56 hoggarth: :)

11:56 i guess it does

11:56 fliebel: amalloy: Yes… but I'm not sure how.

11:56 hoggarth: Mismatched argument count to recur, expected: 2 args, got: 1

11:56 oops

11:56 robonobo: http://clojuredocs.org/clojure_contrib/clojure.contrib.lazy-seqs/primes

11:56 hoggarth: http://richhickey.github.com/clojure-contrib/lazy-seqs-api.html

11:59 fliebel: Oh, right, the wheel, I studied this before :P

12:00 clgv: better just use filter on range with Miller-Rabin-Test ;)

12:19 fliebel: Are some, every? and not-every? all predicate functions for seqs?

12:22 hoggarth: i think so (according to http://clojure.org/sequences)

12:24 amalloy: fliebel: yeah, as well as not-any?

12:25 though some technically isn't, since it doesn't return true/false unless the predicate you use with it does

12:28 fliebel: amalloy: Ah! I was looking for not-any, but that isn;t there ;)

12:28 *any

12:39 ejackson: I'm trying to parse a java object with a bunch of string properties into a clojure map, keyed off a simple mangling of the property time (ie x.m_name becomes :name). Is there a way for Clojure to give me a list of the objects properties to help here ?

12:40 tonyl: maybe bean

12:40 ejackson: cool

12:41 thanks

12:41 clojurebot: Gabh mo leithscéal?

12:43 amalloy: ejackson: bean is the way to go if your object has getX methods; if you want to get the m_name field itself...well, you're probably wrong :)

12:44 ejackson: amalloy: yeah, i'm making a wrapper over an API to stop being wrong :)

12:52 zippy314: hi folks, I'm having a weird situation where running a test with lein fails during compilation with: java.lang.IllegalAccessError: execute does not exist

12:52 where execute if s a function that should exist.

12:52 And the code runs fine not it test mode.

12:53 The test file doesn't even have anything in it other than the simple ns declaration:

12:53 (ns anansi.test.commands

12:53 (:use [anansi.commands] :reload)

12:53 (:use [clojure.test]))

12:54 any thoughts?

13:03 pdk: my favorite part of vimclojure

13:03 is how the parens matching is far from bug free

13:03 hoggarth: zippy314 you are sure the namespace is included?

13:04 zippy314: hoggarth: thanks, it turned out I had a circular reference. The file refered to a file which refered to it, which seems to be ok when you do lein run, but not when testing.

13:07 amalloy: zippy314: no thoughts re your error, but i love that you're writing something called anansi

13:07 zippy314: amalloy: thanks. It's gonna be very cool...

13:07 :-)

13:14 amalloy: chouser: i watched your thing on finger trees this morning, and while i didn't learn that i didn't know from reading the paper, i thought it was quite handy that conjr and consl are like real words with vowels missing. i mentally pronounce them as conjure and conzle

13:24 LauJensen: amalloy: link?

13:25 amalloy: LauJensen: http://twitter.com/#!/clojure_conj/status/29896738538000384

13:25 zippy314: Are assignments in a let block guaranteed to happen in the order they are declared?

13:25 amalloy: zippy314: yes

13:26 hiredman: uh

13:26 assignments?

13:26 amalloy: hiredman: bindings, i assume he means

13:26 zippy314: yah.

13:27 so (let [first "1" second (str first "2")] (println second)) should allways return "12"

13:27 amalloy: zippy314: yes

13:28 &(use 'clojure.walk)

13:28 sexpbot: ⟹ nil

13:28 amalloy: &(macroexpand-all '(let [first "1" second (str first "2")] (println second)))

13:28 sexpbot: ⟹ (let* [first "1" second (str first "2")] (println second))

13:28 amalloy: aw, that doesn't make it clear like i thought. nonetheless it's true

13:29 zippy314: thx, so there's something else wrong with my code...

13:41 mrBliss`: I hope the slides are in sync with the speaker this time. It wasn't the case for at least 3 videos.

13:44 fliebel: Wee, lazy primes. Not as sexy as c.c.lazy-seqs/primes(with wheels and stuff), but it works. https://gist.github.com/795374

13:45 amalloy: mrBliss`: yeah it was perfect

13:59 chouser: amalloy: heh, interesting. unfortunately, both are gone in the current version.

14:00 now just use conj instead of conjr, and conjl instead of consl

14:01 fliebel: chouser: conjl is still a custom function?

14:01 golevar: what is the recommended editor/IDE for clojure?

14:01 amalloy: golevar: emacs, mostly

14:01 golevar: heh, could've figured

14:01 amalloy: chouser: *sadface*

14:01 though i do prefer conjl to consl

14:01 ohpauleez: golevar: But there is great support for almost any editor

14:02 vim, eclipse, IntelliJ

14:02 fliebel: Except notepad ;)

14:02 ohpauleez: For example, I use vim with vimclojure and paredit.vim

14:02 golevar: what about netbeans?

14:02 fliebel: ccw

14:02 oh, no

14:02 ccw is eclipse, right?

14:03 brehaut: fliebel: yes

14:03 enclojure is netbeans?

14:04 golevar: Yes, enclojure, anyone advising against it?

14:05 tonyl: did #clojure log stop saving the logs of the day?

14:12 chouser: fliebel: yeah, conjl is a protocol function that I assume would only make it into core if/when finger trees did

14:13 fliebel: chouser: Is that a possibility?

14:13 chouser: tonyl: oh, sorry, that's my fault. the logs are being saved, it's just that the web isn't being updated at the moment. I'll fix that soon.

14:13 fliebel: maybe

14:14 tonyl: chouser: thanks for that service, it is really welcome. :)

14:15 pdk: (doc if-let)

14:15 clojurebot: "([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"

14:16 chouser: tonyl: thanks -- I always have grand plans for it, and rarely the motivation to put any time into making them happen. :-P

14:19 fliebel: Is there a way to do (apply concat) to an infinite lazy seq?

14:21 chouser: apply concat returns a lazy seq

14:23 mefesto: Raynes: ping

14:23 Raynes: mefesto: pong

14:23 fliebel: chouser: It's magic! How can apply stuff an infinite seq into a functions as arguments?

14:23 mefesto: Raynes: updated the tutorial

14:23 chouser: fliebel: you answered it yourself -- it's magic

14:24 mefesto: Raynes: on the repo if you wanna check it out. I don't have a 'Next' link in there yet so at the moment typing 'next' in the REPL will move you to the next screen.

14:24 fliebel: chouser: Java is not magic, where lies the trick? IN the source of apply or somewhere deep down IFn?

14:24 chouser: apply will call the function, passing a lazy seq to its & args

14:25 fliebel: &((fn [& a] (type a)) 1 2 3)

14:25 sexpbot: ⟹ clojure.lang.ArraySeq

14:26 Raynes: mefesto: Cool stuff. I'll check it out in a moment.

14:26 fliebel: I always thought it'd be a vector...

14:26 chouser: ,(apply (fn [a & b] (type b)) [1 2 3])

14:26 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

14:27 chouser: ,(apply (fn [a & b] (type b)) (range 50))

14:27 clojurebot: clojure.lang.ChunkedCons

14:27 fliebel: I see… Just any ISeq works.

14:27 chouser: ,(apply (fn [a & b] (second b)) (range))

14:27 clojurebot: 2

14:32 fliebel: I haven't figured out how and what, but I think Clojure is missing some iterating function. reductions is to reduce as loop is to ???

14:32 no, wrong thinking...

14:32 Licenser: aloaeh

14:33 fliebel: Licenser: hi

14:33 Licenser: hi fliebel how is live?

14:33 fliebel: *snif* I got a little cold, but besides that, fine :) you?

14:34 (you'll all get crazy when I type *snif* every time I *snif*)

14:42 Licenser: heh I am fine, got a little cold too but aside of that I'm great :)

14:42 amalloy: fliebel: the one that's missing is unfold imo, but i don't think that's what you're looking for

14:44 chouser: fliebel: lazy-seq?

14:47 fliebel: chouser: I don't know yet. I jus find myself in situations where I need the flexibility of loop/recur, but have it work like reductions or iterate, or...

14:48 chouser: I think someone once wrote a macro that looked like loop/recur but returned a lazy seq.

15:01 hiredman: I have a macro that looks like loop/recur but instead queues up bodies to be run async style

15:12 amalloy: fliebel: https://gist.github.com/b549634b4d855cde88c2 is how you could use unfold if it existed. is that anything like what you want your loop/reductions hybrid to do?

15:16 clojurebot: #<RuntimeException java.lang.RuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated>

15:17 fliebel: amalloy: I don't know. I'm still trying to understand :)

15:19 mefesto: Seeking advice. I'm working on an internal json api and would like to transparently handle j.sql.Date and j.sql.Timestamp in a general way. I was thinking of representing them as ["date" year month day] or ["timestamp" year month day hour min sec ms tz] then extending c.c.json. Does this seem reasonable?

15:19 fliebel: amalloy: I think that is kind of what I was thinking of.

15:19 amalloy: fliebel: unfold is the opposite of reduce (and reduce is often called fold, so...)

15:20 pdk: (doc unfold)

15:20 clojurebot: Titim gan éirí ort.

15:21 amalloy: pdk: clojure doesn't have unfold. that's why my gist implements it

15:22 zippy314: I'm getting this error:

15:22 java.lang.IllegalArgumentException: No matching method found: printStackTrace for class java.lang.RuntimeException

15:22 Shouldn't RuntimeException allways have printStackTrace?

15:22 amalloy: zippy314: you're probably calling it with arguments, when it should have none

15:22 zippy314: I only get that if I've set *er* to dev null

15:23 (catch Exception e

15:23 (.printStackTrace e *err*)

15:23 (str "ERROR: " e)

15:23 )))

15:23 hiredman: *err* is not of the right type to pass to .printStackTrace

15:23 amalloy: &(class *err*)

15:23 sexpbot: ⟹ java.io.OutputStreamWriter

15:24 zippy314: in my tests i'm:

15:24 (binding [*err* (writer "/dev/null")]

15:24 amalloy: it wants a printwriter, not a streamwriter

15:24 zippy314: ahh

15:24 amalloy: http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Throwable.html#printStackTrace%28java.io.PrintStream%29

15:26 zippy314: is there a way to create a printwriter through clojure.contrib.io?

15:27 because actually it's working until I do the binding [*err* (writer "/dev/null")] which overrides the standard err

15:27 amalloy: zippy314: looks like no

15:28 but ##(java.io.PrintWriter. (writer "some file")) should work (but i think sexpbot doesn't allow it

15:28 sexpbot: java.lang.Exception: Unable to resolve symbol: writer in this context

15:31 fliebel: Hrm, how comes these infinite cons constructions( ##(source take-nth) ) don't blow the stack, and mine does? https://gist.github.com/795374

15:31 sexpbot: java.lang.Exception: Unable to resolve symbol: source in this context

15:32 fliebel: &(clojure.repl/source take-nth)

15:32 sexpbot: java.lang.ClassNotFoundException: clojure.repl

15:32 Raynes: fliebel: Foiled by sexp!

15:33 tonyl: $source take-nth

15:33 sexpbot: take-nth is http://is.gd/N1aIyC

15:33 Raynes: That wont work either.

15:34 tonyl: why? it gave me the right source

15:34 Raynes: Oh, take-nth.

15:34 I thought you looked up the source to source.

15:34 * Raynes wipes his eyes.

15:34 defn: (require 'clojure.contrib.seq)

15:34 tonyl: oh never tried that

15:34 $source source

15:34 sexpbot: Source not found.

15:35 amalloy: fliebel: because the lazy seqs generated by take-nth are simple

15:35 defn: &(require '[clojure.contrib.seq :as s])

15:35 sexpbot: java.io.FileNotFoundException: Could not locate clojure/contrib/seq__init.class or clojure/contrib/seq.clj on classpath:

15:36 fliebel: amalloy: Please clarify. Does that mean that if I do take-nth on big enough numbers, ti will fail as well, or does it mean my cal is maintaining some stack space somewhere, while take-nth doesn't?

15:36 amalloy: fliebel: sorry, i was working on a clarification

15:37 fliebel: Take your time :)

15:39 amalloy: fliebel: basically, i think, the issue is the remove. you wind up building a chain of (remove (remove (remove (remove ...)))) and realizing them all at once?

15:40 fliebel: Bit take-nth is building chains of (drop (drop (drop))), so I'm not to sure about that.

15:41 amalloy: tbh it's still sorta black magic to me, and it *looks* like yours should work (cf the drop chain you mention), but my experience has taught me that remove/filter are usually to blame when a lazy-seq blows the stack

15:42 do you get a stack trace? it should be fairly clear what element is repeating

15:43 * defn wishes he didn't have a job so he could hang out in here like the olden days

15:43 fliebel: Yea, I had these stacking lazy problems before. But it seems stacks of something is the only way to make use of cons. I'm looking for the trace now

15:45 * fliebel realizes there exists both defn and devn :$

15:45 fliebel: amalloy: Yea, stack trace dominated by filter: at clojure.core$filter$fn__3714.invoke(core.clj:2130)

15:45 at clojure.lang.LazySeq.sval(LazySeq.java:42)

15:45 at clojure.lang.LazySeq.seq(LazySeq.java:56)

15:48 I don't care to much about why my version explodes, but I wonder why other functions *do* work.

15:49 amalloy: &(nth (take-nth 1 (range)) 1e5)

15:49 sexpbot: ⟹ 100000

15:49 amalloy: &(nth (take-nth 1 (range)) 1e6)

15:49 sexpbot: ⟹ 1000000

15:49 fliebel: I tried up to 1e8

15:49 amalloy: just testing that this is in fact the case

15:50 fliebel: Can we see a stack trace of a non-exploding function?

15:51 1e9 is running now ;)

15:51 amalloy: &(map #(if (= 1e5 %) (throw (Exception.)) %) (range))

15:51 sexpbot: java.lang.Exception

15:51 amalloy: fliebel: ^ for a stacktrace

15:52 fliebel: amalloy: But I'd have to raise the exception inside of cons to see what happens there.

15:54 It seems to consume stack up to sval, and that's it.

15:54 at clojure.lang.LazySeq.sval(LazySeq.java:47)

15:54 at clojure.lang.LazySeq.seq(LazySeq.java:56)

15:54 at clojure.lang.RT.seq(RT.java:450)

15:54 at clojure.core$seq.invoke(core.clj:122)

15:54 at clojure.core$drop$step__3728.invoke(core.clj:2177)

15:54 at clojure.core$drop$fn__3731.invoke(core.clj:2181)

15:54 at clojure.lang.LazySeq.sval(LazySeq.java:42)

15:54 ... 25 more

16:16 raek: sometimes, strategically placed 'doall' calls can solve the (f (f (f (f (f ...))))) problem

16:17 brehaut: raek: say what

16:17 raek: they eat stack because one forcing of a lazy seq element triggers another

16:21 hrm, I can't find fliebel's old mail list thread...

16:22 ,(nth (iterate #(map inc %) [1 2 3]) 1000000)

16:23 clojurebot: Execution Timed Out

16:23 raek: results in a stack overflow for me

16:23 ,(nth (iterate #(doall (map inc %)) [1 2 3]) 1000000)

16:23 clojurebot: (1000001 1000002 1000003)

16:24 raek: the only difference here is that now, forcing the first element of the seq does not tigger a cascade of realizations

16:25 I hope this made more sense... .-)

16:25 brehaut: raek: yeah it does

16:26 thats quite a sneaky gotcha really

16:30 raek: yup

16:32 * mefesto is really appreciating clojure.walk today

16:52 shortlord: how can I get a vector that is like another vector with one element somewhere in the middle removed?

16:52 there must be a better way than using 'into' and to subvecs, right?

16:53 raek: shortlord: this cannot be done in constant time. in the worst case, you need to traverse everything after the removed element (i.e. linear time)

16:53 shortlord: no, I think that's pretty much it...

16:54 shortlord: raek: phew, time is not important, the vector always has a length < 20

16:54 amalloy: shortlord: finger trees can do this in constant time

16:55 (they are basically 100% magic)

16:55 shortlord: amalloy: uh, nice, magic is always good

16:56 amalloy: or maybe they can't? i know they can split into a left tree and a right tree (without the element in the middle) in log time, but maybe stitching those two back together into a single tree takes more time

16:57 brehaut: shortlord: as an added bonus, the wizard has made video explaing his magic http://clojure.blip.tv/file/4614554/

16:57 clojurebot: #<RuntimeException java.lang.RuntimeException: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated>

16:58 hiredman: clojurebot: stop that

16:58 clojurebot: we can't stop here! this is bat country!

16:58 amalloy: brehaut: act now and you'll get...?

16:58 ossareh: lol @ clojurebot

16:58 brehaut: amalloy: in my case confision

16:59 chouser is clearly a couple orders of magnitude smarter than me

17:00 shortlord: brehaut: uh, nice. thx :)

17:03 zippy314: whats the idiomatic way of getting a subset of a hash, i.e. would be like (subset {:1 1 :2 2 :3 3} [:1 :3]) => {:1 1, :3 3}

17:05 hiredman: (doc select-keys)

17:05 brehaut: zippy314: (reduce dissoc myhash keys) ?

17:05 clojurebot: "([map keyseq]); Returns a map containing only those entries in map whose key is in keys"

17:06 brehaut: man what was i thinking. thats completely wrong.

17:10 zippy314: clojurebot: ? I'm being noob, I don't get it: (def x {:1 2 :3 4}) ([x [:1]]) => Wrong number of args (0) passed to: PersistentVector

17:10 clojurebot: XmL is case-sensitive

17:11 hiredman: (doc select-keys)

17:11 clojurebot: "([map keyseq]); Returns a map containing only those entries in map whose key is in keys"

17:11 zippy314: tx

17:15 tonyl: zippy314: wrapping a vector in parenthesis ([x [:1]]) makes it a function call. vectors are functions of their indexes ##([:a :b :c :d] 2)

17:15 sexpbot: ⟹ :c

17:16 zippy314: tx

17:16 * tonyl thinks that maybe indices makes more sense in programming then indexes ...

17:33 pdk: ,(boolean nil)

17:33 clojurebot: false

17:34 zippy314: ok, not understanding dosync and alter:

17:34 (def x (ref {:1 1})) (dosync alter x merge {:2 2})

17:34 I would have thought @x should now be {:1 1 :2 2}

17:34 but it's unchanged.

17:34 pdk: (dosync (alter x merge {:2 2}))

17:35 alter requires its own function call within the dosync

17:35 zippy314: zippy314 is slinking away embarassed

17:39 amalloy: zippy314: btw, if you change your def's to let's, you can use clojurebot/sexpbot to demonstrate to other people what behavior you're not understanding, like ##(let [x (ref {:1 1})] (dosync (alter x merge {:2 2})))

17:39 sexpbot: ⟹ {:2 2, :1 1}

17:40 zippy314: testing ##(let [x 1] x)

17:40 sexpbot: ⟹ 1

17:41 zippy314: (let [x 1] x)

17:41 #(let [x 1] x)

17:41 ##(let [x 1] x)

17:41 sexpbot: ⟹ 1

17:41 zippy314: Cool!

17:41 amalloy: zippy314: specifically, messages starting with , or & are interpreted by clojurebot and sexpbot respectively

17:41 and ## can be used anywhere in a message to activate sexpbot

17:41 zippy314: &(let [x 1] x)

17:41 sexpbot: ⟹ 1

17:41 zippy314: ,(let [x 1] x)

17:41 clojurebot: 1

17:42 zippy314: whats the difference between cojurebot and sexpbot?

17:42 amalloy: different authors, different feature sets, different...

17:42 zippy314: ah

17:43 brehaut: the biggest difference is that clojure-bot is part of big brother and hes recording everything you type

17:43 amalloy: $sed brehaut s/recording.*/watching over you

17:43 sexpbot: <> $sed brehaut s/watching over you

17:43 hiredman: well, actually my log is recording everything

17:43 amalloy: damn, i can never remember how that works

17:43 hiredman: and piping into sqs

17:44 amalloy: $help sed

17:44 sexpbot: amalloy: Simple find and replace. Usage: sed [-<user name>] s/<regexp>/<replacement>/If the specified user isn't found, it will default to the last thing said in the channel. Example Usage: sed -boredomist s/[aeiou]/#/Shorthand : s/[aeiou]/#/

17:44 amalloy: $sed -brehaut s/recording.*/watching over you

17:44 sexpbot: <brehaut> the biggest difference is that clojure-bot is part of big brother and hes watching over you

17:45 brehaut: hah

17:46 hiredman: https://github.com/hiredman/Howler

17:47 brehaut: hiredman: my immediate question is: Black Company?

17:48 hiredman: what about it?

17:48 brehaut: is that where the name is from?

17:48 hiredman: nope

17:49 joegallo: Maybe an x-files reference? http://x-files.wikia.com/wiki/Unruhe

17:50 hiredman: nope

17:50 it Howls at you over growl

17:50 brehaut: hah awesome

17:51 joegallo: I've got it, you're a big fan of the Pittsburgh bar scene. http://howlerscoyotecafe.com/

17:51 hiredman: joegallo: fine, I admit it, you caught me

17:51 joegallo: :)

17:55 Scriptor: does anyone know the name of the datastructure Clojure uses for hashmaps?

17:56 raek: persistent hash trie, iirc

17:56 brehaut: bagwell trie

17:56 Scriptor: ah, thanks!

17:56 raek: http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/

17:57 that one mentions "Array-mapped hash trie"

17:57 brehaut: also, doesnt the clojure implementation change the concrete type depending on the size of the map?

17:57 raek: in clojure-land, it is most often refered to as "persistent hash map"

17:58 yes

17:58 array-map vs hash-map

17:59 Scriptor: so the O(log32(N)) comes from the fact that it's stored as a sort of tree?

17:59 raek: yes.

18:00 Scriptor: man, I need to finish reading functional data structures

18:00 raek: if you won't read Krukow's articles, at least take a look at the pictures. they are pretty informative, I think... :-)

18:01 pdk: where are these articles

18:01 i know okasaki's book though this is news

18:02 Scriptor: hmm, I only have okasaki's thesis

18:02 raek: http://blog.higher-order.net/2009/09/08/understanding-clojures-persistenthashmap-deftwice/ and http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

18:03 Scriptor: raek: thanks!

18:11 dnolen: http://lampwww.epfl.ch/papers/idealhashtrees.pdf

18:33 arohner: has anyone tried reading from *in* or System/in when using slime?

18:35 amalloy: arohner: yes, it is known to be hard

18:35 arohner: amalloy: is there a solution?

18:35 amalloy: i don't know, actually

18:41 edoloughlin: Any ideas appreciated: I've run into the same issue with clj-record and clojureQl when trying to insert a record containing an int value. I get a classCastException and a message: "transaction rolled back: java.lang.Integer cannot be cast to clojure.lang.IFn".

18:42 hiredman: clojurebot: english?

18:42 clojurebot: English is the official language of the universe

18:44 raek: edoloughlin: does the stack trace tell you that the exception is thrown from within clj-record/clojureQl or from your own code?

18:45 edoloughlin: raek: By the time the exception gets caught in my code the stacktrace is null. I'm pretty sure it's not in my code.

18:46 raek: edoloughlin: null? have you tried to look at the causes of the exception?

18:46 edoloughlin: raek: it's null.

18:46 pdk: ,(for [i nil] (inc i))

18:46 clojurebot: ()

18:46 raek: I don't understand.

18:46 ,(throw nil)

18:46 clojurebot: java.lang.NullPointerException

18:47 raek: you cannot even throw null

18:47 edoloughlin: That's makes two of us. I get a ClassCastException with a message and no cause.

18:47 raek: what IDE?

18:47 edoloughlin: Eclipse/CounterClockwise

18:48 Line-by-line debugging is difficult in this environment

18:48 raek: ok, I'm an emacs guy, but have you tried (.printStackTrace *e) in the repl?

18:49 edoloughlin: I need to figure out how to get a REPL when debugging - new to this :(

18:49 raek: (perhaps that only works if you eval the expression in the repl, I don't know)

18:50 edoloughlin: Thanks anyway. I'll set some breakpoints in contrib.sql and see what I can find. At least it's not an obvious noob mistake...

18:51 raek: you should be able to get more details from the exception somehow

18:51 it should indicate the source lines for each call in the call stack

18:52 edoloughlin: Driving me nuts. Everything was tickety-boo until I tried to insert an int.

18:53 raek: you will get the same kind of exception if you do something like this:

18:53 ,(1 :a :b :c)

18:53 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

18:54 edoloughlin: Hmm. Don't think I've done anything that silly. Will have a quick check

18:57 raek: if you can launch your code from the repl, (.printStackTrace *e) should be sufficient to get the whole stack trace

18:58 the info you are looking for is without doubt in the stack trace

18:58 edoloughlin: Might be a bit tricky. It's all buried in ring/compojure

18:59 Is there a way I can invoke the repl from my code?

19:00 raek: edoloughlin: have you tried this? http://clojuredocs.org/ring/ring.middleware.stacktrace/wrap-stacktrace

19:00 edoloughlin: yes. calling your handler function directly.

19:00 edoloughlin: Ok. Will try. Thanks for the help

19:02 raek: (my-handler {:uri "/foo/bar", :request-method :get, :headers {}}) ; something like this maybe

19:02 oh, read your utterance backwards. that would anser the question "Is there a way I can invoke my code from the repl?"

19:07 edoloughlin: Think I've isolated the code. It's choking on what looks like a valid record.

19:11 raek: Found it. Noob mistake. Had (def someval 1) and was doing (assoc somerec :field (someval))

19:12 raek: Sorry for wasting your time with something so dumb.

19:24 nishant: is this the right place for questions on clojure-hadoop?

19:25 amalloy: nishant: i don't think there's a better place, but clojure-hadoop is not very up-to-date last i checked

19:25 oh, or maybe it is and i was thinking of clojure-cassandra. don't take my advice :P

19:27 nishant: amalloy: the version I'm using (1.3.1-SNAPSHOT) seems to work, I was able to build it, and also run the example 1 from a java command line, but I am running into problems when I try to run a job from a slime repl.

19:56 can I start "lein swank" with logging?

20:09 zakwilson: Mongo or Postgres... that is the question. Should I flip a coin?

20:18 danlarkin: zakwilson: that is a ridiculous question. do you choose between sandals and snow boots?

20:18 no, you use each when appropriate

20:19 zakwilson: Well, if I don't really know what the weather's going to be like and probably won't until I've been walking for a while....

20:20 danlarkin: there's your first mistake

20:20 how can you expect to make correct decisions then?

20:21 hiredman: ~google seattle weather

20:21 clojurebot: First, out of 2460000 results is:

20:21 Seattle, Washington (98101) Conditions &amp; Forecast : Weather ...

20:21 http://www.wunderground.com/US/WA/Seattle.html

20:22 zakwilson: I don't expect to make correct decisions. I think the best I can hope for is a lower probability of being wrong.

20:24 danlarkin: zakwilson: well if you want to just go hacking around then it doesn't really matter what you choose, does it? But if you want input on your decision (and I assume you do, since you asked in this public forum), then you really should be putting more thought into what data you want to model

20:24 david`: ,(let [ab-adder (partial concat [:a :b])] (ab-adder [:c :d]))

20:24 clojurebot: (:a :b :c :d)

20:28 zakwilson: Well, most of what I have to store will be in Clojure maps, for which MongoDB looks to be a good fit. I guess my real question is how good the respective Clojure libraries are. Both ClojureQL and CongoMongo look good at a glance with the former appearing a bit more mature.

20:30 danlarkin: well if your sole criteria is maturity then I don't think you can beat jdbc

20:33 symuyn: Does anyone know off the top of their head what the hash-function of vectors is?

20:35 zakwilson: It isn't. Fitting naturally with Clojure is a major criterion. The importance of maturity isn't linear; I don't mind something fairly new, but I don't want breaking changes every weak or significant unreliability.

20:37 danlarkin: then my (admittedly biased) opinion is to stay away from flavor-of-the-week datastores like mongro

20:38 and depending on your durability needs, you can just use clojure datastructures in memory

20:38 or contrib.datalog

20:42 zakwilson: I can do most of the interesting stuff with Clojure data structures in memory, but I want a place to put them, queries without loading everything in to memory, indexing...

20:43 hiredman: https://github.com/richhickey/sdb

20:43 if you are just hacking around, why bother with keeping your own database?

20:45 zakwilson: I'm building an API to provide a text classifier as a web service. I don't want it tied to a specific hosting platform though I can see where SimpleDB would save effort.

20:53 david`: did Stuart's clojure conj talk ever get posted?

21:03 danlarkin: zakwilson: you should check out http://www.infoq.com/presentations/Enterprise-NoSQL

21:03 zakwilson: danlarkin: thanks

21:16 mec_: If I have a regex that matches (.*=)?... is there a way to just return .* as in ((.*)=)? without the extra return in there as well

21:18 mefesto: (?:(.*)=)

21:18 mec_: non-capturing outer group but capturing the inner group

21:19 ,(re-find #"(?:(.*)=)" "key=val")

21:19 clojurebot: ["key=" "key"]

21:21 mec_: interesting so (?...) is non capturing group?

21:21 mefesto: (?:)

21:21 mec_: ah, thank you

21:21 mefesto: np

21:36 brehaut: david`: stuart halloway?

21:37 david`: http://www.infoq.com/presentations/Clojure-Java-Interop ?

21:47 symuyn: If I have a map whose keys are vectors, do the performances of assoc or get depend on the size of the vector keys?

21:52 tomoj: you have to compute the hash once for each vector to do those, I think?

21:53 and that requires hashing every element?

21:53 if you keep hold of the same keyset, the hash will always be cached

21:54 symuyn: Already, that makes sense

21:54 I mean, alright

21:55 tomoj: I don't know if that hashing actually takes long enough to matter anyway

21:56 symuyn: I'm thinking about the cost of memoization

21:56 Of a sort

21:56 (And by "of a sort", I mean "of a kind", not "of an ordering", heh heh)

22:09 mec_: ,(reduce (partial apply assoc) {} (map list [:a :b :c] [1 2 3]))

22:09 clojurebot: {:c 3, :b 2, :a 1}

22:09 mec_: is there a better way? there just has to be.

22:10 mefesto: ,(zipmap [:a :b :c] [1 2 3])

22:10 clojurebot: {:c 3, :b 2, :a 1}

22:11 mec_: well then, thats not at all what i thought that did

22:11 brehaut: mec_: is it possible you thought it was like haskell's zip but for maps?

22:12 mec_: I thought it had something to do with zippers, not sure why i didnt do a (doc) on it, i did on all the other map functions

22:13 brehaut: mec_: the reduce portion of your code is roughly 'into' btw

22:14 ,(into {} [[1 2] [3 4]])

22:14 clojurebot: {1 2, 3 4}

22:14 brehaut: thanks clojurebot

22:14 mec_: ah nice

22:14 brehaut: super handy

22:15 mec_: i forgot about conj over assoc too

22:16 al look at that into is even defined as (reduce conj)

22:16 brehaut: i live in fear of someone looking at some of my publicly available clj code and saying 'why did you do [big long mess]; you could just use [stdlib fn])

22:16 mec_: exactly, therefore my main assumption is there is always a better way to do whatever im doing

22:16 brehaut: mec_: yeah, + a transient

22:16 yup

23:23 being able to define monads dynamically is awesome

23:24 tomoj: are there monads in aleph?

23:25 brehaut: ive never looked at aleph

23:25 thats the event driven concurrency lib right?

23:28 replaca: david`: I don't think it's up yet. They're working their way through the two days in order

Logging service provided by n01se.net