#clojure log - Jun 20 2011

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

2:23 tsdh: Hi

2:23 What's the right tool to generate API documentation for clojure projects?

2:25 Till now, I've tried autotdoc-0.7.1 which fails downloading its deps, and com.fxtlabs/autodoc "0.8.0-SNAPSHOT", which fails when running "lein autodoc". I use clojure-1.3 in my project, which might be the reason for the latter.

2:27 raek: I'm currently using [org.clojars.rayne/autodoc "0.8.0-SNAPSHOT"]

2:27 it is the only verision I got working

2:28 tsdh: raek: Thanks, I'll try that.

2:28 raek: tsdh: you might need to clean the lib/ directory manually

2:29 I think one "bad" version of autodoc adds something that breaks lein

2:29 (I used clojure 1.2.1 in the project)

2:32 tsdh: No, doesn't work (even after cleaning lib/ and lib/dev): java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.<init>(ILclojure/lang/Keyword;)V

2:39 In a project.clj file, how can I specify that I need foolib in version 0.2.0 or newer?

2:40 raek: "[0.2.0,)", I think

2:40 http://maven.apache.org/plugins/maven-enforcer-plugin/rules/versionRanges.html

2:41 tsdh: raek: Ah, yeah, I've missed the comma. :-)

3:10 Scriptor: hi everyone, so as I understand it, internally Clojure uses copy-on-write for some sequences while they're still small

3:10 but then converts them to true persistent structures after a certain point, is that right?

3:13 raek: ,(class {:a 1, :b 2})

3:13 clojurebot: clojure.lang.PersistentArrayMap

3:14 raek: iirc, ArrayMaps (which search linearly throught an array) are used for 8 or less entries

3:14 Scriptor: ah, nice

3:14 ,(class [1 2 3])

3:14 clojurebot: clojure.lang.PersistentVector

3:15 raek: for persistent vectors the branching factor is 32, which basically means you get copy-on-write for vectors up to 32 elements

3:15 Scriptor: right, I remember reading about that, it keeps that 32-element array for performance reasons

3:28 hmm, I wonder why arraycopy is under System

3:40 no_mind: there was a function that will let you check the type of a var. Cannot recall its name

3:43 raek: no_mind: what do you mean by "the type of a var"? it's :tag metadata?

3:43 or the type of the value it contains?

3:43 no_mind: nah (type a)

3:44 raek: yes, type of value

3:46 raek: class is the more basic form

3:46 clojurebot: Ok.

3:47 raek: the type function simply does this (defn type [x] (or (:type (meta x)) (class x)))

3:48 it was used to emulate types in the time before records

3:51 Cozey: Hello - I am aot-compiling one clj file to be a ring servlet - I'm using cake, and it generates *.class files for clojure dependencies of the project - should this be so? I'd like to keep the dependencies in separate jar files, not bundled in war together with my app.

4:13 hmm. what's the status of http://dev.clojure.org/jira/browse/CLJ-322 ? - this basically is my problem, but the resolution is still in progress

4:28 raek: I know Leiningen has a workaround for it.

4:28 but it's a shame that issue hasn't been fixed yet

4:41 Cozey: and cake ?

4:41 eh! only lein supports swank-cdt, only lein workarounds this one... should I migrate to it from cake?

4:51 TobiasRaeder: Morning

4:52 bsteuber: Moin

4:54 __name__: moin

8:23 Bronsa: (defmacro my-if [test t f] `(([(fn [] ~t) (fn [] ~f)] ~(#({true 0 false 1} test)))))

8:23 :D

8:57 schani: why is (seq? [1 2 3]) false?

8:59 stuartsierra: a Vector is not a Seq

8:59 schani: yet it responds to first and rest

9:00 stuartsierra: yes

9:00 schani: is there a predicate for whether something can be firsted and rested?

9:00 stuartsierra: it's Seqable.

9:01 `seqential?`

9:01 schani: ah, awesome!

9:02 ok, then follow up question: why would i care whether something is actually 'seq?', rather than 'sequable?' ?

9:03 ebaxt: Hi, I've been trying to figure out what the idiomatic way to 'change' an element in a vector is when you don't know the index of the element. Is map the only option?

9:05 schani: ebaxt: i'd find out its index first and then do an assoc

9:06 ebaxt: schani: ok, thanks.

10:50 shtutgart: Hi. If I'll return random number from macros, it'll be unique for each compilation, right?

10:54 manutter: shtutgart: what do you mean by "return random numbers from macros"?

10:56 shtutgart: manutter: (defmacro rnd [] (rand-int 10)), then (defn foo [] (rnd))

10:57 now (foo) should return unique number for each compilation?

10:59 raek: shtutgart: yes, it will be unique for each place where foo is expanded

11:00 (defmacro duplicate [expr] [expr expr])

11:01 (duplicate (foo)) --> [(foo) (foo)] --> [3 4]

11:01 shtutgart: raek: i guess you mean rnd, not foo

11:02 raek: ...but it is considered bad for a macro to behave as my duplicate

11:02 shtutgart: sorry, yes. that is what I meant... :)

11:03 (defmacro good-duplicate [expr] `(let [x# ~expr] [x# x#]))

11:04 shtutgart: ok :) just wanted to make sure i understand everything correctly. So macros is always expanded before compilation and can't be expanded in runtime

11:04 (except eval)

11:05 raek: shtutgart: yes.

11:06 shtutgart: ok, thanks!

11:06 raek: ...and the result of a macro is sent for expansion again

11:17 ilyak: hi *

11:17 What's the best way to create a bean class in clojure?

11:18 bean class is something with a bunch of setters and an (atom {}) inside

11:18 for use with e. g. spring

11:19 shtutgart: bean fn from clojure.core returns immutable map, so probably you have to write your own function using reflection api

11:21 ilyak: No, bean fn is cool

11:21 chouser: ilyak: deftype, as long as you have interfaces to implement

11:21 or reify

11:21 ilyak: The problem is getting the java object to bean

11:22 chouser: I don't want to write the state-management code myself so I'm looking for an existing solution

11:22 because otherwise it's pretty trivial - :gen-class and stuff

11:22 However, no point of writing that code if it's already there

11:22 chouser: using :gen-class is trivial? whew!

11:24 ilyak: you want to just list your properties and have something generate your getters and setters that manipulate a map in an atom?

11:24 ilyak: chouser: Yeah, something like that

11:24 I'd like to specify what setters/getters I want and get them for free

11:25 chouser: I don't think I've seen anything like that. Might be a fun macro to write, though. :-)

11:36 ilyak: If I have a github gist, how would I figure out its parent project?

11:39 chouser: I didn't know gists had parent projects

11:40 manutter: I think some do and some don't

11:41 I've created "anonymous" gists with no related projects, so I know they don't necessarily have parent projects

11:42 edoloughlin: [org.apache.geronimo.configs/javamail "2.2.1"] in my project.clj pulls down the whole Geronimo dist. Is there a better way?

12:00 naeu: has anyone else noticed slime+swank really struggling to println data structures such as a simple vector?

12:00 (dotimes [x 300] (println ["hi" x])) really destroys my machine and freezes emacs

12:00 whereas in a cake repl, it's pretty much instantaneous

12:04 Scriptor: naeu: works fine for me

12:04 naeu: Scriptor: does it print out instantaneously?

12:04 Scriptor: naeu: just about

12:04 manutter: same here

12:04 naeu: can you try 1000?

12:04 Scriptor: I can go up to 3000 without a problem

12:04 naeu: oh wow

12:04 i'm jealous!

12:05 i'm wondering where my bottle neck is

12:05 which versions of slime and swank are you using?

12:05 manutter: naeu: is this something you've just noticed, or is it always that way?

12:05 Scriptor: running xp on macbook intel core 2 duos

12:05 *duo

12:05 naeu: manutter: it's been this way for a while

12:06 i have a very beefy machine - macbook pro core 2 i7 2.8GHz

12:06 manutter: have you seen technomancy's blog post on the super-simple way to set up swank and emacs?

12:06 naeu: yeah, but i use cake

12:06 Scriptor: naeu: do you get the same problem if you do the same in the repl in the shell?

12:06 manutter: ah

12:06 naeu: but i've tried both lein and cake and see the same results - so its not the build tool that's the issue

12:06 Scriptor: in the repl, it's instantaneous

12:07 it's just in emacs

12:07 Scriptor: damn, and as far as you know it's the latest swank-clojure?

12:07 manutter: if I were you I'd still be tempted to clean out my old emacs setup and re-install using the clojure-jack-in stuff

12:08 well, back up the old stuff and THEN clean it out, of course ;)

12:08 naeu: manutter: clojure-jack-in only works with lein though, and i need cake for my native deps

12:09 technomancy: naeu: leiningen from git should work with native deps

12:09 naeu: technomancy: cool - nice work

12:09 although to be honest, i really don't think it's either lein or cake that's the issue here

12:10 technomancy: sure, just throwing that out there. it hasn't seen a lot of use anyway since native-deps are pretty rare. what's the specific dependency?

12:10 naeu: printing via the repl is super fast, just with emacs

12:10 technomancy: it's fast here with jack-in, otherwise I'd blame a lack of byte-compilation

12:10 naeu: erm, i meant it's just with emacs that i'm seeing the issue

12:11 technomancy: what does jack-in offer for the slime communication that standard swank<->slime doesn't offer?

12:11 or does it just set them up for you?

12:11 I'm running swank 1.4.0-SNAPSHOT and the latest slime from technomancy/slime on github with emacs 23.3.1

12:13 i've tried downgrading to swank 1.3.0 and still see the issue

12:13 i've tried both terminal and GUI versions of emacs and still see the issue

12:14 basically emacs rams up to 100% cpu usage as it churns and churns to print out stuff

12:14 technomancy: naeu: the main advantage is it's just easier to install and it picks a port for you

12:14 naeu: technomancy: that sounds lovely, but i don't think it will resolve my issue

12:14 unless there's some config i'm missing?

12:15 technomancy: naeu: probably not. maybe try another distribution of Emacs? See if it happens in -nw, try compiling 24, etc.

12:15 naeu: technomancy: I've tried two separately compiled versions of emacs

12:15 but both 23.3

12:16 hang on, maybe it's this durendal stuff i'm using?

12:16 i use durendal to highlight the repl

12:16 technomancy: try it with emacs -Q too; relaunch and eval-buffer in slime.el

12:17 naeu: what does -Q do?

12:17 technomancy: oh, that would be my guess.

12:17 -Q skips all dotfiles

12:17 naeu: ah, useful

12:17 i'm going to try without durendal

12:17 i didn't think of that

12:17 here's how i plug slime in though, in case this is way off: https://github.com/samaaron/dot-emacs/blob/master/live-config/slime-conf.el

12:18 technomancy: whaaa

12:18 wait, are you saam aaron?

12:19 whoever wrote that doesn't understand what eval-after-load is for

12:19 naeu: technomancy: yep, i'm sam

12:19 technomancy: oh, hi =)

12:19 naeu: and i don't understand what eval-after-load is :-)

12:19 you're right!

12:19 and hi! :-)

12:19 technomancy: it's basically to set a hook to be eval'd after a given feature is loaded

12:20 naeu: i'm still learning emacs (it's a long slow rocky road)

12:20 technomancy: so having both eval-after-load 'slime and require 'slime in the same file is redundant

12:20 naeu: ah cool

12:20 which is idiomatic emacs lisp?

12:20 technomancy: you can use it to improve Emacs boot time if there are features you're not going to be using in every Emacs launch

12:21 naeu: ok, so that still doesn't make total sense to me

12:22 technomancy: "by the way, if you do happen to load slime at some point, here's some stuff you should do once it's loaded"

12:22 naeu: it seems that i'm usign eval-after-load 'slime to add two callbacks: slime setup and a statement to ignore versions

12:22 technomancy: it's a lot like add-hook, but it works in terms of require rather than individual defuns

12:22 naeu: i then require slime which i assume loads it?

12:22 technomancy: yup, so it's not really deferred at all

12:22 also: setq is safe to do before slime loads anyway

12:22 naeu: if it's similar to ruby's require which loads once only like a defonce

12:22 technomancy: yup

12:23 also you could collapse the two slime-setup clauses

12:23 naeu: yeah, i see that now

12:23 can i combine with a do or does emacs lisp have a different form for combining things?

12:24 i've basically avoided learning emacs lisp as much as possible as to not confuse learning clojure

12:24 technomancy: for slime-setup in particular you can just add combine the two argument lists

12:24 do is progn in elisp/cl

12:24 naeu: but now i'm pretty confident with clojure i feel i can branch out a little

12:24 * technomancy has written defun in clojure a few times; it happens

12:26 naeu: so would this be a good clean-up: https://gist.github.com/1035929

12:26 technomancy: just move the slime-setup to after the require and you shouldn't need eval-after-load

12:27 but yeah, looks better

12:27 naeu: refresh it again

12:28 technomancy: thumbs up

12:28 naeu: cool, thanks

12:28 technomancy: np

12:28 naeu: i really would benefit from working closely from someone that groks emacs

12:28 :-)

12:28 one day maybe

12:28 technomancy: one thing at a time I guess

12:29 naeu: absolutely

12:29 i feel fairly proficient with it now

12:29 which is a huge relief given the amount of work i've put into it :-)

12:29 technomancy: I have the benefit of having learned elisp first, so when I go back it just feels quaint. to someone who knows clojure, picking up elisp afresh would probably seem pretty backwards.

12:30 mrBliss: but now slime is loaded immediately, not 'autoloaded'?

12:30 naeu: ok, so it's definitely the durendal stuff that's killing me

12:30 how annoying - i like having a coloured repl

12:31 technomancy: yeah, it definitely seems backwards

12:31 i was playing around with regexps the other day - horrrrrrrible!

12:31 technomancy: =(

12:32 naeu: does emacs support the notion of contexts for highlighting?

12:32 technomancy: you can narrow the buffer down

12:32 naeu: i.e. if i'm in context A and I see regexp R then it means so and so

12:32 technomancy: but I don't think there are first-class parsing contexts

12:32 naeu: whereas if I see regexp R in context B it means something else?

12:32 technomancy: not really

12:32 naeu: that sucks

12:33 technomancy: a friend of mine is working on a framework for building modes with real composable peg parsers

12:33 naeu: TextMate had that better I think

12:33 that sounds great

12:34 technomancy: it's only in Emacs 21 that syntax highlighting was even turned on by default; back in the day it was seen as a resource hog.

12:34 naeu: haha

12:34 well, it's clearly a resource hog in my repl

12:34 technomancy: "luxury!"</yorkshiremen>

12:34 good point

12:35 offby1: you try telling that to today's young people ...

12:35 naeu: :-)

12:36 technomancy: so have you played with overtone yet?

12:36 technomancy: not yet, though once lein 1.6 is out I may give it a run. sounds like fun.

12:36 naeu: have you done much dsp stuff?

12:37 technomancy: nothing whatsoever

12:37 naeu: it's been a complete headfuck for me to understand

12:37 technomancy: my "digital art" explorations have so far been limited to a handful of Processing sketches

12:37 naeu: however, we're pretty much at the stage of working at higher level abstractions now

12:38 so the dsp stuff can be done by dsp-boffs and higher level musical structures can be written to trigger the audio

12:39 right now overtone is cool for people that know clojure and supercollider

12:39 which is basically 5 people in the world

12:39 which is pretty useless

12:39 so we're really working to make it much more accessible and usable

12:40 the first audience with be people that know clojure and don't know supercollider

12:40 and then we'll move to musicians in general

12:40 technomancy: heh; sweet

12:40 processing seems to have some good ideas re: making programmatic art accessible

12:40 naeu: processing is very nice

12:40 technomancy: shame about the syntax =)

12:40 naeu: haha

12:41 that's the great thing about lisps - syntax is not really an issue

12:41 you can always hof or macro your way out of horrible places

12:41 technomancy: if you're targetting non-programmers you can skip a lot of the "forget everything you know about programming" stage; I imagine that could save a lot of time

12:42 naeu: i'm also *very* excited to see how much leverage Clojure's concurrency stuff for music structure

12:42 ejackson: technomancy: are you implying that artists don't know anything :P ?

12:42 naeu: i believe it will be particularly useful to coordinate multiple 'band-member's' activities

12:43 technomancy: the big question is "how much programming knowledge is necessary to write music with computers?"

12:43 I believe it's probably a fair bit more than we'd like

12:44 Scriptor: naeu: As in composing regular music?

12:44 naeu: Scriptor: it depends on what you mean by regular :-)

12:45 i think if you stick to the declarative notation that is the standard Western Common Notation - then probably no programming knowledge is necessary

12:45 Scriptor: one of the programs that don't require you to directly use a programming language

12:45 naeu: however, that seems soooo limited when we have logic and other interesting notational semantics at our fingertips

12:46 i want to be able to say "occasionally, if thing is doing something over there, and this other thing is doing that, then do something special"

12:47 Scriptor: hmm, that's a neat way to look at music

12:47 almost like an event-based pattern

12:47 naeu: Scriptor: i see it as a big coordination task

12:47 Scriptor: absolutely, that's a nice way of thinking about it

12:47 Scriptor: naeu: well, as far as I know it's layering different sounds up on each other and logic thinking like that is mainly done in the head

12:47 naeu: but it's also only one way, i want to have multiple ways of expressing my composition

12:48 Scriptor: so that if you want something special to be done, you have to write it in yourself

12:48 ejackson: naeu: when you can make jazz, you have succeeded !

12:48 naeu: Scriptor: exactly - and wouldn't it be cool if you could improvise those thoughts

12:48 if you had a magic music repl to try out your ideas

12:48 Scriptor: naeu: wait, are we talking about generating music or better ways to write music yourself?

12:48 oh

12:49 there's a live music thing that uses a lisp dialect

12:49 naeu: Scriptor: both - although i'm personally less interested in generating music, rather using software to augment a performer

12:49 Scriptor: yeah, there's at least two - Common Music and Impromptu

12:50 Common Music is in CL and provides many high order functions for manipulating music concepts but typically generates midi output

12:50 Impromptu rocks but is Mac only, relies on Core Audio and isn't open source

12:51 Overtone is built with Clojure and uses SuperCollider for audio synthesis and is totally open source

12:52 and after spending a good while with Clojure, both Scheme and CL seem a bit backwards

12:53 oh yeah, I forgot to mention that Impromptu is written in a Scheme

12:53 one thing Impromptu does have is a pauseless GC - which is the only real pain running on the JVM

12:53 Scriptor: I think Clojure is spoiling me in some ways, CL and Scheme just seem much less appealing

12:54 naeu: does it use Racket or its own implementation?

12:54 naeu: Scriptor: it's own impl

12:54 or at least major parts are bespokely written

12:54 ejackson: naeu: have you seen the pauseless GC stuff that Azul are hawing ?

12:55 naeu: ejackson: yeah, i've read about it whilst drooling

12:55 ejackson: me2

12:55 naeu: they might spot you a freebie for marketing porpoises

12:55 naeu: ejackson: that would be nice, but i want to make a platform anyone can use for free

12:56 I want Overtone to be easy to hack on and easy to make music with

12:56 currently I'm working on making Overtone easy to hack on

12:56 ejackson: naeu: sure, of course, anybody can still hack on it, but a performer can then get the Azul JVM and perform w/o pauses.

12:56 naeu: ejackson: yeah, that's true

12:57 ejackson: as i understand you just switch out the JVM be

12:57 naeu: i wonder if anyone has had any success runnign clojure on the Azul JVM

12:57 ejackson: anyway, the only instrument I can play is the fool, so I'll just move along.

12:58 naeu: ejackson: we'll have you rocking a REPL somepoint in the future

12:58 ejackson: heh.

12:58 Scriptor: naeu: what's the best way to learn overtone right now?

12:59 naeu: Scriptor: come to Cambridge and hang out with me :-)

12:59 haha

12:59 actually that's an excellent question

12:59 Scriptor: cambridge, MA or England? :p

12:59 naeu: with no simple answer, unfortunately

12:59 Scriptor: the original Cambridge

12:59 none of your American name-reuse garbage

13:00 :-p

13:00 they could have at least prefixed the name to stop clashes like they did with York and Orleans

13:00 ejackson: Cherry Flavoured Cambridge (actually I was there just last week, and in Original this week)

13:01 Scriptor: heh, sounds good, I'll check out the screencast then

13:01 naeu: yeah, there are a few screencasts out there now

13:01 and I'm working on more

13:01 http://vimeo.com/22798433

13:01 http://vimeo.com/25190186

13:01 http://vimeo.com/25102399

13:02 but the last two won't be useful if you've already worked on Clojure projects before

13:02 Scriptor: which I haven't, cheers!

13:02 naeu: oh, then they should be pretty useful then

13:02 the first is how to set up clojure with emacs

13:02 the second is how to work on edge Overtone

13:03 you should also join the mailing list: http://groups.google.com/group/overtone

13:03 that's the best place to have your questions answered

13:04 and we're looking for beginner questions right now: "How do I make a simple synth?" "How to I make a basic beat?" etc.

13:04 Scriptor: awesome, I'll check it out

13:04 naeu: recently I've been spending a whole heap of time working on the guts

13:04 and it's starting to get pretty rock solid now

13:04 Scriptor: I need to find something solid to start hacking with clojure on

13:05 naeu: Scriptor: well this is something fun and engaging to work with

13:05 which i think is an excellent plaground for learning a new language

13:05 it's so much nicer to say "hey, i made it play c major!" than "hey, I sorted this list!"

13:07 Scriptor: naeu: should be good, my musical brain cells have been collecting dust for years

13:07 pdk: i knew one guy who went off to columbia U

13:07 made a music programming language there

13:07 naeu: pdk: nice, do you know the name of the lang?

13:07 pdk: it could go places as a teaching tool

13:07 nah he just mentioned it in conversation when he came back here to visit for graduation

13:08 and this was a project for a compilers course so you might have already eclipsed it :p

13:10 are you going to have a console version of this you can interact with in clojure code or is it focusing on gui

13:10 yknow what would be neat actually

13:10 drag and drop clojure

13:10 since its already a tree format basically

13:10 Scriptor: like a visual languag?

13:11 pdk: not so much a new language but

13:11 since it's already putting code in nested structures

13:11 picture dragging () into a scratch area to start

13:11 then dragging and dropping parts of forms into the middle of the () to add to it

13:12 like drag () onto scratch, drag print onto scratch and it pops up "enter arguments" and you'd type text or get another scratch area to nest forms into the print

13:12 also is this using midi or does it come with instruments prerecorded

13:13 and is the blur on the text from recording it with a camera?

13:14 Scriptor: quick java-ish question, when you implement the interfaces that make an object work like an array, will that object be able to work on any method that takes arrays for input?

13:15 pdk: are we talking ArrayList

13:15 Scriptor: I think

13:15 pdk: ArrayList<type> arrays are distinct from type[] arrays

13:16 Scriptor: ah, got it

13:18 dsesclei: Hello. I'm working on a Clojure REPL applet. In Chrome and Safari, it works the first time it is loaded, but fails if the page is refreshed and won't work again until the browser is restarted. If two tabs are opened to the applet, however, it will work fine when the page is refreshed. I'm guessing this is a problem with caching, but not really sure how to solve it. Does anyone here have an idea?

13:18 H

13:18 Here's the applet: http://66.228.47.25/applet.html

13:19 naeu: pdk: initially a console version - and eventually a GUI

13:19 pdk: there's already a nice block diagram version of scheme used for music programming

13:20 pdk: and midi is crazy old skool. The new cool is osc - open sound control, and Overtone supports both. Plus it lets you design and build your own synths using Clojure forms.

13:21 So you can use Overtone to drive midi/osc devices as well as using it to build and control your own synthesisers

13:21 pdk: how's overtone for cross platform compat

13:22 especially considering the situation with linux sound does it make that a bit less thorny for the programmer

13:22 also do you have an idea in mind for how the gui would work

13:22 naeu: pdk, works out of the box with linux and mac, windows support is there, but a bit cobwebby

13:22 pdk: something like dragging little icons that represent the forms you wrote onto musical bars?

13:22 naeu: pdk: we have a lot of ideas, but really could do with some hacking support

13:23 we're thinking of using JavaFX 2.0 when it stops being windows only

13:23 pdk: is this a team uni project now

13:23 naeu: pdk: is Overtone a team uni project?

13:24 pdk: clojure music

13:24 naeu: i don't understand the question, sorry

13:24 pdk: the project you're doing

13:25 naeu: Overtone is an open source project initiated by Jeff Rose

13:25 I hack on it quite a bit whist at uni (I'm doing a postdoc)

13:26 so it's not really a uni project

13:26 although it's mainly hacked on by people at uni

13:26 but it doesn't have any specific funding etc.

13:26 pdk: if you have any cool GUI ideas, you should totally join the mailing list and get involved

13:26 http://groups.google.com/group/overtone

13:27 right, i'm off out now. Take good care everyone

13:36 Scriptor: are just about all the seq functions implemented using straight clojure, without java interop?

13:37 dnolen: Scriptor: ?

13:40 chouser: Scriptor: most of the higher-level ones, yes. Ones like first, rest, and lazy-seq interact directly with Java classes via interop

13:41 Scriptor: dnolen: just looking at the functions listed on http://clojure.org/sequences#Sequences-The%20Seq%20library-Creating%20a%20seq

13:42 does java not have its own partition function?

13:45 chouser: Scriptor: if it did, it couldn't consume/produce Clojure lazy sequences, could it?

13:46 Scriptor: chouser: right, forgot about that

13:48 alright, time to implement them all

13:49 chouser: what!?

13:50 Scriptor: ;)

13:51 chouser: implement all the seq functions? why?

13:53 Scriptor: a good number at least, for a lisp I'm working on

13:53 chouser: ah

13:54 Why not just use Clojure? (not a rhetorical question)

13:56 Scriptor: chouser: it has its own nice, sorta, but a deal of it is for fun

13:56 chouser: it's own "nice"?

13:56 Scriptor: argh, *niche

13:56 otherwise, once I figure out my next project I'll be using clojure

13:57 chouser: heh, ah. I understand "for fun". What about the niche makes Clojure a poor fit?

13:57 Scriptor: not easy to make it work with a php codebase :D

13:58 chouser: so if Clojure compiled to PHP ...?

13:59 Scriptor: chouser: well, this compiles to PHP, but it's not quite Clojure

13:59 http://scriptor.github.com/pharen/ if you're curious

13:59 chouser: What I'm asking is, if Clojure could compile to PHP would the only reason remaining to create your own lisp be "for fun"?

14:00 Scriptor: chouser: exactly

14:00 chouser: ok!

14:00 * chouser files that one away

14:00 * gfrlog wonders how strange clojure code would look if the roles of [], (), and {} were rotated

14:00 * cemerick waits for chouser's impl to land later this afternoon :-P

14:01 Scriptor: damnit, now I have competition

14:02 chouser: nah, I have no interest in compiling Clojure to PHP.

14:02 Scriptor: though I should probably start making it more clojure-like anyway

14:02 chouser: But, making Clojure easy to extend to new target platforms, now *that*s interesting.

14:03 cemerick: …and probably a 5-year target

14:03 chouser: could be

14:03 gfrlog: if only clojure ran on the JVM then we could take advantage of that write-once-run-everywhere quality it has

14:03 * gfrlog thinks technology is weird

14:03 chouser: we're certainly not as for down that path now as I was predicting at, say, Clojure Conj 2010

14:04 hiredman: I have this idea of doing functional transforms over forms (like var resolution, etc) and using something like a secd machine for code generation

14:05 it seems nice, what little code I have

14:24 ilyak: Where is the documentation for set!?

14:24 hiredman: ~special forms

14:24 clojurebot: special forms are http://clojure.org/special_forms

14:24 hiredman: possible under java interop as well

14:29 * gfrlog wonders what set!? would do

14:29 Somelauw: try (doc set!)

14:32 ilyak: (deftype TempDir [temp-dir] Closeable (close [this] (.forceDelete temp-dir)))

14:32 What's wrong with this example?

14:32 In practice it fails with NullPointerException on .close

14:32 chouser: what does your use of it look like?

14:33 ilyak: (.close (TempDir. (File2/createNewTmpDir "www")))

14:35 chouser: hm, looks fine to me

14:36 ilyak: Oops

14:36 (TempDir. (File2/createNewTmpDir "www")) is NullPointerException already for some reason

14:37 Oh nevermind, it's auto-deref I think

15:00 It seems that ccw fails to recompile my .clj file

15:01 therefore (deftyped class doesn't get renewed

15:01 I wonder how would I force ccw to actually recompile everything on save

15:02 cemerick: ilyak: ccw isn't (intended to be) a build tool — though it does build projects in order to support its tooling functionality

15:03 chouser: cemerick, please tell us -- what is the build tool that we should use instead?

15:03 cemerick: chouser: oh, stop ;-)

15:03 * chouser giggles

15:06 cemerick: Screw it, I'm goin' back to ant.

15:12 pjstadig: chouser: make?

15:13 no, something else that starts with 'm'

15:13 :)

15:13 chouser: cemerick: Don't you dare! I don't know if I can use maven without you.

15:13 cemerick: bollocks :-)

15:14 ejackson: there would be a charm in naming a build system such

15:14 * cemerick calls dibs!

15:14 ilyak: cemerick: Well, it has run/console

15:14 therefore it shoulb be able to compile whatever it takes to present a functional run/console

15:14 should*

15:15 I totally shouldn't call ant every time I want to run something in console

15:16 pjstadig: ejackson: just as long as its not makjure or clobuild or something

15:16 cemerick: ilyak: I was being quite sarcastic in mentioning ant, BTW

15:16 ilyak: My whole project builds using ant+ivy

15:16 so that's what we use

15:17 technomancy: why not port ant to C?

15:17 cant

15:17 ilyak: I even had to undust https://github.com/alamar/clojure-ant-tasks

15:18 pjstadig: technomancy: *groan*

15:19 ilyak: by the way, I wonder why (deftype) causes such trouble

15:19 clojurebot: deftype is see datatype

15:19 ilyak: (defrecord) surely didn't

15:19 Maybe I misconfigured something

15:21 dnolen: so the relationship DCGs and monads becomes more interesting ... http://www.info.ucl.ac.be/~pvr/edcg.html ...

15:22 also Prolog seems like the only lang w/ macro systems as simple as Lisp ...

15:28 pdk: defrecord still auto implements Object

15:28 deftype starts off implementing nothing

15:41 Somelauw: I remember I installed clojure-jack-in, but it looks like it is gone.

15:42 Since the command doesn't work anymore.

15:57 I'll quit again using emacs and go back to vi.

16:18 Cozey: Hello. I'm using cake and it's project.clj, but I would also like to use some of the maven functionality - like deployment to a remote directory. However, the pom.xml is overwritten by cake, and it's not possible to add a supplementary pom, except for changing a 'global' one. any tips?

16:19 carllerche: Is there a way to get leiningen to add a classpath only when running tests?

16:21 raek: carllerche: dev-dependencies won't be included in generated jars, if that helps

16:22 carllerche: I'm trying to load different property files

16:36 technomancy: carllerche: set :dev-resources-path

16:36 carllerche: technomancy: So, the problem I'm having is that I want to set different class paths for development & tests, does lein test ignore :dev-resources-path?

16:37 technomancy: carllerche: are you trying to distinguish between development and test?

16:38 carllerche: technomancy: yes

16:38 technomancy: I would like to get different property files in development & test

16:40 technomancy: what exactly is the difference between development and test?

16:40 carllerche: technomancy: Mostly some config stuff.

16:40 So, I'm probably doing something wrong to be honest

16:40 technomancy: no, I mean... how do you tell the difference?

16:41 carllerche: technomancy: So, I am confused about that too :P lein test is obviously one way, but running tests through swank won't be able to tell

16:41 technomancy: yes, exactly what I'm getting at

16:41 carllerche: technomancy: So, what is confusing me is that it seems that clojure.contrib.logging needs a property file to get configured

16:48 hugod: anyone been able to use tools.logging with slf4j when commons-logging is on the classpath (because a dependency uses it)?

16:49 technomancy: carllerche: if you're trying to silence logs during tests, I recommend using a fixture and twiddling the level through the log4j api

16:49 if you're using log4j

16:51 hugod: the problem being that tools.logging uses commons-logging, rather than slf4j…

16:57 ordnungswidrig: has anybody already implemented a delegating wrapper for protocols? E.g. I have a instance x which implemenets some protocols Ps. Now I like to reify a new instance x' which implements Ps by delegating to x and which reifiy an addition protocol P2 by delegating the methods defined in P2 to another instance x2

16:58 chouser: you don't want to just extend x to P2?

16:59 amalloy: ordnungswidrig: i actually did that for deftypes and reifys this weekend

16:59 might be parts salvageable for protocols?

16:59 https://github.com/amalloy/ordered/blob/develop/src/deftype/delegate.clj and https://github.com/amalloy/ordered/blob/develop/src/ordered/map.clj, but likely to move around as i pull the delegating stuff into a more-general library

17:02 ordnungswidrig: amalloy: nice. it basically the same implementation I have found.

17:03 amalloy: ordnungswidrig: "found"? is this out there already? i guess i wouldn't be surprised; i was doing all this without an internet connection

17:03 ordnungswidrig: amalloy: I found it out.

17:04 howerver I do not specifiy the protocol methods but extract if from the protocol

17:06 Somelauw: what datatype do you recommend for a chessboard? I was considering to use a vector of vectors myself.

17:06 ordnungswidrig: Somelauw: no a bad choice

17:06 Somelauw: why bad?

17:07 ordnungswidrig: Somelauw: oh, sorry. I meant "not a bad choice" :-)

17:07 amalloy: i think a T got dropped in NOT

17:07 Somelauw: either a 't' or a ',' got dropped :P

17:07 ordnungswidrig: depending on your problem domain zippers can help for easy navigation

17:07 s/no/&t/

17:07 *g*

17:08 amalloy: to bad that in my case the delegate will return a new instance for every method invocation that leads to a newly reify delegator instance...

17:09 I suppose reify is costly.

17:09 amalloy: ordnungswidrig: no, reify should be pretty cheap

17:09 just a constructor call, with one argument for each local you close over

17:09 ordnungswidrig: amalloy: doesn't it generate a new java class?

17:09 amalloy: no

17:09 Somelauw: ordnungswidrig: okay, thanks

17:09 amalloy: the compilation all happens when you load the file

17:11 (let [f (fn [n] (reify IDeref (deref [this] n)))] (map f (range 5))) ;; compiles the reify once, calls its constructor five times, with a different arg each time

17:12 &(map class (let [f (fn [n] (reify clojure.lang.IDeref (deref [this] n)))] (map f (range 5))))

17:12 sexpbot: ⟹ (sandbox10562$eval12633$f$reify__12635 sandbox10562$eval12633$f$reify__12635 sandbox10562$eval12633$f$reify__12635 sandbox10562$eval12633$f$reify__12635 sandbox10562$eval12633$f$reify__12635)

17:12 amalloy: ordnungswidrig: as you can see they all have the exact same class

17:13 ordnungswidrig: amalloy: I have a different case here: a macro which evaluates to a reify call where the protocol implementation functions will call the macro itself at runtime.

17:13 amalloy: uh

17:13 ordnungswidrig: maybe I'm a little too meta here.

17:13 amalloy: you're eval'ing at runtime? then yeah, everything will be expensive

17:14 ordnungswidrig: not a literal eval but a reify at runtime

17:14 amalloy: ordnungswidrig: i think you're confused. my example above did five reifies, at runtime, and only compiled anything once; if you're not using eval, it's hard for me to imagine how you could do otherwise

17:14 do you have some example code?

17:17 manutter: Somelauw: you were saying your clojure-jack-in wasn't there after you installed it?

17:17 Somelauw: (sry, catching up on my scrollback here...)

17:17 amalloy: chouser: would it be wrong for me to say that it's very hard to compile something at runtime without using eval?

17:18 ordnungswidrig: https://gist.github.com/82de4ebfd6a331c029a2

17:18 Somelauw: manutter: yes

17:18 amalloy: (or, a macro that uses eval)

17:18 Somelauw: manutter: I remember having installed it.

17:18 chouser: amalloy: hm. what about 'compile'?

17:18 manutter: Somelauw: I had a similar issue -- I think it was because I installed clojure-mode.el manually instead of via packages

17:18 chouser: (doc compile)

17:18 clojurebot: "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."

17:19 chouser: amalloy: I think I might agree with the gist of that statement, but maybe quibble over the word "hard" or something.

17:19 ordnungswidrig: I'm defining a function o using letfn which call reify (via another macro). This function o is used by the functions used in the reification[sic?].

17:19 manutter: Somelauw: it was an easy fix, (add-to-path 'autoload "~/.emacs.d") (require 'clojure-mode) in my .emacs file

17:19 amalloy: *chuckle*

17:19 Somelauw: manutter: So how should clojure-mode be installed. Using packagage-install?

17:20 manutter: Somelauw: That's off the top of my head but I think I got the syntax right

17:20 chouser: "undesirable" or something instead?

17:20 manutter: Somelauw: I had put clojure-mode.el in my ~/.emacs.d directory of course

17:20 amalloy: chouser: i guess what i meant was "hard to do accidentally"

17:21 manutter: Somelauw: yeah, I think package-install is the technically correct way to do it

17:21 Somelauw: manutter: After I did that, should I reinstall clojure-drop-in?

17:21 amalloy: ordnungswidrig: that all happens at compile-time. each call to make-dispatcher will expand into a new reify body, which will be compiled as the macro is expanded

17:21 manutter: Somelauw: Once I did that everything worked again

17:21 amalloy: you can't expand the macro "at runtime" without eval, so it will be mostly just a constructor invocation

17:21 chouser: amalloy: ah! yeah, that might be good

17:21 ordnungswidrig: amalloy: hmm, I think that's correct

17:22 manutter: Somelauw: I didn't need to do anything else (except open a new emacs)

17:22 ordnungswidrig: amalloy: but the type reported by "type" changes after every invocation of a delegated method!

17:25 Somelauw: manutter: It says: Symbol's function definition is void: add-to-path

17:25 amalloy: Somelauw: probably you want add-to-list

17:26 usually that's like (add-to-list 'load-path "some-directory")

17:27 Somelauw: After doing add-to-list: Symbol's value as variable is void: autoload

17:27 manutter: Somelauw: Yeah, I'm not fluent in elisp yet, sorry

17:28 hiredman: Somelauw: what version of emacs are you using?

17:28 Somelauw: me neither.

17:28 emacs 23

17:28 manutter: Somelauw: try (add-to-list 'load-path "~/.emacs.d")

17:28 Somelauw: and if that works give amalloy the credit :)

17:29 Somelauw: It doesn't crash, but it doesn't work either.

17:30 But should there be a file called clojure-mode in emacs.d?

17:30 Since I can't find that file either.

17:30 Or directory

17:31 amalloy: Somelauw: you're looking for clojure-mode.el

17:31 technomancy: sounds like Somelauw is lost, but i don't really know the details of the "distribution"-like things you do for clojure-mode

17:32 Somelauw: I think I will need to reinstall it or something.

17:32 * technomancy reads backlog

17:32 manutter: Somelauw: yeah it sounds like the problem you're having is different than the one I was having

17:32 technomancy: it should be in ~/.emacs.d/elpa/clojure-mode-1.x.x/

17:32 amalloy: Somelauw: see, when in doubt highlight the expert's nick

17:33 manutter: Ok, you're in capable hands here, I'll take off now :)

17:33 Somelauw: okay, thanks

17:33 I will try a reinstall.

17:39 Okay, I got it to work again.

17:46 ordnungswidrig: amalloy: I solved the mystery of runtime reification: for every macro-invokation (at the repl) you'll get a different implementation, of coure.

17:46 amalloy: yep

17:48 ordnungswidrig: I'm really lost in macro-meta-space

19:54 amalloy: anyone know why there aren't (or know that there in fact is) transient versions of sorted-set and sorted-map?

20:02 TimMc: Time for me to look up how the transients are implemented.

20:05 transient takes a c.l.IEditableCollection, conj! take ITransientCollection.

20:10 amalloy: sorted-{map,set} are backed by PersistentTree{Map,Set}, which do not implement IEditableCollection.

20:11 amalloy: TimMc: yes, i realize that. i'm asking if there's a reason they don't implement it

20:11 TimMc: just exploring

20:15 I'd like to know as well.

20:16 amalloy: TimMc: i suspect it's just a lot of work to write, and rich didn't think it was worth the time

20:18 scgilardi: http://groups.google.com/group/clojure/browse_thread/thread/1281d1f7bfc6c5fa has a discussion about it (from long ago)

20:18 TimMc: amalloy: My guess was that you could bang on a transient and then sort it.

20:19 amalloy: scgilardi: thanks

20:20 TimMc: not really satisfying. say i have 2M entries in a sorted set; just calling (persistent! (transient s)) would be O(n) for pouring stuff in and out of the non-sorted version

20:20 nlogn, really, since sorting would have to happen on the way back out

20:22 TimMc: Hmm.

20:22 Depends on how much hammering you are doing, then.

20:23 If you will mutate it n^2 times, it might be worth it. :-P

20:23 hiredman: obviously we should just sit around and complain about not having pods

20:24 amalloy: (inc hiredman)

20:24 sexpbot: ⟹ 3

20:36 kir: hmm

20:36 actually a decent number of people here

20:37 amalloy: kirroyale: no decent people though

20:37 kirroyale: well obviously

20:37 I'm in an irc channel

20:37 dnolen: kirroyale: ha! #clojure is one of the more civilized irc spots.

20:38 kirroyale: Then I will most likely be in shock for a while

20:38 I usually frequent the less civilized ones

20:38 However I doubt I'd get any useful answers or even any answers at all there :p

20:49 any decent genetic algorithm libraries written in clojure?

20:50 TimMc: How much could really be shared between multiple genetic algorithms?

20:50 SO much is specific to the domain.

20:51 kirroyale: That's why a framework for easily defining genetic algorithm domains

20:52 TimMc: hmm

20:52 eliantor: hi everyone

20:52 TimMc: kirroyale: I suppose a framework would be useful.

20:52 kirroyale: I think so :p

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

20:52 kirroyale: And given clojure is highly extensible anyway as the whole code as data thing goes

20:53 seems like clojure/lisp is THE language to do it in

21:00 * kirroyale yawns

21:04 eliantor: is it possible to extend a protocol to a specific instance?

21:04 amalloy: eliantor: no, and i'm not sure why you would?

21:06 dnolen: eliantor: you can create a single instance that implements a protocol w/ reify though.

21:07 amalloy: dnolen: that uses the protocol's auto-generated interface rather than the protocol itself, right? not that i'm saying that's bad for eliantor, just curious

21:07 eliantor: dnolen: but it would not retain the identity... i mean like ruby singleton methods

21:08 dnolen: eliantor: what do you mean "it would not retain the identity" ?

21:08 amalloy: eliantor: no, you cannot modify an object once it is created

21:08 dnolen: kirroyale: this looks interesting, http://www.cl-user.net/asp/libs/GECO

21:09 amalloy: dnolen: (let [x 10, implementing (reify whatever (method [this] (...use x...)))] (identical? x implementing))

21:09 dnolen: kirroyale: seems like protocols would be a good way to build a performant genetic algo lib along these lines.

21:10 amalloy: eliantor: the desired behavior is easily preserved by implemnet equals tho right?

21:10 amalloy: dnolen: the desired behavior is a little crazy

21:10 eliantor: i was tring to attach values to something, like metadata... and it seemed to me a way to solve that

21:11 dnolen: identical? use seems to me only idiomatic for perf reasons.

21:11 eliantor: but i'm just learning :)

21:11 dnolen: or subtle algorithms.

21:12 eliantor: so you just want to make a singleton?

21:18 eliantor: dnolen: https://gist.github.com/1037018

21:18 suppose i want to have something like that

21:18 for a class that don't have metadata

21:19 kirroyale: I'll take a look dnolen

21:19 eliantor: is there a way to do that? i thought that having something like ruby singleton methods, would allow that

21:20 dnolen: eliantor: yeah you can't add metadata to objects you don't control, even more impossible w/ primitive types.

21:21 eliantor: invokeDynamic or a very fancy reflection powered macro can simplify the object case, but not the primitive case.

21:24 eliantor: dnolen: well the primitive was just an example, it's anyhow impossible to do in a simple way for objects too... i guess.

21:25 dnolen: eliantor: yes no simple way. it's advantage of the Ruby/Objective-C/Smalltalk model that Clojure simply does not enjoy.

21:28 amalloy: dnolen: since you're here, i wonder if you can help me with achieving some java performance, or figuring out why i'm not

21:28 eliantor: dnolen: would it be heavy to support (performance wise) or is it a design choice?

21:29 kirroyale: really do need to learn clojure better

21:29 oh well

21:29 dnolen: eliantor: JVM limitation really - fundamentally early bound design. invokeDynamic is the proper solution.

21:29 kirroyale: anyway back to idle

21:30 dnolen: amalloy: what's up?

21:30 amalloy: dnolen: i'm implementing "ordered maps" that retain insertion order; my current draft is at https://github.com/amalloy/ordered/blob/feature%2Fmulti-map/src/ordered/map.clj

21:31 dnolen: eliantor: Clojure will probably get invokeDynamic support at some point but it's very JDK 7 centric, and Clojure supports JDK 5.

21:31 amalloy: i've also implemented ordered sets, layered on top of those in the same way that sets are built on top of maps in clojure.core

21:31 when i compare my (reflection-free) implementation with the pure-java implementation ninjudd did a while ago at https://github.com/ninjudd/ordered-set/blob/master/src/jvm/clojure/lang/PersistentOrderedSet.java, his is 3-4 times as fast

21:32 dnolen: amalloy: is this using fn maps + extend-type ?

21:32 amalloy: dnolen: deftype

21:32 (inline)

21:33 the map in my deftype is for automatically delegating methods to an instance field

21:35 the basic algorithm is to keep one map of keys=>[index, value] pairs, and another of index=>[key, value] pairs, so that you can do fast insertions and fast dissocs while still keeping ordering

21:35 in practice i've split the key=>index/value map into two maps, so that i can delegate getter methods to the key=>value map directly

21:36 dnolen: amalloy: and you observe the perf difference where?

21:38 amalloy: dnolen: conj and into are my test cases: see src/bench/set.clj. my benchmarking is to call, from swank,

21:38 (do (System/gc) (time (dotimes [n 10] (into-stress-test :m (amalloy/ordered-set))))) ; and again with ninjudd's

21:40 for disj i beat the bejeezus out of him, because i overwrite the vector with nils instead of shrinking it

21:41 ninjudd: amalloy: you were actually beating the bejeezus out of me across the board until i suggested you change it ;)

21:41 dnolen: amalloy: can't run your code because of your utils dep I think.

21:42 amalloy: dnolen: dang, sorry, i didn't push that

21:43 dnolen: should be on clojars now

21:43 though i think i'm not even using the function from my utils anymore; you could delete the dependency if you want

21:44 oh, that's a lie

21:44 ninjudd: oh. i misunderstood. i guess mine was faster. too bad. i was hoping to never write another line of Java again

21:48 dnolen: amalloy: hmm seems like lib is not on clojars yet, and you do use transform-if from yr utils.

21:49 amalloy: dnolen: hm. i pushed, so it should be there. but i'm not actually using transform-if anymore; i'll push something with no deps in a minute

21:53 dnolen: updated version on github now, no dependency on amalloy-utils

21:54 (additionally, clojurebot seems to think my push to clojars worked)

21:57 dnolen: amalloy: in checkout I only have bench/map.clj not bench/set.clj

21:57 amalloy: dnolen: git checkout feature/multi-map

Logging service provided by n01se.net