#clojure log - Mar 16 2011

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

0:00 amalloy: brehaut, mec: https://gist.github.com/871993

0:00 a haskell port now that i remember the goal :P

0:00 brehaut: haha

0:00 amalloy: probably it's not at all lazy even though it looks like it

0:00 brehaut: amalloy: did you port break or span?

0:01 amalloy: shit i dunno. it looked like break

0:01 brehaut: damn stupid hoogle anchors

0:01 amalloy: oh i see

0:01 no i did span

0:01 brehaut: i think break is just the revser though?

0:01 amalloy: right

0:02 brehaut: yeah it is

0:02 amalloy: pretty sure this isn't lazy at all

0:02 but it's a start

0:02 mec: what does span do

0:02 amalloy: mec: span is split-with

0:03 i wrote span and called it break :P

0:05 mec: how isnt this lazy? it seems to work fine

0:06 amalloy: mec: it forces the whole first half of the input even if you never ask for the second half

0:07 brehaut: seriously, they had to note that the argument to reverse must be finite?

0:08 brehaut: pervasive laziness makes people a wee bit more precise :P

0:08 mec: It also causes a stack overflow if the pred takes too long to match

0:09 amalloy: s/precise/crazy. obviously you can't reverse an infinite seq

0:09 mec: sounds like a challenge to me

0:09 brehaut: but you can call reverse on it and carry a thunk around

0:09 that will explode somewhere else

0:10 cemerick: Am I missing something, or is this a comprehensive listing of canned cake plugins that are available? https://github.com/ninjudd/cake/wiki/Plugins

0:18 technomancy: cemerick: what's your take on archiva vs nexus? are they pretty close in functionality?

0:24 cemerick: technomancy: I'm afraid I've never really evaluated them in a comparative way. The only diff I noticed when making my decision was that (at the time, anyway) archiva didn't have as rich a set of permission controls. e.g. I wanted to be able to provide/restrict access to artifacts based on coordinate attributes, but archiva only offered permission controls per repo IIRC.

0:24 Nexus has always just worked for me, FWIW. There's a certain safety in going with the one made by the people that keep the keys to central et al. in any case.

0:24 technomancy: ah, good to know. nexus's UI is a little slicker, but I think we picked archiva at work primarily due to lexographic sorting.

0:25 cemerick: of search results, you mean?

0:25 technomancy: no, just lexographic sorting of the names

0:25 cemerick: oh, I see

0:25 technomancy: archiva is the undisputed winner in that regard

0:25 cemerick: I'm hoping that whatever is driving http://mavencentral.sonatype.com/ will get pushed into nexus at some point

0:26 technomancy: or the commercial nexus variant possibly

0:26 cemerick: bleh

0:26 I'm not sure I could bring myself to pay for a glorified web server, just on principle.

0:26 technomancy: in case you'd like to make your eyes bleed: http://docs.codehaus.org/display/MAVENUSER/Maven+Repository+Manager+Feature+Matrix

0:27 ah, p2 repository interop was one feature that I found interesting about nexus pro

0:28 technomancy: hm; that first link looks a bit nicer than jarvana

0:28 cemerick: technomancy: it's new in the last month; absolutely the way to go. It hits a "read slave" of the real central's index AFAIK.

0:29 technomancy: was using http://mvnrepository.com/ for a while, but the slowness+downtime pushed me away really quick

0:29 ly

0:29 thanks for the pointer

0:29 cemerick: ah, the one with the absolutely killer charting! :-P

0:29 technomancy: I need to look into how those repos offer downloadable lucene indices; that sounds really handy

0:29 see if we could get clojars offering that

0:30 cemerick: it does

0:30 Or, eclipse is acting as if it does.

0:30 technomancy: eeeeenteresting

0:30 wonder when that happened

0:31 new features don't make it into clojars very often

0:31 cemerick: it's been there from the start

0:31 http://clojars.org/repo/.index/

0:31 AFAIK, anyway

0:31 I remember talking with ato about it a looong time ago.

0:32 technomancy: no kidding... thanks again for the pointer.

0:32 cemerick: np

0:32 * cemerick is 2/2 so far!

0:32 cemerick: gotta work up out of that karma hole I've been in

0:33 technomancy: I see generalized deployment is in lein now, or imminent…

0:33 that's big news

0:33 technomancy: yeah, I'm thinking of making a pallet crate for nexus or archiva

0:34 since it's a very common need

0:34 joining the Big Kids now =)

0:34 cemerick: I wonder if that makes it a good time to open up the notion of a less mosh-pit-esque community repo.

0:35 technomancy: how have the sonatype free repos been treating you?

0:35 gilicorn: sup

0:35 phenom_: hmmm in multimethods is there a way to do a conditional match? "defmethod my-test (or :key1 :key2) [...] .." ?

0:35 cemerick: technomancy: the setup takes a day of waiting and an initial vetting of your first deployment, but it's now zero-admin

0:36 gilicorn: pls send warez / serial numbers to x6763@gmail.com

0:36 thx

0:36 amalloy: phenom_: you want isa/hierarchies

0:37 that was such an honest, touching request. i can't help but find warez for him

0:37 cemerick: I'm just reusing the new-contrib deploy-to-OSS+central POMs as parents of my public Clojure projects, which makes the actual project setup roughly zero-config as well.

0:37 technomancy: cemerick: I'm also in the middle of adding the ability to specify a repository as snapshots-only or releases-only, so adding new repos won't necessarily slow things down much in the future.

0:37 cemerick: I don't think a Clojure community repo needs anywhere near the sort of administrativia as Sonatype has around OSS, FWIW.

0:37 technomancy: sure

0:38 cemerick: Honestly, clojars has just a couple of off-by-one issues. I'm not sure it'd make sense to change policies in-place though.

0:39 technomancy: the two problems are groupids are first-come-first-served and the lack of the snapshots/releases distinction, right? the latter being more serious in practice?

0:39 the former is easy to solve with a more active admin team, I think

0:40 cemerick: groupIds are *always* first come first serve, even in OSS/central

0:41 technomancy: true, but for non-central repos there's a chance that someone could take a groupid that's been claimed on central.

0:41 but yeah, that's much less of an issue

0:41 I'd be perfectly happy with making lein 2.0 point to a clojars releases-only repo

0:42 just gotta do it during a breaking change

0:42 cemerick: good point. I'm guessing we wouldn't worry about aligning with central's policies or names though. Central sync from a third-party repo is absolutely onerous, which is what prompted the OSS setup.

0:43 technomancy: this is the part where "I told you so" is perfectly ok. =)

0:43 cemerick: the biggest issues IMO are the common practices of (a) deploying slightly-patched artifacts under org.clojars.username, (b) using clojars as a personal scratchpad e.g. deploying artifacts that aren't in central into clojars just because *your* project needs it, and…

0:44 crap, lost my third item.

0:45 technomancy: making it easy to set up private nexii might help with b

0:45 cemerick: Anyway, the snapshots/releases thing is minor relative to those IMO. It screws up some features for downstream tooling, which sucks, but not being able to reasonably identify the authoritiative artifact for a particular project can be soooo painful.

0:46 technomancy: http://cemerick.com/2010/08/24/hosting-maven-repos-on-github/ was my feeble attempt at solving (b)

0:46 not that I tried *that* hard

0:46 technomancy: maybe clojars could even relegate org.clojars.foo artifacts to a separate "mosh-pit" repository that's separate from snapshots/releases too

0:47 but it's cultural; if a real release depends on a mosh-pit release you're contaminated =\

0:47 cemerick: There was a fellow around here at some point that was tinkering with the idea of offering nexus hosting a la paid git or svn hosting.

0:48 technomancy: revisiting the lein tutorial I was sure to make very clear the org.clojars route is a last-ditch measure for when you just can't make it work with upstream.

0:48 cemerick: The whole org.clojars.foo notion is nonsensical to me though. That's not a "proper" groupId, it's just UUID scheme.

0:49 "a UUID scheme" that is.

0:49 technomancy: so are you seeing real releases that depend upon org.clojars artifacts?

0:49 cemerick: I have, yeah.

0:49 waxrose: Do you all add JLine support if so, what exactly is it's purpose?

0:49 technomancy: that's a shame. I've only seen it for internal use ಠ_ಠ

0:50 waxrose: it's for when you don't have rlwrap installed

0:50 waxrose: rlwrap is better in every regard except for the fact that it's not a JVM-level dependency.

0:50 tomoj: for private nexus and lein, is there settings.xml wrangling required?

0:50 cemerick: it became very common around the time that 1.2.0 was released, and a lot of libraries were lagging in the transition

0:50 technomancy: tomoj: no, it's all in project.clj

0:50 tomoj: whew

0:50 waxrose: technomancy, So it's suggested to go with rlwrap instead then?

0:51 technomancy: cemerick: oh, I could see that. shame that people couldn't work with upstream!

0:51 tomoj: got it working with settings.xml but I knew there had to be a more leinish way

0:51 technomancy: waxrose: absolutely

0:51 amalloy: waxrose: 100%

0:51 technomancy: lein 1.5 will issue a one-time warning if it has to fall back to jline in rlwrap's absence

0:51 waxrose: technomancy, Okay, thanks!

0:51 I think I'm using an old installation guide. :/

0:52 cemerick: technomancy: if there's a fast-path available, people will take it. fix,build,scp is *way* quicker and easier than fix,build,diff,email/pull-req,wait,wait,wait,get-new-release

0:52 amalloy: waxrose: just install cake and use cake repl; it bundles readline. lein probly does too

0:53 waxrose: amalloy, Alright, I'll try that. I was testing lein first before I decided without is easiest to get started with.

0:53 which one*

0:53 amalloy: going without lein/cake is *not* easier

0:53 ah

0:54 haha

0:54 waxrose: lol

0:54 Sorry, I type too fast and often typo.

0:54 amalloy: too fast, i see. are you using windows or something crazy like that?

0:54 waxrose: Ubuntu.

0:54 amalloy: cool beans

0:55 sudo gem install cake, cake repl

0:55 waxrose: I was using Arch but it seemed like it would be easier to set up GAE and Clojure on Ubuntu.

0:56 gem? Ruby?

0:56 amalloy: yeah

0:56 cake uses ruby like lein uses bash

0:56 as i understand it

0:56 ie, as a launching pad for all the core clojure goodness

0:56 tomoj: huh, I wonder if the ruby API lets you do cool cake stuff from ruby easy

0:57 waxrose: Interesting, that may be a little easier to start from since I actually left Ruby to for Clojure.

0:57 for*

0:58 Thanks for explaining further.

1:00 technomancy: gem install on ubuntu doesn't work quite right

1:00 cemerick: rich talked to me at emerginglangs about fork-aware dependency resolution

1:01 cemerick: technomancy: anything sane emerge from that?

1:01 it's a tough problem

1:01 technomancy: I think with aether there's the flexibility needed to resolve that sanely so you could tell given a sha what's newer and how to specify a preference, but I haven't thought it all the way through.

1:01 you need a third-party DAG

1:01 cemerick: so, roughly, try to overlay the git and mvn trees?

1:02 technomancy: err--a separate metadata repository for source DAG

1:02 and each pom needs to be clear about scm

1:02 right

1:02 cemerick: yeah, that previously extraneous pom metadata suddenly seems *way* more important

1:02 technomancy: very half-baked in my head right now, but it could turn into something useful

1:03 though of course the "just don't publish forks" approach has its allure too.

1:03 cemerick: yeah

1:04 the semver approach that mvn essentially relies upon and trees don't really mix

1:04 technomancy: I guess clojars forks are like using robert hooke; you only do it if you have to, and you never foist in on anybody downstream of you.

1:05 cemerick: The thing is, even if fork-aware dep mgmt were made to work, nothing else in the toolchain would know what to do with it.

1:05 e.g. hudson, elastic beanstalk .war versioning, etc etc etc

1:06 technomancy: actually, scm-aware dependency resolution isn't just about forks; it's also useful to distinguish between 1.2.0-newnew and 1.2.0-alpha, etc

1:06 back when we had those specifiers

1:06 cemerick: yeah, same thing conceptually

1:06 technomancy: yeah, that's another issue

1:06 one step at a time though

1:07 cemerick: I'd suggest pinging jvanzyl et al., but it's hard to push on that rope.

1:07 technomancy: if you could gen-class up the kind of resolution plugin that aether needs it might be easy to share

1:08 yeah... I'll give it some more hammock time for sure. we'll see.

1:10 cemerick: The git and hg folks must have done some thinking about this as well. Everyone runs into the impedance mismatch eventually.

1:10 technomancy: it could be git people are too mired in autotools to come up for air

1:10 cemerick: hah

1:11 technomancy: and python has like three separate package managers, so they've got more pressing things to deal with maybe.

1:12 ruby had issues for a while where people were publishing $GITHUBUSER-$GEMNAME gems, but I think that got nipped in the bud before anyone was forced to come up with a clever solution.

1:15 cemerick: And that's all nothing compared to the trainwreck in the .NET world.

1:16 Every time I need to screw with dependencies in VS, I want to simply burn and die.

1:24 waxrose: hmm to rlwrap adds tab completion, param matching, and even emacs bindings?

1:24 sweet

1:24 so*

1:25 technomancy: tomoj: hang on; you're deploying to nexus using lein deploy and using settings.xml?

1:25 I didn't know that would actually work. =)

1:26 tomoj: not deploying

1:26 ..hadn't tried that yet. just the fetching of deps

1:26 technomancy: oh, passwords for downloading have worked for a while

1:27 tomoj: no passwords either

1:27 waxrose: technomancy, Would you happen to know of any current, active Clojure oriented projects working with Firefox Fennec on Android?

1:28 technomancy: waxrose: there is only one clojure project on Android, a repl

1:28 it has a loooooong way to go before it's viable for general-purpose apps

1:28 waxrose: hmm

1:28 technomancy: tomoj: so just listing a non-authenticated repository?

1:28 tomoj: seems now that :omit-default-repositories and putting only nexus in :repositories should be enough.. dunno if I tried that, or why I wouldn't have

1:28 technomancy: tomoj: heh. =)

1:28 well if you do have use for the deploy task let me know if it works for you.

1:29 haven't had anyone else report back on that yet.

1:32 amalloy: waxrose: i don't imagine you want it, but readline also has a vi mode

1:33 technomancy: tab completion is doable but not so great in rlwrap; param matching is impossible. you need something like slime for that.

1:37 waxrose: amalloy, Wouldn't hurt to check it out though. I didn't even realize it had a vi-mode. >.>

1:38 amalloy: readline is impressive

1:39 waxrose: Wait, don't you go into vi mode with ctrl + alt + j?

1:40 amalloy: waxrose: looks like you can put the following into ~/.inputrc: set editing-mode vi

1:40 waxrose: set -o vi .....i believe, it's been a while since I've used vi[m] ... that would probably drive me crazy though

1:41 amalloy: yeah

1:41 my goal is in fact to drive you crazy, so

1:41 waxrose: Good, I love the taste of insanity at 12:41am.

1:42 amalloy: where on the east coast?

1:42 waxrose: I'm in Texas actually.

1:43 amalloy: oh right, east coast is 1:41

1:43 waxrose: Yeah, Chicago time.

1:43 amalloy: but is texas really two time zones out? i guess i'm clueless

1:43 apparenlty it is

1:43 waxrose: Where are you, Cali?

1:43 * amalloy stays on the west coast being clueless

1:43 amalloy: yeah

1:44 (more specifically, afk in cali. brb)

1:44 waxrose: Yeah, I have family from Riverside / San Deigo.

1:45 tomoj: shit, when you said 12:41am I thought "glad I'm not in that timezone"

1:45 waxrose: lol

1:45 Why's that?

1:45 tomoj: I am in fact in that timezone

1:45 didn't realize it was so late already

1:45 waxrose: hahha

1:45 Crazy huh?

1:46 My window manager does not display time by default so I often lose track of time. So don't feel too bad.

1:47 technomancy: yeah, I only see the clock in my tmux status bar

1:47 and the server I run my IRC tmux session in is in UTC, so who knows...

1:47 waxrose: eek

1:48 I've been meaning to add some thing to StumpWM to actually remind me what time it is.

1:49 technomancy, Are you planning on attending Clojure Conj?

1:50 technomancy: waxrose: yeah, sure.

1:50 hopefully I can relax and not speak this time.

1:51 waxrose: I'm going to attend for sure. Were there a lot that attended last year?

1:51 technomancy: about 200. a lot for a first-year conference I guess?

1:53 * technomancy wonders how big ILC is

1:53 waxrose: Not bad for a first year. I just like to meet every body from the community that I can so, I probably would have just as much if only 50 people showed up.

1:53 as much fun*

1:53 amalloy: waxrose: it's tough to have a good clojure party with 200 people all at once, is why. 50 at a time is plenty :)

1:53 waxrose: Ruby Conf in Austin last year only had about 280.

1:53 technomancy: I'm hoping it can extend to three days this year.

1:54 waxrose: it actually felt a lot like RubyConf 05

1:54 waxrose: amalloy, Lol, yeah. Just add some alcohol.

1:54 technomancy: back when not everyone was getting paid to hack in it.

1:56 waxrose: I'm not exposed to a lot of non .net developers where I live so I'm always excited to meet people from different communities.

1:57 technomancy, I imagine that makes a big difference. Less greed and more passion.

2:21 technomancy: yeah, it's not as bad with rubyconf vs railsconf though

2:22 waxrose: I've never been to a Rails Conf, but I hear it's hectic.

2:26 tomoj: I'm just glad I got to see ze :)

2:27 waxrose: ze?

2:31 tomoj: ze frank

2:32 waxrose: oh, duh

2:32 :P

2:36 tomoj, I remember his ted talk, was quite funny.

3:18 tsdh: Moin!

3:20 In a deftest, I have something like (= (time (eval1)) (time (eval2))). eval2 might return a lazy seq. Am I correct that the timing will be wrong in that case, when I mean wrong in terms of "doesn't calculate everything"?

3:24 tomoj: &(let [x (time (range))])

3:24 sexpbot: ⟹ "Elapsed time: 0.455126 msecs" nil

3:25 tomoj: guess that's not too illuminating

3:25 yes, you're right

3:25 tsdh: Yeah, I expected that. So I need to do something like (let [r (eval2)] (if (instance? LazySeq) (doall r) r)), right?

3:26 I do that in a macro. How do I write the variable r there? I mean, what's the common lisp `gensym' in clojure?

3:27 tomoj: I don't really understand what you're trying to do. but, we have gensym as well, and also "auto-gensyming": in a macro, names with # at the end will be gensymed

3:28 &`foo#

3:28 sexpbot: ⟹ foo__10853__auto__

3:29 tsdh: tomoj: Thanks, that's what I have looked for. :-)

3:30 tomoj: what's `'s name?

3:30 'symbol quote"?

3:35 tsdh: I have this working macro: http://pastebin.com/bUp2Un6t

3:35 How would I go to extend it to receive arbitrary many funqls, where the expansion contains the second `do' for each of them?

3:55 Nearly got it.

3:59 What's wrong with ~(map quote forms) in a macro?

4:00 I get error: java.lang.Exception: Unable to resolve symbol: quote in this context

4:00 tomoj: quote is a special form

4:01 tsdh: And forms would be evaluated before passing to quote anyway...

4:02 tomoj: maybe '~forms ? dunno

4:28 tsdh: Hm, now I got it that the expansion looks ok, but when executing the tests defined with my macro, it seems I have namespace issues. Probably, because I eval the forms... http://pastebin.com/TLU0M5zL

4:28 Any ideas how to do that in a better way?

4:55 ZabaQ: there's a cheatsheet somewhere that maps clojure to common lisp equlvalent functions/specials - I can't find it anymore, anybody have an url?

4:58 angerman: ZabaQ: apart from http://clojure.org/lisps, don't know.

5:05 raek: tsdh: first, do you really need eval there?

5:05 tsdh: raek: Did you check the mailinglist? There I've posted the complete code and the problems/errors.

5:05 raek: I think it would be a better idea to generate (fn [] ...) forms and call them inside the (time ...)

5:06 * tsdh tries that...

5:07 raek: the code you give to eval is not evaluated in the lexical scope of the eval call, but at the top level

5:07 angerman: anyone can lend me a hand with defmulti? … it fails to dispatch right :(

5:07 https://gist.github.com/872217

5:07 The error i get is: No method in multimethod 'depth-comp' for dispatch value: [geometry.renderer.Edge geometry.renderer.Point]

5:09 raek: tsdh: (doseq [funql-fn# ~(for [funql funqls] `(fn [] ~funql))] ... (let [r# (funql-fn#)] ...

5:10 angerman: are the objects you pass in records?

5:10 angerman: yes

5:11 raek: type returns a class in this case, and the multimethod looks for keywords

5:11 angerman: if I write out the full name geometry.rernderer.Point and …Edge it does work.

5:11 reak is there any "better" way to implement that?

5:11 reak: and can I turn a mutli-method into a comperator?

5:11 raek: angerman: you can (:import (geometry.rernderer Point Edge)) and then use the shorter names

5:11 tsdh: raek: Thank you.

5:12 angerman: reak they are defined in the same file…

5:13 raek: imports of classes behaves differently from vars in namespaces

5:13 angerman: reak ok

5:13 raek: you can do a (import '(geometry.rernderer Point Edge)) after the defrecord (since the classes does not exist before)

5:14 ...with correct spelling, of course. :)

5:15 angerman: raek: thanks. Hm. And can I turn a multimethod into a comperator_

5:16 raek: hrm

5:16 ,(defmulti foo type)

5:16 clojurebot: DENIED

5:16 raek: &(defmulti foo type)

5:16 sexpbot: java.lang.SecurityException: You tripped the alarm! def is bad!

5:16 tsdh: raek: Now I get java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$fn--732$fn

5:17 raek: tsdh: oops.. what does the macro expansion look like?

5:17 oh

5:17 the ~(for ...) becomes ((fn [] ...) (fn [] ...) ...)

5:18 make it ~(vec (for ...))

5:18 then the generated code will be [(fn [] ...) (fn [] ...) ...] instead, and it won't try to call the first fn with the rest as arguments

5:21 angerman: doesn't look like multimethods implement Comparator, but ordinary fns do

5:21 tsdh: raek: Yes, that works. Thanks a lot!

5:21 angerman: raek: I think (comparator multi-fn) works… will have to experiment.

5:47 bennylu: hi, i want to embed a clojure repl to my java program - is there any class in clojure that can start an embeded repl?

5:50 clgv: bennylu: clojure.main/repl starts a repl

5:51 bennylu: clgv, thanks i look into it

5:51 clgv: but probably you will have to build a wrapper for it

5:52 bennylu: clgv, its ok all i wanted is some sort of repl that connected to my program (hance can control it) and that i can connect to it in some way so that ill be able to let my users use it

5:53 clgv: fine :) I just think I needed to mention that it might still be some work

6:08 ZabaQ: has iterate been ported to clojure?

6:09 clgv: bennylu: I found something interesting - a swing repl. it is in the cljr project https://github.com/liebke/cljr

6:13 oh well, cljr only installs it. the swing repl is from here: https://github.com/alandipert/clj-swingrepl

6:22 thorwil: i have [net.cgrand/moustache "1.0.0-SNAPSHOT"] in my project file, did "lein deps", the .jar is in lib, is use (:require [net.cgrand.enlive-html :as html]), but: java.io.FileNotFoundException: Could not locate net/cgrand/enlive_html__init.class or net/cgrand/enlive_html.clj on classpath

6:23 what's the silly detail i must be forgetting?

6:29 tsdh: Is pmap guaranteed to deliver the same result as map with respect to the order?

6:30 opqdonut: yes

6:30 afaik

6:30 https://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L5426 <- there's the source

6:31 as you can see by the "rets (map #(future (f %)) coll)", it works just like map, but evaluates the result later

6:33 tsdh: Hm, ok.

6:33 tomoj: thorwil: hmm, do you see the enlive jar in (System/getProperty "java.class.path") ?

6:33 thorwil: "lein classpath" tells me that enlive-1.0.0.jar is on my classpath.

6:34 angerman: http://dl.dropbox.com/u/281539/schwarz-lantern.pdf // Schwarz Lantern (clojure via TikZ)

6:34 hmm. well. It's written in clojure but compiles to tikz for rendering.

6:34 tomoj: thorwil: I assume you started the jvm the error occurs in after running `lein deps`?

6:36 thorwil: tomoj: i suspect that is the silly detail i was looking for. thank you! :)

6:37 indeed

6:37 tsdh: Is there a way to compare 2 seqs without respect to ordering?

6:39 I mean, (= (into #{} s1) (into #{} s2)) would nuke duplicates, which I don't want...

6:39 tomoj: another perhaps almost equally distateful way is to sort both

6:40 tsdh: tomoj: Yep. Hm, I can define equals-no-order which checks the count and if that is true, converts to sets, right?

6:40 tomoj: (btw (set coll) is probably better than (into #{} coll))

6:40 tsdh: Yep

6:40 tomoj: if you're OK with [1 1 2 3] and [1 2 2 3] being equal..

6:41 tsdh: Oh, I'm not. :-(

6:42 Then sorting by natural order would be the right way, I think.

7:00 Hm, sorting doesn't work, if the seq contains other (lazy) seqs, cause these don't implement comparable... (sort (map (fn [x] (lazy-cat x x)) [1 2 3 4 5]))

7:01 Hm, sorting doesn't work, if the seq contains other (lazy) seqs, cause these don't implement comparable... (sort (map (fn [x] [x x]) [1 2 3 4 5]))

7:01 Ups, sorry.

7:05 tomoj: hmm

7:06 you want, say, '((1 2 3 4) 5 6) and '(5 4 (3 4 2 1)) to match?

7:06 er, '(5 6 (3 4 2 1)) for the latter

7:07 or only '((1 2 3 4) 5 6) and '(5 6 (1 2 3 4)) ?

7:07 tsdh: yes

7:08 The former

7:08 tomoj: and arbitrarily deep?

7:09 tsdh: If possible, yes.

7:09 Oh, wait.

7:09 tomoj: I suppose I'm leading you on as I have no clue really

7:09 just trying to establish how difficult exactly :)

7:10 tsdh: I think, I will be comparing seqs of tuples (also seqs), and the order of the surrounding seq should be ignored.

7:10 So: ((1 2) (3 4)) = ((3 4) (1 2)), but ((1 2) (3 4)) != ((4 3) (1 2))

7:12 tomoj: does (= (frequencies x) (frequencies y)) work, then?

7:14 * tsdh is testing...

7:14 tomoj: perhaps not the best solution even if so

7:14 tsdh: It does!

7:15 Well, it's only in my test suite, so I can live with possibly not too good performance, as long as it is correct.

7:16 tomoj: Thanks a lot.

7:26 angerman: are there any limitations on resolve? does it need a repl?

7:27 clgv: angerman: what do you mean?

7:28 angerman: I'm trying to resolve a function from a glued together symbol

7:29 (resolve (symbol (str some-symb "/create")))

7:29 and it returns nil :/

7:29 clgv: ok.

7:30 I think resolve does not load require namespaces for you

7:30 angerman: the namespace is loaded.

7:30 clgv: you have to "use" or "require" them before

7:31 angerman: does *ns* get bound specially in the repl?

7:31 hmm… if I (:require … :as some)

7:32 I cannot (resolve "some/symb")?

7:34 https://gist.github.com/872353

7:34 here's what I try to do

7:34 L33F

7:36 but resolve just returns nil for 'cube/create as well as for the algorithm. even though it's (use imported)

7:39 clgv: hmm 'cube is no string how does that evaluate? ##(str 'cube)

7:39 sexpbot: ⟹ "cube"

7:39 clgv: oh kk

7:41 tomoj: (resolve 'some/symb) seems to work fine

7:41 angerman: tomoj: on the repl… yes.

7:42 clgv: I guess the compiler remebers the alias when you use it directly

7:42 so it cant handle the indirect approach via strings

7:44 angerman: you could write a macro that appendes the complete namespace automatically so that you dont need to use it everytime

7:44 tomoj: hmm, I have equal success outside the repl

7:45 with e.g. (resolve (symbol "clojure.java.io/resource")) in an ns that requires clojure.java.io

7:46 similarly with (:require [clojure.java.io :as jio]) and (resolve (symbol "jio/resource"))

7:49 angerman: hmm.. so whats wrong with my code? … hmm.

7:53 clgv: spoke the programmer right before the cpu meltdown ;)

7:55 angerman: clgv: fixing with liquid cooling...

8:26 yikes… some bugs are /really/ hard to track down.

8:31 waterbuffalo: lol: (time (apply + (range 100000000))) = 5400 msec

8:31 (binding [+ unchecked-add] (time (apply + (range 1000000000)))) results in crash: out of memory

8:32 :(

8:32 chouser: &(= 100000000 1000000000)

8:32 sexpbot: ⟹ false

8:33 waterbuffalo: deleted one zero

8:33 same exception lol

8:34 chouser: I like 1e8 syntax for this sort of thing

8:34 ,1e8

8:34 clojurebot: 1.0E8

8:34 chouser: oh. heh.

8:34 waterbuffalo: besides I clearly shouldn't run out of memory...I think

8:34 chouser: waterbuffalo: I suspect the performance difference between checking for overflow or not will be overwhelmed by the boxing and unboxing going on there.

8:35 waterbuffalo: I heard something about not holding on to sequence head once

8:35 chouser: waterbuffalo: but you can try reduce instead of apply and see if that avoids the memory error.

8:35 waterbuffalo: but I can never tell when I'm doing that

8:35 trying reduce

8:36 chouser: waterbuffalo: this is Clojure 1.2 ?

8:36 waterbuffalo: yes

8:36 clgv: angerman: you found it?

8:36 chouser: waterbuffalo: unchecked-add only takes 2 args. It's not varargs like +

8:37 waterbuffalo: reduce seems to fail also

8:38 chouser: waterbuffalo: I think Clojure is trying to realize the entire range before checking to see if unchecked-add can take all those args. In the apply case, I mean.

8:38 I'm surprised reduce doesn't work.

8:38 clgv: &(binding [+ unchecked-add] (time (reduce + (range 100000000))))

8:39 sexpbot: Execution Timed Out!

8:39 clgv: &(binding [+ unchecked-add] (time (reduce + (range 1000000))))

8:39 sexpbot: Execution Timed Out!

8:39 chouser: try 1e5

8:40 waterbuffalo: well reduce hasn't crashed yet

8:40 its still running

8:40 clgv: the reduce version isnt allocating an increasing amount of memory as htop shows

8:40 tomoj: why is the version with the binding 170x slower?

8:40 chouser: I don't excpect unchecked-add to be much (any?) faster than + when used this way.

8:41 tomoj: I wouldn't expect inlining to help here..

8:41 waterbuffalo: it's burning it's core to the max :P

8:41 well + did it in 5 sec

8:41 chouser: accessing thread-locally-bound vars is slower than accessing root bindings

8:41 waterbuffalo: with binding it has been more than a minute and still not finshed

8:41 tomoj: ah

8:42 waterbuffalo: so there's no easy way for me to convert whole programs to unchecked arithmetic

8:42 tomoj: waterbuffalo: huh, seems like your jvm is 250x slower than mine somehow

8:42 clgv: waterbuffalo(binding [+ unchecked-add] (time (reduce + (range 100000000))))

8:42 waterbuffalo: how do you reckon?

8:42 clgv: ups sorry

8:42 tomoj: I get 20ms with +, 4s with the rebinding

8:43 clgv: you could use clojure.core/alter-var-root

8:43 tomoj: on a relatively shitty netbook

8:43 chouser: bleh. what are you even trying to do?

8:43 clgv: but then you have no checked adds anymore

8:43 waterbuffalo: I'm using core i7

8:43 tomoj: i5 here. odd

8:44 oh

8:44 waterbuffalo: oh shit..... it's stupid IBM JVM

8:44 tomoj: I was doing it with 1e5

8:44 waterbuffalo: I've noticed that sun JVM is faster than IBM one for clojure

8:46 chouser: &(time (let [x (long 1e8)] (loop [i (long 0), a (long 0)] (if (< i x) (recur (inc i) (+ i a)) a))))

8:46 sexpbot: ⟹ "Elapsed time: 995.548407 msecs" 4999999950000000

8:46 clgv: when using doubles you also have to check that you are running a 64bit JVM. occured to me when running my program on windows with 32bit jvm ;)

8:46 chouser: &(time (let [x (long 1e8)] (loop [i (long 0), a (long 0)] (if (< i x) (recur (inc i) (+ i a)) a))))

8:46 sexpbot: ⟹ "Elapsed time: 833.750908 msecs" 4999999950000000

8:46 waterbuffalo: why clgv?

8:47 chouser: &(time (let [x (long 1e8)] (loop [i (long 0), a (long 0)] (if (< i x) (recur (unchecked-inc i) (unchecked-add i a)) a))))

8:47 sexpbot: ⟹ "Elapsed time: 593.003624 msecs" 4999999950000000

8:47 clgv: I think JVM doubles are emulated on 32Bit machines. thats the only explanation I can think of

8:47 chouser: That's how to write fast loops in Clojure 1.2

8:48 waterbuffalo: chouser, that why I tried binding...not only is replacing all + with unchecked calls in my programs annoying as hell, I would also have to do it for core library functions

8:48 like range

8:48 chouser: but the boxing is going to hurt much more than the overflow checking

8:49 clgv: waterbuffalo: unchecked-add is no holy water. I checked at a lot of code pieces and it didnt even speed up those

8:49 waterbuffalo: chouser: I know that loop recur is the fastest way...but it produces butt-ugly code, even more so than java's iterative constructs

8:50 chouser: Using binding like this isn't going to get you better performance.

8:50 waterbuffalo: clgv it usually shaves 33% off your arithmetic operations

8:50 I can see that :D

8:51 clgv: what I meant is that I doubt that replacing it everywhere will do that much impact. Just use it where you have your performance bottlenecks

8:52 waterbuffalo: that's why I loved the binding idea

8:52 the ability to dynamically specify what to do :)

8:54 fliebel: Are there any people in here with a good understanding of Sudoku and Clojure? I wrote this solver https://gist.github.com/871708 , but for the hard board it does not come up with a complete solution. Does this mean the board has multiple valid solutions, or that my solver is to simple?

8:55 chouser: fliebel: Everything I know about sudoku solvers I learned here: http://blog.n01se.net/?p=12

8:55 clgv: fliebel: hard boards often have multiple solutions

8:55 fliebel: chouser: Thanks, will read.

8:56 waterbuffalo: yeah generally with sudoku, if you have a few empty places, just do a depth first search

8:57 clgv: the trick is to restrain possibilities and derive field values as long as you can. then you can simply pick a random of the valid values in e.g. the most restrained field

8:57 fliebel: Hm, okay, so that means just assuming a number and trying if it works.

8:57 waterbuffalo: yes

8:58 clgv: almost. It will definitiely work if you derived all constraints correctly

8:58 waterbuffalo: you choudl conceiveably do this with empty board

8:58 fliebel: clgv: Well, I checked the solution, and my partial solution at least contains the give one.

8:59 clgv: mathematically speaking you'll have a hyper plane of solutions (multiple) at the point where you can't restrain the possibility sets anymore

8:59 fliebel: right, I need more math :)

9:00 chouser: Or a carefully constructed regex. :-)

9:00 fliebel: chouser: I like that idea...

9:00 chouser: fliebel: follow that link

9:00 fliebel: chouser: I'm reading :)

9:01 clgv: fliebel: if you are sure that all constraints apply and you cant restrain possibilities anymore, just pick a random value in one of the most restrained fields

9:04 or you could try for every possible value left to get to all possible solutions

9:04 fliebel: clgv: :)

9:05 waterbuffalo: what are you using for fields? type from deftype?

9:06 clgv: for sudoku in a plain functional style I'd use a set for every field

9:06 fliebel: waterbuffalo: sets indeed

9:07 waterbuffalo: :)

9:07 clgv: in OOP versions they use custom classes with signaling-like functionality to avoid overhead in applying constraints to fields

9:07 waterbuffalo: it'd use type to also have info about the column, row

9:08 clgv: you can put the sets in a grid and dont need the info about column and row then ;)

9:08 fliebel: I did consider to use something like an atom, to save me from the folding and unfolding of the rows, collumsna dn especially the blocks.

9:09 waterbuffalo: interesting...maybe have each field have a bunch of listeners registered on it

9:09 fliebel: waterbuffalo: listeners? why? to make them update their neighbors?

9:10 clgv: it doesnt have to be listeners. it could be just updating counters when it is changed with these counters being organized in a priority queue

9:10 fliebel: clgv: hu? how did priority queues get involved?

9:11 clgv: the german computer magazine "c't" had an article about that some years ago

9:11 you select fields to update from that priority queue afair

9:11 waterbuffalo: fliebel yes something like that

9:12 clgv: I assume the neighbor-updating listeners would get quite confusing

9:13 fliebel: clgv: yea, spageti updaters :)

9:14 clgv: they solved it by gathering the constraint groups (rows, columns and blocks) in objects that had an update method afair

9:18 waterbuffalo: (time (reduce unchecked-add (range 1000000))) "Elapsed time: 23742.330576 msecs"

9:19 (time (reduce + (range 1000000))) "Elapsed time: 191.690584 msecs"

9:19 LOL

9:20 tomoj: I don't get it

9:20 clojurebot: Gabh mo leithscéal?

9:21 dnolen: ,(time (reduce #(unchecked-add (int %1) (int %2)) (range 1000000)))

9:21 clojurebot: "Elapsed time: 845.265 msecs"

9:21 1783293664

9:21 dnolen: ,(time (reduce + (range 1000000)))

9:21 clojurebot: "Elapsed time: 845.351 msecs"

9:21 499999500000

9:22 dnolen: ,(time (reduce #(unchecked-add (long %1) (long %2)) (range 1000000)))

9:22 clojurebot: "Elapsed time: 815.014 msecs"

9:22 499999500000

9:29 dnolen: ,(time (loop [x (long 1e6) r (long 0)] (if (zero? x) r (let [x (long (unchecked-dec x))] (recur x (unchecked-add r x))))))

9:29 clojurebot: "Elapsed time: 96.199 msecs"

9:29 499999500000

9:32 waterbuffalo: interesting

9:32 seems like casts alone ruin performance a ton

9:35 dnolen: waterbuffalo: not in my experience. but in 1.3.0 you can write: (set! *unchceck-math* true) (loop [x 1e6 r 0] (if (zero? x) r (let [x (dec x)] (recur x (+ r x))))), and it will run just as fast as the above.

9:36 waterbuffalo: interesting

9:36 dnolen: waterbuffalo: LOL interesting

9:36 waterbuffalo: I'll still need to deconstruct operations like range into loops?

9:37 dnolen: waterbuffalo: if you want speed, don't use range for loop control.

9:39 angerman: clgv: no i didn...

9:39 clgv: i rewrote my for loop to take the resolved symbol and a string...

9:39 waterbuffalo: well range...reduce...map any of the list operations

9:40 angerman: clgv: e.g (for [[algo aname] [some/ns/fn "SomeAlgo"] ,…)

9:40 clgv: angerman: ah ok

9:40 dnolen: fliebel: a sudoku solver in CHR in 22 lines, http://people.cs.kuleuven.be/~tom.schrijvers/CHR/chr_benchmarks/sudoku.chr ;)

9:44 fliebel: dnolen: CHR?

9:44 dnolen: fliebel: Constraint Handling Rules.

9:44 clgv: dnolen: fliebel: oh no that reminds me of our professor frühwirt :P

9:45 dnolen: clgv: haha! you had him?

9:45 clgv: I'm reading his book.

9:45 clgv: dnolen: yeah. one lecture in theoretical computer science and one in constraint programming

9:46 dnolen: clgv: tough guy?

9:46 clgv: oh no it was practical computer science...

9:46 dnolen: there are "strong" and different opinions about him amongst the students ;)

9:47 dnolen: clgv: did you enjoy the constraint programming lecture?

9:47 clgv: dnolen: the constraint programming lecture I heard was 3 years ago

9:47 angerman: aren't there always "strong" and different opinions on professors?

9:48 waterbuffalo: no, sometimes everyone agrees he's shit

9:49 clgv: dnolen: the content was interesting

9:49 angerman: waterbuffalo: ahh…

9:50 at first I read: "everyone agrees his shit" :?)

9:51 clgv: dnolen: you do research in the CHR / constraint programing field?

9:51 dnolen: clgv: not at all. But I have some interest in doing something like CHR for Clojure.

9:52 fliebel: dnolen: I can barely read the code. One good thing is that my code is shorter.

9:53 dnolen: fliebel: heh, yeah you'd have to read up on CHR, it's different from Prolog (Prolog is one host language for it)

9:53 angerman: ,(time (filter (complement nil?) (range 1000)))

9:53 clojurebot: "Elapsed time: 0.135 msecs"

9:53 (0 1 2 3 4 5 6 7 8 9 ...)

9:53 mec: Why is (time (for ...)) returning immediatly but continuing to process in the background?

9:53 angerman: ,(time (filter identity (range 1000)))

9:53 clojurebot: "Elapsed time: 0.131 msecs"

9:54 (0 1 2 3 4 5 6 7 8 9 ...)

9:54 angerman: hmm.

9:54 dnolen: mec: you need (time (doall (for ...))), for returns a lazy sequences immediately.

9:55 mec: dnolen: it returns immediatly, but its still running some thread in the background

9:55 angerman: lazy sequences can be a real pita.

9:56 clgv: dnolen: I guess you can make a prettier CHR with Clojure.

9:56 angerman: (if you are not aware of of them :)

9:57 dnolen: clgv: heh, I think the syntax for CHR is not so bad, if you're OK w/ Prolog (whose syntax I like)

9:57 clgv: dnolen: I only remember that I didnt like it much ;)

9:57 fliebel: dnolen: I'm not sure what to do with Sudoku in Logos. I wrote a plain Clojure version that works, but the logos version does not finish within any reasonable time. I might try to write it in the same style as the Clojure version, but that feels less declarative.

9:59 dnolen: fliebel: not surprising. Perhaps you should revisit when I get disequality constraints and fix cond-a cond-u ?

10:00 fliebel: dnolen: Hm, I think that is a good idea. Pattern matching also might help a lot with tearing apart the board.

10:01 angerman: ! TeX capacity exceeded, sorry [main memory size=3000000]. … lol

10:02 clgv: angerman: looks familiar ;)

10:03 angerman: wow. that tikz renderer has some funky features...

10:03 create gray/glass like structures.

10:04 it could use some backface culling for better performance.

10:04 would obviously destroy the glass like option though.

10:04 http://dl.dropbox.com/u/281539/cc-ds-pl-subdiv.pdf [900kb]

10:05 clgv: angerman: do you have your TikZ related code up on github?

10:06 angerman: yep

10:06 https://github.com/angerman/planarity

10:06 clgv: you have been bookmarked ;)

10:06 angerman: the geometry renderer is in https://github.com/angerman/planarity/blob/master/src/geometry/renderer.clj

10:07 and the tikz driver is in https://github.com/angerman/planarity/blob/master/src/tikz.clj

10:09 clgv: ah you compile them with the skript. I used the externalize library in my last presentation

10:09 this way the pictures are only recompiled on change. I built a tex file per animation manually.

10:11 angerman: well most of the tikz compile and show stuff is mainly so I can take geometry from the repl, and just compile it and let Skim refresh.

10:11 e.g. chaning the camera/eye position. Adding light (which does not work yet)...

10:12 how on earth do I increate latex main memory?

10:12 clgv: commandline param?

10:12 angerman: yep… anything that helps :D

10:13 clgv: maybe you have an error in your generated latex that is causing that error

10:13 angerman: no. it's main memory.

10:13 the file linked above is the result of the exhaustion. there are some more figures to come.

10:17 waterbuffalo: wait, you are making 3d graphic renderers in clojure? O_O

10:17 * angerman really hopes that what he just did … did what he expects it to do.

10:19 mec: (reduce merge {} lots-o-maps) or (apply merge {} lots-o-maps) ?

10:20 * angerman 'd say second. but why not time it?

10:22 Chousuke: I suggest apply

10:22 that way, merge is free to optimise with transients, for example. (no idea if it does)

10:23 waterbuffalo: unless you have like 1000+ elements I don't think transients work that well :P

10:24 mec: I have at least 1 million

10:26 angerman: ok. it did what I expected it to do...

10:26 mec: identical?

10:26 clgv: waterbuffalo: for me it works well for list with a maximum of 100 element

10:26 angerman: nah. my latex memory increase.

10:26 clgv: it's definitely faster

10:27 angerman: how did you do it?

10:27 waterbuffalo: really?

10:27 AWizzArd_: ,(Math/PI)

10:27 clojurebot: 3.141592653589793

10:27 waterbuffalo: amazing

10:27 AWizzArd_: Btw, why does this work? Is Math/PI a static method?

10:27 waterbuffalo: static variable

10:27 public final static

10:27 AWizzArd_: yes, so I would expect it to work without the parens which I used.

10:27 ,Math/PI ; <-- OK, makes sense

10:27 waterbuffalo: yes

10:27 clojurebot: 3.141592653589793

10:28 AWizzArd_: ,(Math/PI) ;<-- I called a static method??

10:28 clgv: (1.0)

10:28 clojurebot: 3.141592653589793

10:28 * angerman would use apply simple becasue reduce would call merge repeatedly until all maps are consumed while apply would allow the merge is allowed to do what ever it want's if fed multiple maps (not limitied to dual arity)

10:28 clgv: ,(1.0)

10:28 clojurebot: java.lang.ClassCastException: java.lang.Double cannot be cast to clojure.lang.IFn

10:28 waterbuffalo: no such static method

10:28 angerman: clgv: basically followed http://doxdrum.wordpress.com/2011/02/25/increase-texs-main-memory/

10:28 AWizzArd_: Right, so this must be some Clojure magic then.

10:28 waterbuffalo: probably

10:28 clgv: angerman: and it did the trick?

10:28 AWizzArd_: Maybe Clojure allows to call static fields then.

10:28 angerman: full set of graphs http://dl.dropbox.com/u/281539/cc-ds-pl-subdiv.pdf

10:29 clgv: yes. I assume I can create 64pages worth of these kinds of graphs :D

10:29 clgv: why do you do these graphs anyway?

10:30 angerman: thesis in partial fulfillment of a degree of Diplom in Mathematik.

10:31 clgv: ah. I was tempted to put you in computer graphics ;)

10:31 angerman: The last 12 images show planar quadrilateral subdivision (or what is left).

10:31 The first 12 show catmull clark subd. the next 12 doo sabin subd. and the final 12 planar subd.

10:32 clgv: well. It's closely related. I'm at the chair of geometry and visualization.

10:33 clgv: ok. then I didn't guess too wrong ;)

10:34 angerman: yes. It's somewhere at the intersection of both.

10:39 clgv: we dont have that intersection here - our mathematicians are in the nearby forest ;)

10:39 * angerman is at TUM :D

10:42 fliebel: Can I :use a set of things, and :reload only one?

10:42 With the correct mixture of parens...

10:42 * clgv thinks that everything in clojure is done with the correct mixture of parens ;)

10:44 waterbuffalo: lies, I do everything by calling java classes I make beforehand

10:44 * fliebel dumping cake for lein because cake is being super slow on the repl.

10:45 clgv: waterbuffalo: really? why do you use clojure then? ;)

10:45 waterbuffalo: to look cool and wear sunglasses while programming

10:46 clgv: oh, is wearing sunglasses idiomatic?

10:46 fliebel: clgv: depends on the brand

10:47 * clgv makes a note: "Buy programming sunglasses with the right brand."

11:03 TobiasRaeder: Is there a way to typehint that something should be a primitive when calling an java function?

11:03 i need to call a function that takes float float float and float float Object

11:03 mattmitchell: anyone know how to make emacs NOT put my cursor in a slime error buffer after executing code? i want it to stay in my main code buffer.

11:03 TobiasRaeder: need to call the float float float one tho

11:30 sattvik: TobiasRaeder: I believe you can use ^Float.

11:31 TobiasRaeder: @sattvik tried that but it always get No matching method found exceptions :/

11:37 sattvik: TobiasRaeder: I tried doing a quick test. I am not getting a no matching method exception, but it also doesn't seem to pick the right method to call.

11:37 TobiasRaeder: @sattvik interesting

11:38 Fossi: tried (float param)?

11:39 raek: ^Float means boxed (non-primitive) float

11:40 sattvik: Yes, doing (float .) does seem to do the trick. It won't work if the method is overloaded with both Float and float, I think.

11:41 clgv: "reference to field costs can't be resolved." do defrecords not have fields but only keywords?

11:43 sattvik: clgv: They have fields. You should be able to both (:field record) and (.field record) with a defrecord.

11:43 waterbuffalo: man I forgot the rules

11:43 clgv: sattvik: but I get the above reflection warning

11:43 waterbuffalo: does autoboxing precede upcasting?

11:44 sattvik: You may need to type hint the record. (.field ^Record record).

11:44 waterbuffalo: it was on my java certification exam

11:44 clgv: sattvik: right, forgot about that

11:45 all warnings gone :)

12:08 mattmitchell: using clojure.contrib.mock.test-adapter and trying to figure out the has-args option -- how can i be more specific about the type of arg ?

12:09 fliebel: Who else besides dnolen who knows miniKanren? I run into trouble to frequently… :P

12:37 sjl: Is there a templating library for Clojure that a Jinja/Django user would feel at home with?

12:39 fliebel: sjl: Moustache probably, but I don;t know anything that lets you embed logic and stuff.

12:39 ah, dnolen, can I bother you with another Logos problem? :P

12:39 dnolen: fliebel: what's up?

12:40 fliebel: dnolen: I have a relation that is behaving strange, either that, or I don;t understand it. Let me gist it.

12:44 uh, oh… one more moment… all my repls are doing weird stuff…

12:44 sjl: fliebel: Is that the same as the moustache templates in all the other languages (Chris Wanstrath's moustache)? If so, it's pretty close.

12:44 Thanks

12:44 fliebel: sjl: it is

12:44 sjl: fliebel: Hmm, is this not the moustache I'm looking for? https://github.com/cgrand/moustache

12:45 fliebel: sjl: oh, right, it's u, not ou

12:45 sjl: oh dear

12:46 fliebel: dnolen: problem solved… I renamed a function, but not the recursions, and the repl kept these around, so it used the new function, and the recurred into the old function.

12:58 dnolen: I noticed you have some debug functions, how do they work?

12:59 dnolen: fliebel: they're a bit klunky since I use lazy sequences to avoid stack overflow.

12:59 fliebel: they drop strings into an atom, you can then (print-debug *debug*), which will print out what happened.

13:00 fliebel: in order to cleanup (reset-debug! *debug*)

13:01 fliebel: I'm thinking I'll add a debug paramter to (run ...) to make this less tedious. Can't do this right now but I'll try to get to it later tonight.

13:01 fliebel: dnolen: But they are not a goal, nor do they project stuff, do they? So how do I use them?

13:01 dnolen: oh, okay.

13:02 dnolen: fliebel: they are a goal, but they don't change anything, they're basically an s#, they would be problematic with cond-a cond-u I think tho.

13:04 fliebel: dnolen: Ah, so I can do stuff like (exist [x y] (== x 3) (project [x] (log "x is" x)) (== y 4))

13:05 dnolen: fliebel: yeah.

13:05 fliebel: okay, tres cool

13:12 dnolen: Would it be possible to write a xml parser in Logos? That would result in stuff like http://www.seas.upenn.edu/~harmony/

13:18 dnolen: fliebel: perhaps. I think Logos needs to be a lot faster tho. I'm ruminating how one would combine CHR/Art of the Propagator with miniKanren. Seems like a fruitful direction.

13:20 CHR is interesting because it seems like one of the few declarative paradigms that can really compete w/ imperative ones. clause order doesn't matter like it does in prolog, execution order doesn't matter either.

13:22 fliebel: dnolen: Sounds great. But I do have the feeling that I'm writing Scheme, Prolog and whatnot when using Logos, and use very little actual Clojure.

13:23 dnolen: fliebel: as it should be. multiparadigm programming all the way.

13:24 fliebel: But maybe that is just a matter of adding a few high-level relations and iterations. think map-o, partition-o, etc :) Just thinking out loud here.

13:25 Bronsa: how do I exit from a for?

13:25 fliebel: Bronsa: You don't, there is no break keyword or such. why do you need to exit? For is lazy, so you can use just what you need.

13:27 dnolen: fliebel: such constructs are low-level details for the Logic Programmer ;) LP is all about letting the computer figure out _how_.

13:27 technomancy: ,(for [x (range 10) :while (< x 5)] x)

13:27 clojurebot: (0 1 2 3 4)

13:27 cemerick: Bronsa: you can use :when and :while in for's let binding to cause the lazy seq for produces to terminate "early"

13:27 Bronsa: uh

13:27 pdk: for produces sequences, use doseq for iterative looping

13:27 Bronsa: yeah that's what i needed

13:27 thanks

13:27 fliebel: dnolen: But recursion is low-level as well.

13:30 dnolen: fliebel: recursion in LP has a different feel (I think). You're defining _what_ in terms of _what_. in FP _how_ in terms of _how_.

13:32 fliebel: dnolen: But in logos just as much in Clojure, there are a few kinds of recursion that are very common, which should be wrapped in something less verbose, leaving hand-made recursion for the complicated cases.

13:34 dnolen: fliebel: come up with some examples, helper relations, improvements. I want to see them :)

13:35 fliebel: dnolen: I have none, but as soon as I have, I will show them.

13:47 mec: is there a first-filter?

13:49 danlarkin: mec: (comp first filter)

13:53 amalloy: mec: you can sometimes use (some pred coll), if your predicate returns elements unharmed when they match

13:53 cemerick: technomancy: you should figure out an IPA version of lein's pronunciation

13:54 raek: [laWriting a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.

13:54 oops

13:55 ['laɪnɪŋən]

13:57 TimMc: seems right

14:06 joelr: good day! how do i install the native-deps plugin for leiningen? it appears to be just another clojure project

14:09 raek: joelr: you add it as a :dev-dependency in your project.clj

14:10 joelr: raek: so i don't need to install it somehow then. i see

14:10 mattmitchell: i'm having a tough time figuring this out. basically, the docs for clojure.contrib.mock says the the has-args option accepts predicate fn's for testing arguments. I can't get this to work at all though. Anyone use contrib.mock?

14:10 joelr: lein native-deps

14:10 Exception in thread "main" java.lang.IllegalAccessError: default-repos does not exist (native_deps.clj:1)

14:10 raek: what about this error when running lein?

14:11 raek: joelr: leiningen does find the "native-deps" task, but something else is wrong

14:11 joelr: raek: ok, thanks

14:11 technomancy: joelr: probably an old version of native-deps; be sure to get the latest

14:12 joelr: technomancy: how do i get the latest? how do i even figure out what the latest is?!

14:12 i did clone the native-deps repo and ran lein deps in it but what then?

14:12 mattmitchell: on a related note, what are most people using for testing/mocking in clojure?

14:12 dnolen: joelr: what are you trying to do? I'm the maintainer of native-deps.

14:13 technomancy: looks like 1.0.5: https://github.com/swannodette/native-deps/blob/master/project.clj

14:13 joelr: dnolen: i'm trying to build this: https://github.com/mikejs/ring/tree/master/ring-mongrel2-adapter

14:13 dnolen: joelr: you definitely need 1.0.5 as technomancy said.

14:13 if you're using the latest released version of lein.

14:14 joelr: i think i am... does lein self-update?

14:15 technomancy: joelr: yeah, as long as you didn't install it from a package manager lein upgrade should work

14:16 joelr: technomancy, dnolen: thanks!

14:17 more generally, i'm struggling with getting clojure/zeromq going against mongrel2

14:17 any tips?

14:17 dnolen: joelr: the problem is that version of ring is requiring native-deps 1.0.1. You need to change it to require 1.0.5. You don't need to mess w/ the native-deps project directly at all, the latest is on clojars.

14:18 joelr: dnolen: thanks, that's likely part of my problem

14:19 technomancy: dnolen: I can add in an alias for default-repos for backwards-compat; where's it looking for it?

14:19 thorwil: i wrote my very first clojure macro. testing with macroexpand suggests it's correct, to me. yet, i get a "java.lang.IllegalArgumentException: Key must be integer". would someone be so kind to have a look at http://paste.pocoo.org/show/354684/ ?

14:22 joelr: dnolen: what is the best way to set the dyld library path with native-deps?

14:22 dnolen: technomancy: lemme look.

14:22 joelr: you don't need to set it. lein does that.

14:22 joelr: dnolen: my java is looking at /usr/local/lib instead of the lein directory

14:22 dnolen: i did run lein deps and lein native-deps

14:22 and upgraded lein

14:22 dnolen: joelr: are you using lein to start the repl or swank?

14:23 joelr: dnolen: ye[

14:23 yep

14:23 amalloy: thorwil: ([""] anything) looks like it must be wrong

14:23 joelr: dnolen: i get this error when using the ring adapter: /Users/joelr/Work/java/ring/ring-mongrel2-adapter/native/macosx/x86_64/libjzmq.dylib: Library not loaded: /usr/local/lib/libzmq.0.dylib Referenced from: /Users/joelr/Work/java/ring/ring-mongrel2-adapter/native/macosx/x86_64/libjzmq.dylib Reason: image not found

14:23 dnolen: joelr: do you have a folder called native in your project now?

14:24 joelr: dnolen: one sec, i think i know why i get this error

14:24 amalloy: you say that the "code to be replaced" is [""] (-> ...), but that's two deparate sexps

14:24 dnolen: technomancy: in 1.0.1 I was using (:use [leiningen.pom :only [default-repos make-dependency]] ...)

14:25 technomancy: dnolen: ok, I'll add an alias there; thanks.

14:25 thorwil: amalloy: it's for routing with moustache. [""] means root. this stuff is used within a an "app" macro from moustache

14:26 amalloy: thorwil: bur [""] (...) is very different from ([""] (...)). which do you want?

14:26 technomancy: dnolen: will it break things if default-repos entries become a map sometimes? "clojure" {:url "http://build.clojure.org/releases" :snapshots false}

14:27 if so it's probably not worth it

14:27 thorwil: amalloy: the first. i thought the outer () was macroexpands doing

14:27 amalloy: thorwil: a macro cannot expand to multiple sexps. if (foo) somehow expanded to (bar) (baz), life would be very difficult for everyone

14:28 so if you want your eventual code to look like (defroute [""] (...)), you need a macro that generates the whole defroute form, not just the first two args to it

14:29 joelr: dnolen: i had a version of jzmq installed in /usr/local/lib

14:29 dnolen: technomancy: if that makes your life easier that's fine w/ me, I can check map? and do conditional logic.

14:29 thorwil: amalloy: i wasn't aware of that limitation, thank you

14:29 dnolen: joelr: gotcha, so things are working for you now?

14:30 amalloy: thorwil: it certainly can expand to ((bar) (baz)), as you saw, and *within* its single sexp it can do as much splicing and fiddling as it wants, but it cannot leave that sandbox

14:31 technomancy: dnolen: yeah, it will speed up dependency checking quite a bit if we don't check non-snapshot repos for snapshots

14:32 joelr: dnolen: yep, otool -L reveals that native/macosx/x86_64/libjzmq.dylib wants /usr/local/lib/libjzmq.0.dylib even though there's a perfectly working native/macosx/x86_64/libjzmq.0.dylib

14:33 hiredman: ~logs

14:33 clojurebot: logs is http://clojure-log.n01se.net/

14:36 dnolen: joelr: they are both on your path. It's not clear to me that there's a way to prefer one or the other. Global installs of Java native libs are a PITA in my experience. Open to insights on how to handle such cases.

14:38 choffstein: Hey all. This is going to be a very, very stupid question, but how do I find the max of a seq? Calling (max [1 2 3 4]) just returns [1 2 3 4]... is there any way to destructure the seq into the params max expects?

14:38 amalloy: apply max

14:38 fliebel: choffstein: ##(apply max [1 2 3 4])

14:38 sexpbot: ⟹ 4

14:38 choffstein: *smacks forehead8

14:39 Yep...right. Apply. God damnit.

14:39 dnolen: ,(reduce max [1 2 3 4])

14:39 clojurebot: 4

14:39 fliebel: dnolen: I was about to say that. I think that is prefered in most cases, no?

14:39 amalloy: i don't think so

14:39 dnolen: amalloy: remind me why apply is preferred here?

14:39 amalloy: i mean, either is fine

14:40 fliebel: $source max

14:40 sexpbot: max is http://is.gd/HUUFvJ

14:40 amalloy: but apply gives more room to the implementors of max to optimize, in future

14:40 eg spin off some new threads to do a divide-and-conquer instead of mandating a linear pairwise thing

14:40 fliebel: amalloy: max reduces internally for more than 2 args, so reducing is cheaper here.

14:41 amalloy: fliebel: so? the difference is basically zero for that

14:41 dnolen: I'd rather implementors optimize, parallelize, primitivize reduce in the future, than bother with max ;)

14:41 TimMc: brehaut: Grah, can't get the hang of fnparse.

14:41 amalloy: dnolen: they can't parallelize reduce! reduce specifies that you have to work with o1, then o2, then o3...

14:42 TimMc: brehaut: I think I'll just use regex for now and switch to fnparse later.

14:42 fliebel: amalloy: what about pvreduce?

14:42 amalloy: these performance concerns are basically pointless in either direction

14:42 brehaut: TimMc: oh? what is causing you grief?

14:42 amalloy: TimMc: https://github.com/amalloy/claudius/blob/master/src/claudius/core.clj has a simple use of fnparse

14:42 fliebel: amalloy: that might be true, but I think some guru said reduce was better, except for str and a few others. I'd like ot find out why that was.

14:42 amalloy: super-simple, maybe too simple for your use

14:43 fliebel: it's worse for str because str *does* have the optimizations now that max *could* have in future :P

14:43 brehaut: TimMc: sure thing

14:43 amalloy: anyway, executive summary: use reduce or apply for this case. some cases apply is necessary; sometimes reduce is necessary: keep them both in mind

14:44 fliebel: amalloy: I think there was another argument, namely that apply works one level above your code, rather than on the same level, but I don;t know what that is supposed to mean.

14:44 brehaut: fliebel: have you got a link for this?

14:45 fliebel: brehaut: No, just a random irc conversation months back. If my search feature was less crapy, I would try to find it.

14:46 brehaut: fliebel: no worries

14:46 fliebel: ~logs

14:46 clojurebot: logs is http://clojure-log.n01se.net/

14:46 amalloy: fliebel: searching those is pretty dang hard too

14:49 dnolen: amalloy: isn't http://labs.oracle.com/projects/plrg/Publications/ICFPAugust2009Steele.pdf all about making reduce parallel for applicable operations?

14:49 fliebel: amalloy: Yea… Maybe the guru in question could enlighten us. Might be chouser or fogus who said it.

14:50 amalloy: dnolen: that paper is new to me, and at a glance it looks like you are right. but i'm not sure how it's relevant: the contract for reduce, as it exists now, specifies an order of operations. some futuristic pvreduce on the par branch might allow parallelization, but the one we have now won't

14:51 choffstein: If I have a map and I want to apply a function to the vals and replace them, is there a function to do that? I wrote a macro using reduce and assoc on an empty map ... but it seems hacky.

14:51 amalloy: fmap, walk

14:51 in clojure.contrib.generic.functors (i think) and clojure.walk, respectively

14:52 choffstein: amalloy: if you charged me a penny for every question of mine you've answered, you'd have ... $10?

14:53 amalloy: heh

14:53 dnolen: amalloy: there is no contract for how reduce works as far as I'm aware. reduce already works differently for different datatypes.

14:53 amalloy: i should stop giving two answers at once, then

14:53 $source reduce

14:53 sexpbot: reduce is http://is.gd/SRobxr

14:53 brehaut: amalloy: turning down a chance to use juxt and comp?!

14:53 amalloy: If val is not supplied,  returns the result of applying f to the first 2 items in coll, then  applying f to that result and the 3rd item, etc.

14:55 if reduce didn't have such a contract how could it be usable? foldl vs foldr have hugely different characteristics for non-associative operations

14:55 joelr: dnolen: how do you deal with native libraries that want to be installed in /usr/local/lib?

14:55 amalloy: like, you could certainly specify a new special-case of reduce that allows parallelization and is vaguer in its contract

14:55 but i don't see reduce itself changing

14:56 dnolen: joelr: I don't know how to handle that case. I meant that I was open to ideas on how to deal w/ that.

14:56 joelr: short answer, don't global install native extensions if you're a JVM language developer.

14:57 joelr: dnolen: let me try something (i'm on the mac)

14:59 dnolen: amalloy: not in disagreement, but the door seems wide open for optimizing reduce. But I see nothing similar for apply.

15:00 amalloy: dnolen: apply itself can't be optimized, for sure. but it can benefit from optimizations to the function being applied

15:01 which is different from reduce: you could optimize reduce itself but that's less likely to happen in a hurry because of the way reduce is specified

15:11 dnolen: amalloy: my experience is that Clojure tends to prefer global optimizations over specific ones. My bets are on reduce :)

15:13 joelr: dnolen: any clues on this? i copied the native libraries to /usr/local/lib/, just symlinking them didn't do it but now i get Could not initialize class org.zeromq.ZMQ [Thrown class java.lang.NoClassDefFoundError]

15:13 chouser: is clojure-conj.org down?

15:14 amalloy: http://www.downforeveryoneorjustme.com/clojure-conj.org says it's just you

15:14 fliebel: chouser: not for me

15:14 amalloy: and i can see their page too, fwiw

15:14 chouser: heh, ok, thanks.

15:15 amalloy: (well. they say it's just me, cause i didn't tell them i was asking on your behalf)

15:15 chouser: "The server encountered an error and could not complete your request." Hm...

15:16 amalloy: chouser: it only works for people with at least two Ls in their irc name. weird bug

15:16 dnolen: joelr: I would remove your global install. how did you install?

15:16 * chouser nods

15:16 chouser: makes sense

15:16 joelr: dnolen: i removed my global install a long time ago if you are talking about libraries in /usr/local/lib

15:18 dnolen: is there anything else to do to remove my global install?

15:18 fliebel: chouser: You can always try wget/curl, but set the X-irc-name header ;)

15:18 dnolen: joelr: so it's still looking there? that baffles me. I don't know anything abut jzmq so I can't say.

15:18 joelr: dnolen: i did install that lib into my local maven repo when installing globally, does that matter?

15:19 dnolen: joelr: probably.

15:23 joelr: dnolen: tried that, doesn't help. i'm still getting Could not initialize class org.zeromq.ZMQ [Thrown class java.lang.NoClassDefFoundError]

15:23 dnolen: i don't know if this helps but it works if i build manually and install using maven

15:24 dnolen: and use the :native-path "/usr/local/lib" variant instead of native-deps

15:24 Licenser: aloa :)

15:26 joelr: dnolen: question... in addition to the native deps, won't i also need something like [org.zmq/jzmq "2.0.7-SNAPSHOT"]? or is the assumption that the jar is packaged with the native deps?

15:27 hiredman: apparently 'if' vs. 'when' is the most divisive issue in clojure

15:28 dnolen: joelr: you definitely need that, :native-dependencies [some/native/jar "version"]

15:28 Licenser: i kind of like if

15:28 hiredman: called out a use of 'if' with a single branch an hour or so ago, and the argument is still waging on sonian's irc channel as to which is appropriate where

15:29 amalloy: haha

15:29 joelr: dnolen: but that would include the jar with the java wrapper code, correct?

15:29 amalloy: if you use if when you should use when, you deserve what you get

15:29 Licenser: amalloy: brilliant statement

15:30 hiredman: some claim it doesn't matter which you use where, some claim when is only for sideeffects because of the implicit do, etc

15:30 amalloy: sure, i see both sides of the argument, it's just that every side but mine is wrong

15:30 joelr: dnolen: because that class-not-def error is clearly due to the jar not being found

15:30 fogus`away: hiredman: http://www.xach.com/naggum/articles/3215299538573186@naggum.net.html

15:31 hiredman: ugh, common lisp

15:31 dnolen: joelr: native-deps assumes that all your native stuff is in a single jar, not packaged up with the other stuff.

15:31 hiredman: fogus`away: fns and let have an implicit do

15:31 technomancy: yeah; bring down the naggum-hammer

15:32 Licenser: I found it not to be too much of a trouble to have a lib directory for additonal deps

15:32 dnolen: joelr: native-deps also assumes a specific layout that lein expects.

15:32 fogus`: naggum-hammer, good name for a project

15:32 joelr: dnolen: does it mean that :native-dependencies [[org.clojars.mikejs/jzmq-native-deps "2.0.7-SNAPSHOT"]] was not packaged correctly?

15:32 dnolen: how can i check?

15:33 fogus`: hiredman: substitute progn for do

15:33 dnolen: joelr: do you have a native folder in your project directory now?

15:33 joelr: dnolen: 100%

15:33 technomancy: fogus`: yeah, I wasn't even thinking of the norwegian connection.

15:33 dnolen: joelr: it's also important to run, lein deps, lein native-deps _always_ in that order.

15:33 hiredman: fogus`: it's not 'oh clisp, I can't read this' it's 'oh, this is digusting, I don't want to read this'

15:33 joelr: dnolen: i do that, in that order. i also do lein clean before lein deps and lein native-deps

15:34 fogus`: hiredman: fair enough ;-)

15:34 dnolen: joelr: is the zeromq jar in your lib folder?

15:35 joelr: dnolen: no, although there's zeromq stuff in ~/.m2/repositories/...

15:36 dnolen: joelr: something is wrong then, you need the jar in your lib folder.

15:36 joelr: e.g. lein native-deps

15:36 Expanding: /Users/joelr/.m2/repository/org/clojars/mikejs/jzmq-native-deps/2.0.7-SNAPSHOT/jzmq-native-deps-2.0.7-20100821.141701-5.jar into /Users/joelr/work/java/ring/ring-mongrel2-adapter

15:36 dnolen: ^

15:37 dnolen: joelr: I would erase all zeromq stuff from your maven dir. lein clean, lein deps, lein-native-deps.

15:37 joelr: dnolen: ok, i see jzmq.jar in my lib

15:38 dnolen: joelr: progress.

15:38 joelr: let me try swank...

15:41 dnolen: what bit of code makes lein automagically load jzmq.jar for me?

15:43 thorwil: how can i deal with -> in a macro?

15:43 amalloy: thorwil: start by explaining what you mean :P

15:44 thorwil: amalloy: with (defmacro urgh [] `(-> foo bar baz)) what i want is expansion to (-> foo bar baz)

15:45 i guess i'm stumbling over the fact that -> is a macro itself?

15:45 amalloy: um, looks like you're all set then. is your issue that instead you're getting user/foo instead?

15:46 joelr: does lein automatically load all the jars from the lib directory?

15:46 thorwil: amalloy: i get (user/baz (clojure.core/-> user/foo user/bar))

15:46 joelr: lein swank that is

15:47 amalloy: well, that's sorta two different issues. the first is that you aren't quite getting how macroexpansion works

15:47 when that code gets actually run, the -> will expand again, getting you the eventual (user/baz (user/bar user/foo))

15:48 you can see the end result with clojure.walk/macroexpand-all, if you want

15:48 &(macroexpand-all '(-> x y z))

15:48 sexpbot: ⟹ (z (y x))

15:48 dnolen: joelr: it's in lib, so it's automatically loaded.

15:48 amalloy: contrast with ##(macroexpand '(-> x y z))

15:48 sexpbot: ⟹ (z (clojure.core/-> x y))

15:49 joelr: dnolen: can i check? because that NoClassDefFound error means it's not being loaded

15:49 dnolen: joelr: are you using swank?

15:49 joelr: dnolen: 100%

15:49 lein swank

15:49 dnolen: joelr: and you restarting when your jars change?

15:50 joelr: dnolen: i think so. let me restart just in case...

15:50 amalloy: the other is that unqualified symbols in macros are automatically namespace-qualified, to prevent you accidentally using symbols for different things in the calling scope

15:50 &`x

15:50 sexpbot: ⟹ clojure.core/x

15:51 thorwil: yes, i got aware of that already

15:52 maybe i have to rewrite what i'm trying to generate without ->, to find the damn bug hiding somewhere :)

15:52 thanks

15:53 joelr: dnolen: this is the thing... i copy the libs from native/... to /usr/local/lib. i lein swank and try to use the project. i get the library image not found blah blah blah error. but the libs are there, i just copied them! if i copy the libs at that moment and try to use the project again (w/o restarting swank) then i get the no class def error

15:55 dnolen: joelr: curious as to why you keep moving things to /usr/local/lib, how does anyone (java) know anything is there?

15:56 joelr: dnolen: the jzmq dylibs want /usr/local/lib

15:56 dnolen: i'm on the mac so i verify this with otool -L

15:57 the funky thing is that i get this error regardless of whether i have the libs in /usr/local/lib or not

15:58 see how it wants /usr/local/lib? /usr/local/lib/libjzmq.dylib: Library not loaded: /usr/local/lib/libzmq.0.dylib Referenced from: /Users/joelr/work/java/ring/ring-mongrel2-adapter/native/macosx/x86_64/libjzmq.dylib Reason: image not found

15:58 dnolen: the error is saying that native/macosx/x86_64/libjzmq.dylib is linked against /usr/local/lib/libjzmq.dylib

15:59 dnolen: joelr: that seems broken to me.

15:59 joelr: dnolen: i concur

16:00 dnolen: joelr: you can explicitly set your library path and load from there I guess, in this case it's probably best to avoid native-deps entirely.

16:00 fliebel: huh… ArityException Wrong number of args (-1) passed to

16:02 joelr: dnolen: how can i tell if my java is running in 64-bit mode or force it to do so?

16:03 dnolen: because i think that's the issue

16:03 fliebel: joelr: Mac has a preference pane for that in application/utitilties

16:03 joelr: the libs are 64-bit

16:03 fliebel: java pref pane?

16:03 fliebel: joelr: mac 10.6?

16:03 joelr: fliebel: yep. latest java too.

16:03 fliebel: Java Preferences.app

16:04 joelr: ;latest for 10.6 anyway

16:04 fliebel: what do i set to only allow 64-bit?

16:04 fliebel: (that was supposed to be the app name and path, dunno what it did)

16:05 joelr: fliebel: it can't seem to uncheck or check just one of the boxes

16:05 fliebel: joelr: yea the java pref pane, you can drag them in the right order.

16:05 joelr: fliebel: i do have 64-bit first

16:05 amalloy: fliebel: -1 args is something to do with macros expecting automatic env and body arguments

16:06 iirc

16:06 fliebel: amalloy: It;s a macro for sure, but what does that mean?

16:06 joelr: fliebel: and activity monitor shows that i'm indeed running 64-bit java. damn, there goes my theory.

16:07 amalloy: fliebel: it indicates that something has gone wrong :) but that's as specific as i can get

16:08 fliebel: amalloy: Oh, okay… lol I even want to go as far as to say something went wrong in a weird way.

16:08 joelr: can i force-load a jar from the clojure prompt?

16:09 fliebel: joelr: force load?

16:09 joelr: fliebel: i mean just load

16:10 fliebel: i'm having trouble with a jar in lib/ and i want to see exactly what happens when i load it

16:10 fliebel: amalloy: Maybe you see something out of place? http://pastebin.com/26ZAY4QT

16:10 joelr: Besides using import and checking the classpath and lib path I wouldn;t know.

16:10 joelr: ok

16:11 thanks

16:11 fliebel: how do i check the classpath and lib path?

16:13 raek: (doseq [url (.getURLs (java.lang.ClassLoader/getSystemClassLoader))] (println url))

16:13 amalloy: fliebel: aside from the evil repetition of (map (fn ...)) stuff

16:13 fliebel: amalloy: I think it is a greater evil to write another loop/macro for 3 lines.

16:14 amalloy: fliebel: but those three functions are exactly the same function

16:14 you don't even need another macro or loop

16:14 fliebel: amalloy: That is true...

16:14 amalloy: fliebel: see also https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/macro.clj#L9 for cases where the function isn't exactly the same

16:15 hiredman: clojurebot: what does the hyperspec have to say about it?

16:15 clojurebot: hyperspec is not applicable

16:15 fliebel: amalloy: But that does not make the macro technically broken..

16:15 amalloy: no

16:16 the macro looks fine to me, modulo the prolog stuff that i have to just assume works

16:16 fliebel: amalloy: That wouldn't break when doing a macroexpand-1, would it?

16:16 amalloy: what?

16:16 clojurebot: what is exceptions

16:17 fliebel: amalloy: The prolog stuff has nothing to do with expanding the macro, as far as I can tell.

16:19 amalloy: fliebel: hard for me to know when you haven't told me where the breakage is :P. eg if slice is throwing the arityexception, that's happening inside the macroexpansion

16:19 fliebel: amalloy: Hm, true, let me look at the exception

16:20 amalloy: Funny how it does not mention anything that has my namespace.

16:21 amalloy: gist up the stacktrace, perhaps

16:21 fliebel: amalloy: sure: http://pastebin.com/Em4qNXmD

16:22 amalloy: whoa -1 args to map, that's funny stuff

16:24 fliebel: i think it's seeing only-one arg passed to map, and accidentally subtracting two because it thinks it's a macro

16:25 what's the form you're calling macroexpand-1 on?

16:25 joelr: dnolen: the nativelibs in clojars have not been packaged correctly, not for the mac.

16:25 fliebel: amalloy: something random with 2 args, like (macroexpand-1 '(pruning-sudoku [1 2 3] :a))

16:26 joelr: dnolen: i built the libs from source, installed them into /usr/local/lib, used :native-path "/usr/local/lib" and removed the libs from native/macosx/... now it works like a charm

16:27 amalloy: then my best guess is that (slice (reduceable-board [1 2 3])) causes a problem?

16:27 fliebel: amalloy: As long as the first is a seq, I get the same error.

16:28 amalloy: then i'm out of guesses

16:28 fliebel: close… ArityException Wrong number of args (1) passed to: core$map wehn executing that.

16:29 amalloy: but range 81 works… wait… ['range 81] does not of course ;)

16:30 there we go!

16:30 dnolen: joelr: good to hear that you got that sorted, sorry for the trouble.

16:31 amalloy: told you it was the prolog stuff :)

16:31 fliebel: amalloy: Nah, it's the literal macro argument stuf that tricked me up again.

16:32 amalloy: I somehow expect clojure to know whether I mean the result of (range 81) or the literal form.

16:39 choffstein: Hey all ... i'm back with more questions :D This one is more code design. I have a list of maps, like [{:date <date> :value 0.1} {:date <date> :value 0.2} ...], and a function that takes a list and constructs a moving average over it. Basically, what I would like to do is yank out all the :value data from the list, pass it to my moving average function, then construct a new map with the associated date values...

16:39 thoughts on the best way to design this one?

16:41 raek: something like this maybe? (map #(assoc %1 :value %2) originals (moving-average (map :value originals)))

16:42 choffstein: mmm ... i like that

16:42 raek: (--> (map :value the-list) ;;Basically, what I would like to do is yank out all the :value data from the list,

16:43 (moving-average)

16:43 ;; pass it to my moving average function

16:43 (map #(assoc %1 :value %2) the-list)) ;; then construct a new map with the associated date values...

16:43 eh, you get the idea :)

16:44 also, --> should be ->>

16:44 oh, you wanted a map...

16:45 or wait, maybe I did interpreted it correctly...

16:50 choffstein: this is what I meant: https://gist.github.com/raw/873272/f3f1dcf77243be32f0e6e7079b9b3d4a94811579/moving_average.clj

16:51 choffstein: thanks raek. that looks like exactly what I am doing. appreciate it.

16:56 angerman: reak the last "the-list" is in error. no?

16:56 ahh. sorry

16:56 * angerman shoots himself.

16:57 waxrose: o_o

17:07 choffstein: is there a way to tell what classes are inside a jar?

17:07 amalloy: choffstein: jar tf <myjar>?

17:08 choffstein: thanks.

17:09 okay -- question for ya. I named one of my namespaces 'moving-averages' in a different library. When my program tries to find it, I get an error that moving_averages.clj can't be found -- but moving-averages.clj is in the jar. Are namespaces allowed to have dashes in them?

17:10 amalloy: yes, but files aren't. my-cool-ns should be in my_cool_ns.clj

17:10 choffstein: ohhhh

17:10 that ... explains a lot

17:10 amalloy: haha i'm glad it does. still seems crazy to me :P

17:11 fliebel: amalloy: Maybe there is a platform with a JVM that uses dashes as path separators.

17:11 amalloy: fliebel: no; java classes just can't have dashes in them, is the root cause

17:11 choffstein: yep, that fixed everything

17:11 amalloy: i just don't really understand how this causes a ripple to clj filenames

17:11 fliebel: amalloy: Maybe something with gen-class?

17:12 amalloy: probably

17:16 fliebel: Oh, great, I coded myself into a corner.

17:16 raek: would be weird to have the source of my-cool-ns.foo in my-cool-ns/foo.clj but the AOT compiled class in my_cool_ns/foo_init.class

17:16 fliebel: What donald duck did, is put up a hammock, and wait. *goes to bed*

17:22 quizme: re-match doesn't work on arrays. What's a good way to handle re-matching in a type-insensitive way on arrays or strings ?

17:22 how do you test if something is an array ?

17:27 brehaut: quizme: i dont think there is one 'array' type; each type of primative and object has its own array type

17:27 quizme: how would you explect re-match to work on an array?

17:29 hiredman: ,(->> Class .getMethods (map bean) (map :name) set)

17:29 bulters: gday all

17:29 clojurebot: #{"getComponentType" "getName" "getEnclosingClass" "isAnnotationPresent" "getClass" "getDeclaredMethods" "getEnclosingConstructor" "getResource" "getConstructor" "getField" ...}

17:29 hiredman: ,(->> Class .getMethods (map bean) (map :name) (filter #(.startsWith % "is")) set)

17:29 clojurebot: #{"isAnnotationPresent" "isEnum" "isInterface" "isArray" "isMemberClass" "isAnonymousClass" "isLocalClass" "isAnnotation" "isSynthetic" "isAssignableFrom" ...}

17:29 quizme: brehaut return an array of matched sub items

17:30 brehaut and nil if nothing matched

17:30 by "Array" i mean vector

17:30 brehaut: quizme: re-matches returns a vector

17:31 &((juxt vector? nil?) (re-matches #"a(b)c" "abc"))

17:31 sexpbot: ⟹ [true false]

17:31 quizme: (re-find #"abc|123" ["abc"])

17:31 java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.

17:31 CharSequence (NO_SOURCE_FILE:0)

17:32 brehaut: &(map #(re-matches #"a(b)c" %) ["abc" "ac"])

17:32 sexpbot: ⟹ (["abc" "b"] nil)

17:33 hiredman: quizme: that is not an array

17:33 brehaut: if you only want the ones that are actually values then ##(keep #(re-matches #"a(b)c" %) ["abc" "ac"])

17:33 sexpbot: ⟹ (["abc" "b"])

17:33 quizme: hiredman it's a vector ?

17:33 hiredman: quizme: yes

17:34 brehaut: &(.getBytes "abc")

17:34 sexpbot: ⟹ #<byte[] [B@2af631>

17:34 brehaut: thats an array

17:34 quizme: hiredman k thanks

17:34 brehaut: thanks I guess i'm ok for now

17:35 hiredman: clojurebot: the policy on names is http://en.wikipedia.org/wiki/Rectification_of_names

17:35 clojurebot: c'est bon!

18:23 riddochc: So, it looks like the current leiningen wants robert-hooke already available, in order to build. robert-hooke is buildable with leiningen. I seem to have caught an infinite loop. :)

18:24 The clojars website doesn't make it terribly obvious how I'd get a prebuilt jar of robert-hooke.

18:24 Any suggestions?

18:25 raek: riddochc: the jar is available here: http://clojars.org/repo/robert/hooke/

18:25 technomancy: riddochc: "building" in the bottom of the readme shows how to do it. you can go sourdough-style or bootstrap with maven

18:26 riddochc: Aha! Thanks raek, and technomancy - I should've kept reading, obviously.

18:30 joelr: how do you split a string at character N?

18:31 a combination of take and drop?

18:32 raek: joelr: at a certain index, or at a certain character (e.g. \, in "foo,bar")?

18:32 joelr: raek: index

18:32 brehaut: &(vec (.split "a,b,c" ","))

18:32 sexpbot: ⟹ ["a" "b" "c"]

18:32 brehaut: oh sorry, misread

18:32 raek: joelr: use subs

18:33 joelr: subs?

18:33 brehaut: (doc subs)

18:33 clojurebot: "([s start] [s start end]); Returns the substring of s beginning at start inclusive, and ending at end (defaults to length of string), exclusive."

18:33 raek: ...twice

18:33 joelr: raek: which is the same as take and drop, no?

18:33 lazy1: ,(map #(apply str %) (split-at 3 "abcdefg"))

18:33 clojurebot: ("abc" "defg")

18:34 raek: joelr: not exactly... take and drop return sequences, but subs returns a string

18:34 joelr: right

18:34 lazy1: i like that

18:35 riddochc: I've made some effort at using sequence functions (take/drop/etc.) for parsing text, and it gets rather complicated, very quickly.

18:36 lazy1: For splitting at a character, you have clojure.contrib.str-utils2/split

18:36 riddochc: Particularly since I wind up trying to return some structure along with the remaining section of input, and then all the parsing functions need to do destructuring, and then I think that it might have been easier to use fnparse to begin with.

18:37 raek: ,(let [s "abcdefg", i 3, left (subs s 0 i), right (subs s i (count s))] [left right])

18:37 clojurebot: ["abc" "defg"]

18:37 joelr: basically, i need to parse a mongrel2 header, e.g.

18:37 82209006-86FF-4982-B5EA-D1E29E55D481 0 /python 568:{"PATH":"/python","accept-language":"en-US,en;q=0.8","user-agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134

18:37 82209006-86FF-4982-B5EA-D1E29E55D481 0 /python 568:{"PATH":"/python","accept-language":"en-US,en;q=0.8","user-agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134

18:37 82209006-86FF-4982-B5EA-D1E29E55D481 0 /python 568:{"PATH":"/python","accept-language":"en-US,en;q=0.8","user-agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134

18:37 82209006-86FF-4982-B5EA-D1E29E55D481 0 /python 568:{"PATH":"/python","accept-language":"en-US,en;q=0.8","user-agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134

18:37 82209006-86FF-4982-B5EA-D1E29E55D481 0 /python 568:{"PATH":"/python","accept-language":"en-US,en;q=0.8","user-agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134

18:37 82209006-86FF-4982-B5EA-D1E29E55D481 0 /python 568:{"PATH":"/python","accept-language":"en-US,en;q=0.8","user-agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.134

18:38 82209006-86FF-4982-B5EA-D1E29E55D481 0 /python 568:{...},0:,; Evaluation aborted.

18:38 brehaut: raek: subs has a 1-ary fn that takes the start and runs to the end

18:38 joelr: where {...} is 568 chars worth of JSON

18:38 riddochc: I wonder if it would be easier if we clojure could support multiple return values... or if that would just make it more complicated.

18:38 raek: brehaut: ah, yes. that is indeed better.

18:39 lazy1: There is clojure.contrib.json, so you can parse the log with that

18:39 brehaut: raek: im just disappointed that i cant work out how to do it with juxt

18:39 pdk: sometimes i wish it still had something like that to indicate whether it returns nil as an actual value pulled from a structure or nil as a dummy value

18:39 raek: ,(let [i 3] ((juxt #(subs % 0 i) #(subs % i)) "abcdefg"))

18:39 clojurebot: ["abc" "defg"]

18:40 brehaut: ((juxt #(subs %1 0 %2) subs) "abcd" 2)

18:40 joelr: lazy1: parsing json is not the issue, i already do that. the issue is elegantly taking the 1st 3 elements of that message, then splitting on : to grab 568 and the rest, then taking 568 chars worth of json then processing what's left

18:40 brehaut: &((juxt #(subs %1 0 %2) subs) "abcd" 2)

18:40 sexpbot: ⟹ ["ab" "cd"]

18:40 raek: yeah, closing over the index as I did is cheating... :)

18:40 brehaut: :)

18:40 joelr: so i'm doing (split #" " req 4) then (split #":" rest 2) then Integer/parseInt

18:41 then (map #(apply str %) (split-at header-len (second rest)))

18:41 it all seems rather inelegant to me

18:46 brehaut: joelr: ## (->> " 1:2 2:3 " .trim (re-seq #"(?:\s+|(\d+):(\d+))") (take-nth 2) (map (comp vec rest)) (into {}))

18:46 sexpbot: ⟹ {"1" "2", "2" "3"}

18:46 brehaut: bah ##(->> " 1:2 2:3 " .trim (re-seq #"(?:\s+|(\d+):(\d+))") (take-nth 2) (map (comp vec rest)) (into {}))

18:46 sexpbot: ⟹ {"1" "2", "2" "3"}

18:46 brehaut: &(->> " 1:2 2:3 " .trim (re-seq #"(?:\s+|(\d+):(\d+))") (take-nth 2) (map (comp vec rest)) (into {}))

18:46 sexpbot: ⟹ {"1" "2", "2" "3"}

18:47 brehaut: sorry about that

18:47 joelr: brehaut: thanks

18:48 brehaut: joelr: sorry i didnt solve the actual problem you mention though

18:53 hsuh: i'm creating an "uberjar" with lein, but then when i do java -jar xxx.jar, i get Exception in thread "main" java.lang.NoClassDefFoundError: myprj/test/core... what going be going on ?

18:55 brehaut: hsuh: you have a :main defined in your project?

18:55 clojurebot: project euler is http://ProjectEuler.net

18:56 hsuh: brehaut: yep, its :main myprj.test.core) and in this file there is a defn main

18:56 brehaut: defn -main ?

18:56 with varargs?

18:56 hsuh: no, (defn main []

18:56 brehaut: hmm, try -main

18:56 do you also have :gen-class in your ns ?

18:56 hsuh: hm

18:56 no

18:57 brehaut: and give it [ & args ]

18:57 hsuh: ok, lemme try

18:58 whats -main instead of main though?

18:58 brehaut: i dont know if the entrypoint is allowd to be defined with a 0 arity main method

18:59 hsuh: sure

18:59 brehaut: hsuh: i cribbed it from http://clojure.org/compilation

18:59 raek: I think you just get a IllegalArgumentException at run time

19:00 amalloy: yes, his actual problem is probably caused by missing :gen-class; missing -main will show up as a problem later

19:01 hsuh: so i need gen-class? this is kinda new right?

19:01 brehaut: not really

19:01 amalloy: uhh

19:01 hsuh: i just installed a new lein version

19:01 and for the first time i'm getting this error, thats what i find strange

19:01 brehaut: gen class is at least a couple of years old i think

19:02 rata_: I miss so much third, fourth, fifth and so on

19:02 amalloy: rata_: write them with a macro

19:03 rata_: amalloy: no problem with that, but I think they are common enough to be in c.core, at least third, which is the one I definitely miss

19:04 brehaut: ,((meta #'gen-class) :added)

19:04 clojurebot: "1.0"

19:04 raek: rata_: destructuring tends to solve those problems for me

19:05 hsuh: brehaut, amalloy: yeah, adding a gen-class to the file with the main function did the trick, i just wonder why i didnt needed it before ... thanks anyway

19:05 rata_: raek: for me too, but this time it made it more verbose

19:06 amalloy: rata_: https://gist.github.com/6f6d7f5811c232c93c25 is a quickie

19:06 needs my macro-utils package tho :P

19:07 rata_: hahaha =) do-template does something similar and is in c.template

19:08 thanks anyway amalloy =)

19:08 amalloy: yeah?

19:09 rata_: amalloy: (do-template [name pos] (defn name [s] (nth s pos)) third 2 fourth 3)

19:10 amalloy: ah. couldn't find that when i was writing mine. mine's more general anyway

19:10 thanks for the pointer

19:16 sjl: Can anyone point me at a guide to handling POST data in Compojure that works?

19:26 brehaut: sjl: have you included the wrap-params etc middlewares?

19:26 (to actually decode the forms data)

19:26 sjl: brehaut: No, but I think handler/site does that. I figured it out though, it was that I had [] before {params :params} and didn't notice

19:27 brehaut: ah right

19:32 amalloy: wow, i did not know about C-x a C-a. this will make coding in verbose languages less painful, i'm sure

19:34 phenom_: does anyone have an example of a non trivial compojure app? one that keeps state around

19:35 brehaut: phenom_: you might want to try #compjure too

19:35 waxrosecabal: amalloy, Yeah, it will. :D

19:35 amalloy: phenom_: maybe ask rata_

19:35 waxrosecabal: brehaut, Greetings.

19:35 brehaut: waxrosecabal: hi

19:39 phenom_: its not really the responsibility of compojure to help you manage your state though

19:39 ZabaQ1: ..hmm..should I really have my static content in classes/public.. ?

19:50 phenom_: rata_ around ?

19:55 rata_: phenom_: yes, sorry, I was eating something

19:56 phenom_: I don't use compojure, but ring+moustache... that won't make a difference probably

19:58 phenom_: you don't need anything special to handle state in ring, just do it as you would in any clojure app

19:58 use an atom or a ref

19:58 I use a ref

19:58 or use a db

19:59 sorry, I use an atom

20:03 TimMc: So there is a single process with multiple server threads and they can potentially share some references?

20:04 phenom_: rata_ I understand ... but how would you structure your functions for a chat application for example ... chat is made up of multiple rooms, each room with multiple users

20:04 rata_: TimMc: I don't know if ring spawns multiple server threads under the hood

20:06 phenom_: your state there would be users and chat rooms, if I understood correctly

20:06 phenom_: im trying to wrap my head around mutable state and side effects ... like what if whenever you created a room you also needed to send off an email

20:06 rata_: you can store them in refs

20:06 or in atoms if you don't need to update both at the same time atomically

20:07 phenom_: what have emails to do here?

20:07 phenom_: just for example ...

20:08 how would you structure such a function

20:08 TimMc: phenom_: I think you might send an agent off to do the emailing.

20:09 phenom_: but the agent has no state ... so use a future ?

20:09 rata_: agents have state

20:10 they're one of the mutable things in clojure

20:10 futures don't

20:11 phenom_: (defn create-room [name] (swap! *rooms* conj name) (send email))

20:11 if you use atoms

20:12 phenom_: that's how i would do it but all of it is side-effects and mutable state

20:12 for some reason i feel that it's wrong lol

20:13 rata_: it's not wrong, not for me at least

20:13 mutable state is in clojure to help you when state is required

20:16 TimMc: There's nothing wrong with mutability, it just shouldn't be the default.

20:31 riddochc: Hey, anybody awake who's familiar with using fnparse?

20:32 I'm having a bit of trouble making use of the 'validate' function correctly. I can't seem to find any examples that use it.

20:38 brehaut: riddochc: i have dabbled with it

20:41 riddochc: Hmmm. Okay, I can get it to identify that there's an error, by returning false from my validator function, but I'm not sure how to make it give a decent error message...

20:41 brehaut: riddochc: validate is pretty simple, what trouble are you having with it?

20:42 riddochc: that isnt the purpose of it

20:42 riddochc: You can assume that most of my code is just like the example json parser, and I've made something like so...

20:42 (def digits

20:42 (validate (complex [digit-seq (rep<= 12 decimal-digit)]

20:42 (-> digit-seq apply-str Long/parseLong))

20:42 (fn [n] (if (> n 2147483647)

20:42 false

20:42 n))))

20:43 What I'm trying to do here is to make sure that whatever number I read isn't larger than 2147483647. If it is, I should error out...

20:43 brehaut: riddochc: instead of using complex i would semantics

20:44 riddochc: Yeah? I'm mainly using complex because that's what the json example uses...

20:44 brehaut: riddochc: put Long/parseLong etc into the body of the semanitcs function; if it raises an exception you can catch that with intercept

20:46 riddochc: Hm. Except it's not about whether it fits in a long, but whether it's actually in so many bits... Seems a long can fit bigger numbers than I can allow.

20:46 brehaut: riddochc: sure. its not bad per se, but its just a bit heavy weight when you only have one parser in the comprehension

20:46 anyway, validate is about causing the parser to backtrack and try a different parsing strategy

20:47 whereas intercept is about capturing an actual error

20:48 riddochc: again, i think thats an exception rather than a parser 'failure'

20:48 riddochc: Well, sure... I could have some logic go over the structure built up afterwards and validate it.

20:49 But this number needs to be used to determine how many arbitrary bytes to read, later in the parser.

20:49 What do you suggest for that situation?

20:49 brehaut: riddochc: you could, but your semantics (or the body of complex) is able to throw an exception

20:51 riddochc: The json parser pretty much only handles errors by using (failpoint (expectation-error-fn ...)) which kind of obscures how to use it any other way.

20:52 I feel like I'm sort of cookbook-programming, rather than really understanding what's going on. :/

20:52 brehaut: let me check i understand everything. a) you are parsing longs out of json b) that value is later used to determine how many bytes to read c) if that value is greater than a certain threshold, its in error and your entire parse has failed?

20:52 im going to go look at this example

20:53 riddochc: My protocol isn't actually json, it's something else... but yes, essentially. I'm just reading the json example code that comes with fnparse as a starting point.

20:53 brehaut: lets take a step back then; what do you understand about the underpinnings of the library?

20:53 ok

20:53 riddochc: I understand it uses monads to handle the passing of the input through the series of functions I'm defining.

20:54 brehaut: riddochc: and do you know what that actually means?

20:54 riddochc: Essentially, that it's doing composition... but dealing with the fact that these functions take and return more than one value.

20:54 brehaut: riddochc: do you understand that its doing nondetermistic depth first search ?

20:55 riddochc: Huh, I wasn't aware that that was the specific mechanism involved.

20:56 It's been a rather long time since I've written formal grammars, but I studied this stuff, once upon a time. LL(k), etc.

20:57 I *think* that the idea of having part of what's already parsed determine future parsing behavior makes it not so context-free, doesn't it?

20:57 brehaut: ok. so the mechanics of the parser are actually a monad transformer around a monad; it has state-t around maybe-m

20:57 state-t lets it track states and maybe-m provides the failure handling logic

20:59 riddochc: Tell you what, I just discovered the articles you wrote about using fnparse, I should probably go read that, and ask questions later -- I've only been woring off the documentation that's directly associated with fnparse.

21:00 er, working.

21:00 brehaut: i think so; you have access to the clojure stack in any case, 'as well as' the state stored within the state machine (which includes the remainder, and any other data you wish to track)

21:00 hah no worries

21:00 riddochc: I'll send you an email after I've had some time to think about what I'm doing.

21:01 brehaut: riddochc: sure thing; ive got a couple of other articles on there about state monads and they also link to some other articles about it

21:02 carlo_au: brehaut: where are these articles? Are they on monads in Clojure (as opposed to Haskell)?

21:02 riddochc: In case you're curious, the specific purpose of this is to implement a rather obscure but useful protocol in clojure... I emailed the author of aleph about it, because it's remarkably similar to aleph's concepts. Check out RFCs 3117 and then 3080 - BEEP is what websockets *wishes* it were. :)

21:03 I was planning on seeing how I can implement BEEP tied in with aleph, etc.

21:03 brehaut: riddochc: apparently my explaination of complex is a bit weak and the rule-to-set function is also poorly introduced

21:03 carlo_au: yeah they are. jsut a moment

21:03 hehe awesome

21:04 riddochc: It was designed in the late 90s, when people first started realizing that HTTP was being badly abused, and were thinking about how to handle things better.

21:05 I forget the guy's name, but its author helped design some pretty significant protocols before that, and it really seems like some pretty smart people worked on BEEP.

21:06 I kinda doubt I can resurrect it for its intended purpose of doing better than HTTP, but that doesn't mean it isn't useful for being the basis of some application-specific protocols. I had a major brainstorm about uses for it last weekend.

21:06 Anyway.

21:07 I should go get some food. Have fun clojuring.

21:07 brehaut: carlo_au: http://khinsen.wordpress.com/2009/04/22/monad-tutorial-for-clojure-programmers/ http://intensivesystems.net/writings.html are your starting points; the first is by the author of the clojure monads lib in contrib, the second becomes quite a deep dive; i also have some of my own ramblings at http://brehaut.net/blog/tag/monads but they arent 'introductions to monads'

21:07 * riddochc copies links.

21:07 brehaut: riddochc: interesting. cheers for the pointers

21:07 carlo_au: that should be http://brehaut.net/blog/tags/monads sorry.

21:07 good luck

21:08 riddochc: if you really want to get a deep understanding, implement state-m your self

21:09 carlo_au: brehaut: cool, thanks

21:11 brehaut: carlo_au: no worries; just keep in mind that as interesting as they are, the application is much narrower in clojure than haskell.

21:11 devn: hello all

21:11 brehaut: hi devn

21:12 * devn has been re-reading the JoC today

21:13 carlo_au: brehaut: is that because Haskell forces anything to do with state to go through a monad/arrow, whereas Clojure allows impure functional code?

21:13 devn: carlo_au: i dont think impure and functional should be used together there

21:13 brehaut: carlo_au: its imprecise but its good neough

21:13 devn: carlo_au: stuart halloway put it like this: clojure is a "consenting adults" language

21:13 brehaut: carlo_au: 99% of monads in haskell are pure

21:13 devn: you can do I/O if you want

21:14 carlo_au: yeah

21:14 devn: but most of clojure is geared towards making the things you do pure by default

21:14 so yes, you can do things which are not pure, but rich's example of Google is apropos

21:14 brehaut: and the impure stuff (IO) is available as more than monads and arrows too; also functors and applicative functors

21:14 devn: Google is not a pure function

21:14 you wanna build google? You need to change some stuff.

21:15 the nice thing is that in clojure after a little bit of reading you can look at some clojure code and be fairly certain about where things are getting impure

21:16 the do* functions for instance are a pretty good indicator

21:16 there's also the implicit (let [k 10] (println k) (+ k 1) (+ k 2))

21:16 some side effects there, but that's still pretty obvious there is something impure happening

21:17 carlo_au: yep

21:17 devn: carlo_au: hope that answers your question?

21:17 carlo_au: devn: it does, yes

21:17 brehaut: carlo_au: its more that haskell has optimized for monads. they are a bit krufty in clojure.

21:17 devn: brehaut: sort of true, but ive seen some haskell hackers implement lots of haskelly stuff in clojure with quite a bit of ease

21:18 carlo_au: are you coming from haskell?

21:20 carlo_au: devn: I dabbled in Haskell about 10 years ago in undergrad, but never did much with it

21:21 my current day job involves writing a lot of C, and that spontaneously made me learn Lisp in my spare time

21:21 devn: this is the extent of my experience with monads: http://carlo-hamalainen.net/blog/2011/02/11/monad-motivation/

21:21 brehaut: devn: you sure can, but you have to overcome the additional syntax barrier. curried functions and infix operators (and do notation) make haskell a much more suitable target for that style of programming. we end up with (comp this) (partial that) (domonad whatever-m ...) everywhere

21:21 devn: brehaut: yeah good poin

21:21 point*

21:22 (defm m-sequence [monads] (let [f (fn [ms m] (let-bind [result m results ms] (return (monad-type m) (conj results result))))] (reduce f (return (-> monads first monad-type) nil) (reverse monads))))

21:22 brehaut: devn: on the other hand, the stuff that jim duey is doing with conduit is pretty cool :)

21:22 devn: yeah jim's monad tutorials for clojure are great

21:23 really enjoyed those.

21:23 conduit is still something im sort of getting my head around tbqh

21:23 brehaut: devn: im slowly coming to grips with conduit but its pretty heavy stuff

21:23 devn: i havent had much of a need

21:23 brehaut: hah

21:23 devn: :D

21:24 yeah, but im beginning to see /now/ where it would be useful

21:24 likewise with aleph and lamina

21:24 brehaut: yeah likewise

21:24 devn: i was like "cool, not sure if ill ever use that, but cool"

21:24 and now it's like "ohhhh!!!!"

21:25 makes me feel kind of behind the times -- someday im gonna be like "rabbitmq!" and some whippersnapper is going to laugh at me and show me some newfangled way of doing it that is 10x better

21:25 im still like, uh, i could use a priority queue, or somethin'...

21:25 brehaut: i want to have a play with github.com/stuartsierra/cljque and the async thing hiredman wrote

21:26 https://github.com/hiredman/die-geister i think

21:26 devn: yeah jim duey referenced hiredman's work -- think he did a hornet queue thing for conduit

21:26 brehaut: hornet queue?

21:26 dnolen: http://www.jboss.org/hornetq

21:27 devn: dnolen: FTW

21:27 brehaut: dnolen: cheers :)

21:27 devn: what's up david

21:27 dnolen: devn: happily crafting macros

21:27 devn: i saw your gist yesterday without the context -- whatcha playin with palindromes for, eh?

21:28 euler fun?

21:28 dnolen: devn: just comparing calculating palindromes with miniKanren vs. for lisp comprehension.

21:28 er list

21:28 devn: bratko-logos

21:28 dude, you're always up to no good

21:29 and by no good i mean working on awesome stuff

21:29 i dont think i can resist looking at code that contains "monkey-banana" in the commit message

21:30 dnolen: devn: heh, we'll see where all this goes, but it fun so far.

21:30 brehaut: dnolen: i forgot to mention, i ran my benchmarks yesteray with version 2 of my monkey-banana thing; when i ran it with version 3 (which uses the unifier) it was 2 orders of magnitude slower

21:30 dnolen: brehaut: your own unifier?

21:30 brehaut: dnolen: just fogus's unifycle

21:30 i dont think im smart enough to write my own

21:31 dnolen: brehaut: yeah, it uses postwalk, postwalk is like molasses.

21:32 brehaut: dnolen: i was going to use your one, but my project is 1.2 so that i can get the monads lib

21:32 devn: i just went through a bunch of old OSX86 installs on this mac while building up my NAS and found all sorts of half-finished projects laying around my hard drive. working on putting it into a "clj-garden" kind of thing. that's neither here nor there, but brehaut, suggestion: grab a white paper on something interesting and write some code for it.

21:32 brehaut: devn: dnolen gave me a link to Oleg et al's LogicT paper

21:33 devn: ive doing that for the last 8 months or so and it's amazing how much insight you get just by plugging away at a whitepaper

21:33 dnolen: brehaut: postwalk makes it 2 orders of magnitude slower. In logos.unifier, unifier will only work with pre-walked exprs. unifier' will call postwalk for you, and run dog slow.

21:33 brehaut: dnolen: does the unifier rely on any 1.3 features?

21:33 dnolen: brehaut: not, really I've actually slowly been removing dependencies on 1.3.

21:34 brehaut: dnolen: i'll have to give that a shot

21:34 devn: btw, i havent been keeping up as keenly as i was, what's new on 1.3? anything beyond static/dynamic, pods?

21:34 dnolen: it was almost all syntactical anyway, using ' in symbols.

21:36 amalloy: devn: primitives

21:36 and unchecked-math by default

21:36 dnolen: amalloy: unchecked math is not the default.

21:37 amalloy: dnolen: well. the default has changed

21:37 from "expand as needed" to "throw an error if it's bigger than a long"

21:38 that's not really unchecked but for someone sitting on 1.2 (ie me) it feels about the same

21:38 brehaut: dnolen: one thing that has surprised me about the LogicT is that i dont think there is a logic var type

21:47 dnolen: brehaut: yeah I haven't looked LogicT closely enough to understand how it works. LogicT seems like it's deals with the ideas from the goal/goal constructor portion of miniKanren.

21:49 brehaut: dnolen: i'll have to take your word for it having not looked at that portion of miniKanren

21:49 dnolen: it definately looks like a layer of additional abstraction and some more opperations on the 'basic' nondeterminsitc state monads

21:49 dnolen: brehaut: unification is considerably less tricky then it sounds. It amounts to recursively traversing two terms and storing what ever is on the "other side" when you encounter a logic variables.

21:50 brehaut: interesting

21:50 dnolen: brehaut: like bidirectional destructuring.

21:52 brehaut: dnolen: i presume that it only gets tricky when there are logic var chains ?

21:52 or is that a seperate concern?

21:52 * brehaut should go read the paper

21:53 dnolen: brehaut: yes that the essence of the tricky part, binding a variable to another variable.

21:53 when people mention occurs-check, they mean preventing variable cycles.

22:01 * devn finds it hard to believe how many subtle things he missed by skipping over the early parts of JoC (apologies to chris and michael)

22:02 devn: i totally missed :refer, forgot about :rename

22:03 what's the best way to alias a defn?

22:04 im used to alias_method in Ruby

22:07 scottj: I think there's a defalias in contrib

22:07 probably c.c.def

22:08 sjl: Anyone used clj-oauth with a site that only needs signed requests, not request tokens?

22:11 devn: scottj: thanks

22:36 mec: Is there any good place that explains the difference between defstruct deftype and defrecord?

22:36 brehaut: mec: defstruct is deprecated

22:38 mec: and thats the only one with an example on the main site :X

22:38 brehaut: really?

22:38 mec youve read http://clojure.org/datatypes ?

22:39 amalloy: mec: ken wesson put together an excellent example of a deftype on the mailing list recently

22:39 scottj: btw are you sure defstruct is deprecated? doesn't say so in the source

22:39 amalloy: scottj: yes

22:39 mec: brehaut: that's mostly the whys not the hows

22:40 amalloy: http://groups.google.com/group/clojure/msg/66a09ed29b488854

22:40 brehaut: mec hmm thats true

22:40 mec: amalloy: thanks

23:22 hiredman: amalloy: neat

23:54 rata_: does anybody know how to optimize this fn? https://gist.github.com/871248

23:54 would typehinting be useful there?

23:55 (if so, how would you do it? I've never done typehinting on my own code, just saw others doing it)

23:57 technomancy: rata_: don't type-hint until you've verified it's a bottleneck by profiling

23:57 rata_: technomancy: I've verified it

23:57 it takes ~80% of the time

23:58 technomancy: should have been more clear: unless you've verified that reflection is the bottleneck.

23:58 rata_: oh ok... how do I do that?

23:59 technomancy: visualvm is one way, I think. haven't done it myself.

Logging service provided by n01se.net