#clojure log - Feb 08 2011

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

0:44 defn: first madison, WI #clojure meetup, complete.

1:04 bartj: er, I am not able to understand the difference b/w re-find and re-matches

1:05 amalloy: ##(doc re-find) ##(doc re-matches)

1:05 sexpbot: (doc re-find) ⟹ "([m] [re s]); Returns the next regex match, if any, of string to pattern, using java.util.regex.Matcher.find(). Uses re-groups to return the groups."

1:05 (doc re-matches) ⟹ "([re s]); Returns the match, if any, of string to pattern, using java.util.regex.Matcher.matches(). Uses re-groups to return the groups."

1:05 clojurebot: "([m] [re s]); Returns the next regex match, if any, of string to pattern, using java.util.regex.Matcher.find(). Uses re-groups to return the groups."

1:05 "([re s]); Returns the match, if any, of string to pattern, using java.util.regex.Matcher.matches(). Uses re-groups to return the groups."

1:06 amalloy: whoops. silly bots

1:06 defn: $(doc re-groups)

1:06 #(doc re-groups)

1:06 ...

1:06 ,(doc re-groups)

1:06 clojurebot: "([m]); Returns the groups from the most recent match/find. If there are no nested groups, returns a string of the entire match. If there are nested groups, returns a vector of the groups, the first ...

1:06 amalloy: bartj: re-find lets you reuse a matcher object

1:07 to search the same string multiple times (though usually you'd prefer re-seq)

1:10 bartj: for all practical purposes, re-seq seems pretty similar to re-matches

1:10 except that re-seq puts the whole match in a seq

1:15 bytecolor: am I correct in assuming there is no way to seed the core random functions? rand, rand-int, and rand-nth

1:16 since they use the rand method of Math, which creates an instance of java.util.Random, afaik

1:38 defn: bytecolor: http://richhickey.github.com/clojure-contrib/probabilities.random-numbers-api.html ???

3:43 Arelius: Excuse me if this question shows a terriable misunderstanding of how variable bindings work but:

3:43 I have a function that I call a bunch to populate a list, this is only done once at load-time.

3:44 Do I have to wrap it in a ref or atom or some such, or is constantally re (def ...) ing it going to work?

3:44 It seems to work fine, but I am also running it from SLIME, so I don't know if that's always going to be the case.

3:45 brehaut: Arelius: if i understand what you are saying, i think theanswer is no. but can you please give an example of your usage?

3:45 Arelius: brehaut: yeah....

3:45 brehaut: am i correct that you are not redefining your list?

3:46 Arelius: Well, I am, second

3:46 brehaut: eg you are doing something like (def my-list (my-complex operation))

3:48 Arelius: Something simple like this: https://gist.github.com/816118

3:48 brehaut: defun ?

3:48 Arelius: defn

3:48 sorry

3:48 brehaut: np

3:49 Arelius: I come from a Common Lisp background.

3:49 brehaut: i think that will actually work in clj1.2

3:49 but not in 1.3 unless you explicity set the var to dynamic

3:49 however i wouldnt recommend it

3:50 Arelius: So, all the appending to the list will pretty much happen at initialization time. so it seems a bit overkill to wrap it with a ref or something.

3:50 Dranik: Arelius, that is awfully not idiomatical

3:51 you should firstly compute the whole list and only then bind it to L

3:51 since all the data is persistent

3:51 it can't be changed

3:51 Arelius: Dranik: Ideally, yes...

3:51 But I'd like to be able to create it from Macros littered through the code.

3:51 brehaut: yikes

3:51 Arelius: and having to constrain all the macros to one place would be less than ideal.

3:52 Dranik: Arelius, if you are totally sure you need a mutable variable then use refs

3:52 it's easy

3:52 brehaut: Arelius: its not overkill to be explicit about your mutables in clojure

3:52 Dranik: Arelius, but your gist seems to me simple and you may use persistent data

3:52 brehaut: even if they only mutate at load time

3:53 Arelius: Well, I could solve the problem without mutables by writting a pre-processor that would look for all instances of (add-item ...) and put them into a single place.

3:53 For instance.

3:53 brehaut: Arelius: use use a ref or var

3:53 s/use use/just use/

3:53 sexpbot: <brehaut> Arelius: just use a ref or var

3:54 Arelius: Ok, I can do that. I just figured there would be a better way to do that sort of thing.

3:54 brehaut: s/var/atom/

3:54 it denotes clearly to any reader that the var is subject to change

3:54 Arelius: Would it change it if add-item were a macro?

3:54 brehaut: IMO no

3:54 Dranik: Arelius, guess it's ok to use mutables in macross

3:55 bcs it is totally another environment. single-threaded usually

3:55 brehaut: Arelius: the other option is using the earmuffs idiom

3:55 Arelius: earmuffs?

3:56 brehaut: (def ^:dynamic *my-munged-var* [])

3:56 and use set! rather than def

3:56 oh

3:56 huh

3:56 Arelius: How is that differen't then ref?

3:57 brehaut: a ref is an STM variable

3:57 it can only be updated in a transactional context

3:57 and it is coordinated with any other transaction editing the same ref, and any other refs in the same transaction

3:58 Arelius: see http://clojure.org/vars http://clojure.org/refs and http://clojure.org/atoms

3:58 Arelius: How are dynamic variables protected?

3:58 brehaut: I read all those, have no idea how dynamic fits into it.

3:59 brehaut: dynamic is metadata

3:59 otherwise your hack is going to stop working in 1.3

3:59 Arelius: hmm...

3:59 brehaut: in clj 1.2 and lower vars are as dynamic as possible by default

3:59 in 1.3 they are static by default and dynamic with meta data

3:59 Arelius: Anyways, I tried to flesh out the example a bit, incase this gives you a better understanding: https://gist.github.com/816134

4:00 brehaut: if you try that code with what you have now split over two files it definately wont work

4:00 Arelius: Because of namespaces?

4:00 brehaut: yes

4:01 Arelius: Sure, it's not a compilable example, but I think it otherwise gets the point across?

4:01 brehaut: yes

4:01 its not much different to multimethods

4:01 Arelius: Yes

4:02 brehaut: honestly though, i think an atom is probably simpliest

4:02 Arelius: How are the decleration of multi-methods updated?

4:02 brehaut: theres a mutable object behind the scenes

4:03 Arelius: with like dynamic, ref, atom, etc?

4:03 brehaut: clojure.lang.MultiFn

4:03 its possible to create something similar using deftype i believe

4:04 (deftype is the low level abstraction implementation feature)

4:05 Arelius: Sure, so deftype, and some sort of mutable object?

4:05 brehaut: deftype _is_ the mutable object

4:05 Arelius: Ohh, hmm

4:05 brehaut: but seriously, just use an atom

4:06 its much easier, its all you'll need, its thread safe

4:06 and its very little overhead

4:06 Arelius: Ok, I can do that

4:07 brehaut: (def L (atom []) (defn addItem [i] (swap! L #(conj % i)))

4:07 Arelius: Also, any links on the dynamic metadata, not sure I understand that yet.

4:07 brehaut: dont worry about it then

4:07 its just something you would have to encounter if you went down the var route

4:08 Arelius: brehaut: Sure. I still would like to understand what it is, so if I ever encounter, or have a reason to in the future.

4:08 brehaut: its real simple

4:08 ^ is the metadata reader macro

4:08 it attaches the next form as metadata to the form after

4:08 Arelius: Sure, but about the annotation itself, how that works. and when dynamic variable break.

4:09 brehaut: :dynamic affects vars, and only vars in clojure 1.3 (currently in alpha)

4:09 Arelius: I assume they break when I try to touch them in threads. But I'm not very clear why. are they really just fully mutable?

4:09 brehaut: no in 1.3 they are static by default

4:09 once defined, you cannot redefine them

4:09 Arelius: less I set them as :dynamic.

4:09 brehaut: exactly

4:10 Arelius: So, that'd allow me to change the decleration. In what manner does that break when I have threads running.

4:10 brehaut: threads are different

4:10 atoms or refs will provide thread safety

4:11 vars do not traverse thread boundaries

4:11 Arelius: Ahh...

4:11 brehaut: (or more correctly, _changes_ to bindings do not)

4:11 Arelius: So, if I have another thread running, it wouldn't catch the variable update?

4:11 brehaut: correct

4:12 Arelius: but presumablly, if I create another thread after updating the decl. that thread should have the new decl?

4:12 from, of course the thread it was updated in.

4:12 brehaut: yes

4:12 Arelius: Ok. that makes sense. thanks.

4:13 brehaut: no worries

4:36 TobiasRaeder: morning

5:39 Jewtaeus_maximus: Hi, I'm completely and utterly new here, why doesn't clojure support TCO?

5:45 AWizzArd: Jewtaeus_maximus: because the JVM doesn't support this.

5:46 Jewtaeus_maximus: but for all practical purposes you can use Clojure as if it supported TCO. CLJ has 'recur' and trampolines.

5:46 Jewtaeus_maximus: AWizzArd, how do trampolines work?

5:52 AWizzArd: Jewtaeus_maximus: http://goo.gl/yuCiO

5:55 ejackson: Jewtaeus_maximus: also, in Clojure, you rarely want to write in a 'Schemey' style. Rather use the seq abstraction either by constructing your only lazy-seqs or using the myriad built in functions.

5:57 so you end up not needing TCO

6:18 Jewtaeus_maximus: So trampoline is more or less: (defn trampoline [f] (if (Fn? f) (recur (f)) f))), AWizzArd?

6:24 clgv: Jewtaeus_maximus: almost. have a look here: https://github.com/clojure/clojure/blob/b578c69d7480f621841ebcafdfa98e33fcb765f6/src/clj/clojure/core.clj#L5040

6:26 Jewtaeus_maximus: So f you do (trampoline 3) it reports an error?

6:26 clgv: &(trampoline 3)

6:26 sexpbot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

6:26 clgv: yes^^

6:28 Jewtaeus_maximus: What if I want the final return value of some mutual recursion to be a funtion?

6:29 clgv: maybe, you could wrap into some data. but does it really makes sense that way?

7:44 AWizzArd: $seen rhickey

7:44 sexpbot: rhickey was last seen quitting 18 hours and 20 minutes ago.

7:47 AWizzArd: Btw, to the +/- 50 german users: There is also a #Clojure.de channel.

8:19 Vinzent: flatten always saves order of the elements in coll, right? e.g. things like (flatten [[1 2][3 4]]) always results in (1 2 3 4)?

8:44 opqdonut: Vinzent: that's the idea, yes

8:44 MoUsSoR: hi, can somebody help me here about a jreality pb ... ?

8:46 Vinzent: opqdonut, ok, i just wanted to make sure

9:04 rahcola: are sorted-sets homogeneous only?

9:05 &(sorted-set :a 1 :b)

9:05 sexpbot: java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number

9:06 ejackson: rahcola: if you use a sorted-set-by you can pass a Comparator that can handle inhomogenous sets, otherwise, no.

10:02 khali: I'm putting a jar in lib/ and calling lein uberjar doesn't include it in the final jar. Any ways around this?

10:04 mefesto: khali: you probably have to install that jar first then include it as a dependency in your project.clj. just my guess.

10:05 khali: is this a jar that isn't available on any repository (clojars, maven) ?

10:06 khali: yes it is available but it's a newer version than those

10:07 mefesto: khali: this is probably the long way around of doing this (i'm not too familiar with all lein's features) but if you have maven installed you can update your local repository with the jar yourself (e.g. mvn install:install-file)

10:08 once you do that and specify the groupId, artifact, etc then you can depend on that specific version in your project

10:09 that's what we do here with some proprietary libs (like oracle's jdbc driver) that aren't available on maven

10:09 khali: mefesto, cool thanks, i'll try that!

10:22 clgv: khali: but putting a jar in the lib directory should work to. it does here. maybe your project.clj specified a different directory name?

10:23 khali: well when i put it into libs after calling lein it actually gets deleted, and that's without mentioning it in the project.clj file..

10:23 mefesto: any ring users around?

10:25 clgv: khali: ah well I know that behaviour. add the following to your project.clj: :disable-implicit-clean true

10:28 khali: clgv, oh that did the trick, cheers.

10:36 hm, final question. im slime how do i change to a given namespace?

10:38 raek: khali: C-c M-p

10:39 TimMc: So, I'm going to try to write a Swing app in Clojure. I know a little about Refs and a reasonable amount about threading in Java. Where should I start?

10:39 (I.e. I have no idea how to use Clojure's concurrency idioms for this.)

10:40 khali: TimMc, i'm attempting the same thing :)

10:40 raek, legend, now i'm set!

10:46 TimMc: khali: Have you made progress on it?

10:50 bartj: is there a light-weight Clojure library to do mean/median computations other than incanter ?

10:50 *are

10:51 khali: TimMc, kind of, i first wrote it using netbeans with enclojure, and did the gui using matisse. now i'm trying to do using clojure only and laying it out using miglayout

10:53 TimMc, but i'm very new to clojure.. only started learning it a few days ago :)

10:56 TimMc: khali: Roughly the same here.

10:57 I've written a graphics app in Clojure before, but not one with interactivity or concurrency.

10:57 Just one big window with a non-animated (but dynamically generated) drawing.

10:58 khali: TimMc, have you looked at the ants example? wonder if that would give some clues..

10:58 odyssomay: TimMc, khali http://www.dreamincode.net/code/snippet3252.htm

10:59 khali: odyssomay, cheers!

11:00 TimMc: odyssomay: Ah, that looks helpful -- it has explicit global state, which the temperature converter example does not.

11:01 I see that there are some dosync blocks with side-effects -- is that kosher?

11:01 Chousuke: hmm

11:01 probably not

11:03 I doubt that code is correct in the general case

11:04 khali: chouser, whats the general principle to obey?

11:04 Chousuke, rather

11:04 Chousuke: no side-effects whatsoever in dosync blocks :P

11:05 dnolen: Clojure + Swing using agents - http://stuartsierra.com/2010/01/08/agents-of-swing

11:05 Chousuke: the event handlers won't probably get executed in multiple threads simultaneously but you might get retries at the very least

11:06 so you'd get a number of redundant .grabFocus and .setText calling.

11:07 integrating a stateful UI library with Clojure's STM and functional programming unfortunately isn't trivial :(

11:07 I guess agents are a good bet

11:07 update data in a functional way, send UI updates to an agent which then applies them.

11:09 TimMc: My program will have a drawing canvas and some buttons, with user interaction constrained by global state.

11:09 Chousuke: though if you absolutely must never have the UI go out of sync with the data model even for a moment, even that might not work :/

11:09 raek: khali: TimMc: check out c.c.swing-utils (especially the do-swing fn) for executing gui code in the swing thread (which swing requires)

11:09 TimMc: The most difficult interaction will be when the user is dragging stuff on the canvas.

11:09 Chousuke: yeah.

11:11 raek: this is how I do it for a small project: https://github.com/raek/thiudinassus/blob/master/src/thiudinassus/graphics.clj#L168

11:11 TimMc: This will be a double-buffered canvas. If I keep updating the state of some global Ref from the event thread, could I use an agent to update the canvas image?

11:11 raek: pics: http://raek.se/thiudinassus/

11:11 (*very* basic, though)

11:14 gfrlog: is there a function in the core libraries or contrib for getting a list of files in the filesystem?

11:15 clgv: java.io?

11:15 gfrlog: like (clojure.contrib.shell-out/sh "ls")

11:15 fliebel: morning

11:15 gfrlog: yes of course java -- that's what I was trying to avoid

11:16 hoeck: gfrlog: maybe file-seq ? was once there as an example of using tree-seq

11:16 gfrlog: ,(doc file-seq)

11:16 clojurebot: "([dir]); A tree seq on java.io.Files"

11:17 gfrlog: hoeck: that looks quite promising, thank

11:17 s

11:17 clojurebot: I don't understand.

11:17 raek: gfrlog: the File class has a method for that

11:18 ah, just read "that's what I was trying to avoid"

11:18 gfrlog: yeah -- it seemed like the sort of thing that is common enough to have been wrapped already

11:18 hoeck: raek: how is that colortheme called? (on those screenshots)

11:18 raek: clojure tends to not add something when a working version exists in java-land

11:19 hoeck: tangotango

11:19 hoeck: raek: thx

11:19 raek: don't have the URL atm. there exists multiple versions, I think.

11:20 it is problably this one: http://orgmode.org/worg/color-themes/color-theme-tangotango.el

11:21 hoeck: raek: just found a one on github too, looks nice and I need some change :)

11:21 khali: hm, swank-clojure-project hangs on 'Polling "/tmp/slim.10147" .. (Abort with

11:21 M-x slime-abort connection')

11:22 i've started swank using lein swank in the project directory though

11:24 fliebel: Has anyone in here followed the async ring discussion( http://groups.google.com/group/ring-clojure/browse_thread/thread/243f452c915356c8/ ) a bit? I would like to understand what is proposed here, since Ring does already support OutputStreams and lazy seqs. There was one short message that mentioned this, and talked about duplex, what is meant by this?

11:26 raek: khali: if you have started swank manually, connect to it with slime-connect

11:27 khali: raek, i tried that but it cant 'see' the namespace of my app (in the repl)

11:27 raek: khali: have you loaded it?

11:28 i.e. pressed C-c C-k in the source file buffer or executed (require 'the-ns)

11:29 or, what do you mean by "see"?

11:30 gfrlog: isn't there a macro-thing like (let) that lets all the bindings refer to eachother?

11:30 pdk: binding probably does that

11:31 letfn if it's all functions and you need them to refer to each other

11:31 gfrlog: maybe "...that allows all the bindings..." is a less confusing way to say that

11:31 fliebel: gfrlog: letfn might be useful.

11:31 gfrlog: thanks

11:31 raek: gfrlog: in let, a binding can refer to previously letted values

11:31 gfrlog: raek: I have a pair that are mutually dependent

11:31 my first solution was to use an atom, which is terrible

11:31 raek: gfrlog: but letfn allows you to let a number of functions that are mutually recursive

11:32 khali: raek, require worked

11:32 raek, im ok now

11:32 raek: gravity: let is works immutably, and immutable values cannot be mutually referring

11:33 fliebel: gfrlog: If you feel hacky, you can try #'symbol, or let one of them as nil first, or whatever.

12:04 willtim: hi guys, is this a bug in clojure?

12:04 KirinDave: willtim: This irc message?

12:05 willtim: for [:let [xs [1 2 3]] x xs] x)

12:06 i.e. :let does not work as the first binding

12:06 which can be useful sometimes and saves nesting

12:08 jkkramer: willtim: :let, :while, and :when are modifiers of the binding (you can have different modifiers for each binding), so no

12:17 willtim: @jkkramer, yes makes sense, thanks

12:20 khali: it was painful to setup but now that i have, slime+clojure rules for swing programming.. :)

12:20 odyssomay: Does 'send' spawn a new thread?

12:24 Hmm, it seems like it uses a thread from a thread pool

12:24 ejackson: odyssomay: send-off starts a new thread entirely, I believe

12:25 odyssomay: ejackson, ok, thanks

12:29 willtim: @jkkramer, interestingly, haskell does not have this limitation and guards can be at the top of a comprehension (checking input)

12:35 jkkramer: willtim: i think using (let [xs ...] (for [x xs] ...)) is clearer anyway. your way messes with my internal dialog: "for let something x in xs ..."

12:36 TimMc: willtim: macro time! :-P

12:53 weilawei: http://pastie.org/1541676 < I get "java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn" when attempting to run iter-fib (on anything, seemingly). It's an exercise from SICP. What am I missing?

12:54 Never mind, got it.

12:55 Tried to evalulate a value. >_<

12:55 TimMc: OK, what's the difference between ^String and #^String in the arguments to a function?

12:56 jkkramer: TimMc: #^String is the old, deprecated way of type hinting

12:57 TimMc: Gotcha.

13:25 jweiss: this page seems to be out of date: http://clojure.org/protocols

13:25 talks about 1.2 being unreleased

13:31 khali: am i missing something or is there no function to find the length of a sequence?

13:31 odyssomay: khali, count

13:31 khali: ooh

13:32 odyssomay: ;) it was the same for me

13:32 khali: it makes sense, i guess sometimes you need to compute it, and count is more precise

13:34 {aaron}: hi. what does a - in front of a function name mean?

13:34 e.g. http://codingkata.org/katas/unit/hello-world/solutions/view/8

13:35 amalloy: {aaron}: by default, gen-class causes -foo to become MyClass.foo, i believe

13:36 {aaron}: ah

13:36 that makes sense, thanks

13:36 amalloy: khali: you can also use ##(counted? (range 10)) to determine whether the count will be fast or not

13:36 sexpbot: ⟹ false

13:39 khali: amalloy, over my head atm, but i'll jot it down for later

13:40 TimMc: khali: counted? tells you whether a collection computes its count in constant time.

13:40 amalloy: khali: lists and vectors store their count in every node, so that (count some-vec) takes constant time; lazy sequences can't do that of course

13:40 khali: oh understood :)

13:41 i meant the usage of ## there

13:41 amalloy: oh that just triggers sexpbot

13:41 khali: ah

13:41 TimMc: so ##3 should give me...

13:41 amalloy: TimMc: nope, sorry

13:41 TimMc: maybe ##(+ 2 3) then

13:41 sexpbot: ⟹ 5

13:41 TimMc: ah

13:42 amalloy: &3 though, of course

13:42 sexpbot: ⟹ 3

13:42 TimMc: Why of course?

13:42 amalloy: well

13:42 starting a message with & is an unambiguous "sexpbot do this for me" command

13:42 TimMc: Got it.

13:42 amalloy: the ##hashmarks might be referring to ##java, for example, so he only wakes up if the thing you're trying to eval is a sequence of some kind

13:43 TimMc: Good point. And I see that clojurebot responds to , as a command trigger.

13:43 amalloy: indeed

13:44 well, an eval trigger, anyway. sexpbot has a separate "command" structure starting with $, and clojurebot treats ~ as command

13:44 $seen cemerick

13:44 sexpbot: cemerick was last seen quitting 16 hours and 59 minutes ago.

13:45 TimMc: Back to type hints... I have a vector (currently of known length) of Point2D$Double that I am decomposing in a let and using in Java graphics calls.

13:45 I'd like to get rid of reflection here. Is there a way to mark the whole vector as only containing Point2D$Double, or will I have to hint that each thing I take out is an instance of that?

13:46 amalloy: TimMc: the latter

13:46 or you can copy it all into a native java array and type-hint that

13:46 TimMc: Ah, I'll keep that in mind!

13:47 amalloy: though the syntax for type-hinting it will be pretty gross iirc

13:47 &(import java.awt.Point2D$Double)

13:47 sexpbot: java.lang.ClassNotFoundException: java.awt.Point2D$Double

13:48 amalloy: &(import java.awt.geom.Point2D$Double)

13:48 sexpbot: ⟹ java.awt.geom.Point2D$Double

13:48 khali: is there a way to treat a struct as an array of values?

13:48 amalloy: khali: (vals struct)

13:48 &(class (into-array [(Point2D$Double. 10 10)]))

13:48 sexpbot: ⟹ [Ljava.awt.geom.Point2D$Double;

13:49 khali: perfect amalloy

13:50 amalloy: so TimMc, your type-hint would look like (let [^"[Ljava.awt.geom.Point2D$Double" hinted-val (into-array ...)] (use hinted-val))

13:50 TimMc: eep

13:51 amalloy: heh, indeed. hinting arrays and/or primitives is a pain

13:51 TimMc: ...and then I'd still have to use Java interop calls to pull stuff out of the array.

13:51 amalloy: TimMc: well, aget isn't so bad

13:52 TimMc: Can I destructure arrays?

13:52 amalloy: TimMc: sure, but then you've lost the type-hinting

13:52 TimMc: urgh

13:53 Is that something that could be changed?

13:54 amalloy: ummmmm, i don't know

13:54 TimMc: It *seems* reasonable, but then I'm not the one writing Clojure's compiler.

13:54 amalloy: TimMc: well, if it is possible it shouldn't have to involve java at all

13:55 $source let

13:55 sexpbot: let is http://is.gd/DlvwkU

13:56 amalloy: let and/or destructure might be able to get at the :tag metadata and inspect it for arrays

13:56 TimMc: Oh right, it's the macro that would have to do this.

13:57 I was still in non-macro-language land.

13:57 I've been thinking about fancy whole-program stuff like type-inference.

13:59 amalloy: TimMc: if you've ever written (defmacro ...), then you were wrong when you said you're not the one writing clojure's compiler :)

14:01 TimMc: haha

14:21 hiredman: ,(namespace 'foo/bar)

14:22 clojurebot: "foo"

15:07 brehaut: does anyone know if fogus's core.unify is in clojars?

15:08 rrc7cz: why might I still be getting a "WARNING: alias already refers to..." even though I have a (:refer-clojure :exclude [...]) in my ns?

15:18 kencausey: Well, I'm on day two of trying to download Brian Marick's robozzle.mov midge demo/tutorial from github with little progress. Again, has anyone a mirror by chance?

15:22 phenom_: hey anyone interested in helping me build out a queueing system? i'm doing it more to learn clojure than to compete in the market ... no standards or complexities, just a simple thing

15:22 odyssomay: kencausey, http://www.vimeo.com/19404746

15:22 Raynes: defn: Ping.

15:23 phenom_: anyone interested, get in touch with me ... github.com/djunforgetable

15:23 kencausey: odyssomay: Yeah, vimeo is a problem for me with screencasts because flash won't fullscreen for me and I see no option to popout a resizable window like I would with say youtube

15:24 I have a dual-head setup which flash is not happy about

15:24 odyssomay: kencausey, so don't fullscreen?

15:24 kencausey: then it's too small to read

15:25 odyssomay: which flash version do you have?

15:25 kencausey: Linux 10.2 d161

15:25 the problem may be with the nvidia driver

15:25 some applications full screen fine, others don't, flash is not the only one that doesn't

15:28 odyssomay: kencausey, the flash is streamed to ~/.mozilla/firefox/*.default/Cache/

15:28 you can use mplayer or similar to view it

15:29 kencausey: odyssomay: cool, that's an idea, although for some reason today the flash viewer is not working at all, I see the default view but no option to start the video, the html5 player works though

15:30 oh, except I'm not using moz ;) but the idea still holds merit

15:30 fliebel: brehaut: It's core.unify, so it ships with Clojure, right?

15:40 odyssomay: kencausey, If you happen to have flashblock, it doesn't work with vimeo

15:41 kencausey: I don't have any blocking of any kind

15:41 odyssomay: ok

15:41 kencausey: flash is working fine on other sites

15:41 this is all rather irrelevant/off-topic at this point

15:42 odyssomay: yes, you're right, but it's pretty quiet here anyway

15:43 kencausey: sure

15:46 Actually, this is all moot now, I find that vimeo's html5 viewer 'fullscreens' within the browser boundary (of course) so it works fine and hopefully the quality will be sufficient for my purposes

15:46 but thanks odyssomay

15:47 and then I can full-screen chrome and all is still good, enough about that ;)

15:47 odyssomay: heh, yeah np

16:40 rata_: hi

16:42 ohpauleez: Does anyone know how to select something with enlive that has a space in it

16:45 dnolen: ohpauleez: like a text node?

16:46 ohpauleez: dnolen: something like: (map html/text (html/select (scrape/fetch-url scrape/*base-url*) [:div.inner :ul.topiclist forums]))

16:46 where the ul I'm going for is "topiclist forums"

16:46 dnolen: the className is topiclist-forums ?

16:47 er I mean, 'topiclist forums'

16:48 brehaut: ohpauleez: in css, that is actually two classes

16:48 dnolen: :ul.topiclist.forums

16:48 ^ should work

16:48 ohpauleez: ahhh cool

16:48 right tight

16:48 thanks guys, I really need to focus

16:48 :)

16:49 brehaut: dnolen: is the unifier in logos usable outside the context of your miniKanren imp?

16:51 dnolen: brehaut: it is, logos.unify/unifier and unifier'. It uses logos.minikanren under the hood, but it provides the same interface as fogus's core.unify

16:51 brehaut: dnolen: sweet :)

16:52 dnolen: brehaut: unifier takes prepped sexprs, that is sexprs where the location of the logic vars have already been determined. unifier' can take un-prepped sexprs, but its *dog-slow* cause of post-walk

16:52 brehaut: dnolen: im fine with dog slow ;)

16:53 im writing a series of monkey and banana implementations (pg 46 of bratko)

16:53 gradually moving from functional to logical

16:53 i want to eventually end up with a logos implementation

16:54 dnolen: brehaut: nice! there's a pretty wacky critical bug I need to fix ASAP in logos, fingers crossed you don't run into it.

16:54 brehaut: hah cheers :)

16:54 im still 2 steps away from the logos imp so hopefully i'll not run into it

17:02 lancepantz: does anyone know how keyword lookups are optimized on records?

17:02 are they converted to method calls at compile time or runtime?

17:02 brehaut: lancepantz: roughly i think? theres a callsite cache that does that

17:03 lancepantz: brehaut: so keywords are hashed and cached at runtime?

17:03 brehaut: i dont know if its hashed or what, but there is a runtime optimsation at the callsite

17:03 lancepantz: i've got a record lookup in an innerloop and my profiler says a lot of time is being spent hashing keywords

17:04 brehaut: beyond that i dont know any of the details

17:04 lancepantz: i had expected that to be converted to a method call at compile time

17:05 chouser: keyword lookups are compiled as method calls in case the target changes type

17:05 are NOT, :-P

17:06 lancepantz: i added a type hint expecting that to take care of it, didn't seem to change anything though

17:06 so if i want full optimization i should just call the methods using interop?

17:06 chouser: yes

17:06 lancepantz: great

17:06 thanks chouser :)

17:06 chouser: though I think the keyword should get hashed at compile time, so I'm not sure what you're seeing.

17:07 lancepantz: most of the activity is in clojure.lang.Keyword.hashCode

17:07 22% of my execution time

17:08 chouser: that method just returns a field of the keyword object

17:09 lancepantz: so that should be really fast?

17:09 chouser: one would think, yeah

17:10 lancepantz: my loop is calling it alot, i'm going to try interop and see if that helps

17:10 chouser: but regardless if you want maximum performance, use sufficiently hinted interop on the record.

17:10 lancepantz: cool

17:10 i'll report back :)

17:11 jkdufair: can i do interactive debugging in emacs?

17:12 found (i think) a bug in appengine-magic and want to step into it

17:14 raek: jkdufair: haven't tried this myself, but could be worth checking out: http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml

17:23 jkdufair: raek: thanks! i'll check it out

17:28 amalloy: jkdufair: see also george jahad's cdt

17:28 jkdufair: amalloy: super. thx!

17:59 rsenior: I'm hitting a snag with AOT compiling some code. I'm invoking multimethod (based on class) from inside a macro, during AOT compilation, it's treating the defrecord constructor as a list (i.e. (new-foo ...)). If I do not AOT compile, it's treating that same code as the defrecord type (Foo) instead of the persistent list, and it works fine.

18:00 I'm trying to dig a little deeper to see if I'm hitting a bug or if it's just bad macro code, but I'm having difficulty figuring out what's different from AOT and the normal compile/load from the REPL

18:02 jweiss: this page seems to be out of date: http://clojure.org/protocols - probably just needs to reference to 1.2 being unreleased taken off. reason i bring this up is i'm trying to sell clojure to coworkers and this looks bad

18:03 rsenior: jweiss: send an email to alex@puredanger.com with that

18:03 jweiss: rsenior: ok will do, thanks

18:06 rata_: rsenior: have you a gist of that?

18:07 *with that code

18:07 macro I mean

18:08 rsenior: rata_: there's several, I could try to isolate it for a gist

18:08 rata_: *there are several

18:08 rata_: give me one to look at the macro

18:11 rsenior: rata_: will do, one minute

18:11 brehaut: anyone here familiar with jim duey's state-t from c.c.monads ?

18:14 rsenior: rata_: https://gist.github.com/817497

18:17 rata_: in that code snippit, record that is being destructured off of the first argument, is being interpreted as a list and the REPL as a record

18:18 amalloy: rsenior: this doesn't look to me like it should work

18:18 rsenior: rata_: not sure that tells you much

18:18 rata_: I think you want to eval the record constructor at compile time

18:19 why are you doing it with a macro?

18:20 amalloy: (record-matcher '(new-baz {:bar ?e})) is what your macro is doing at compile time (note the quote), and i don't see how it ever works at the repl

18:20 rsenior: that's a good question

18:21 rata_: what's record-matcher?

18:21 rsenior: record matcher is the multi-method that is being invoked based on type of record

18:22 amalloy: I agree, not sure why it works at the REPL

18:23 I stumbled on this today when I was switching a piece of previous not AOT compiled code to AOT

18:23 ahh, now I remember why it needs to be a macro

18:24 if-match is actually a macro in matchure (https://github.com/dcolthorp/matchure)

18:25 (new-baz {:bar ?e}) has a symbol, ?e that the if-match macro is finding a replacing with a gensym'd symbol behind the scenes

18:25 if the above code is a function, it will try and eval that ?e which will cause problems

18:26 and is actually the error that happens at AOT compile time (and not at the REPL)

18:27 rata_: do you want to print those two lines at compile time?

18:27 rsenior: just for debugging

18:27 rata_: ok

18:27 rsenior: I put that there to try and find out what's going on

18:27 and the (class record) part is what's returning a persistent list vs. a proper defrecord type

18:28 amalloy: rsenior: i don't really know what matchure tries to do, but you might find my article at http://hubpages.com/hub/Clojure-macro-writing-macros useful, regarding what should be a function and what should be a macro

18:33 rsenior: amalloy: nice entry, what solidified it for me was On Lisp, I found a lot of what was discussed relating to macros carried over pretty well to Clojure

18:34 amalloy: yeah, most of it applies pretty equally to any lisp

18:35 arohner: isn't there a built-in fn to convert a String to byte[]?

18:35 amalloy: &(.getBytes "test")

18:35 sexpbot: ⟹ #<byte[] [B@1b220a3>

18:35 arohner: amalloy: thanks

18:35 amalloy: &(seq (.getBytes "test"))

18:35 sexpbot: ⟹ (116 101 115 116)

18:36 amalloy: just checking :P

18:36 ninjudd: can type hints use an interface instead of a class?

18:37 arohner: ninjudd: I think so

18:37 amalloy: ninjudd: i don't see why not

18:37 yeah, there are type-hints on j.u.Collection somewhere in core, i think

18:38 rata_: rsenior: when you remove those println, does it work?

18:39 amalloy: rata_: if that fixes it he should probably call an exorcist

18:41 rata_: hahahaha... the thing is, I don't see why the `(if-match ...) shouldn't work, he's unquoting everything in that expression

18:42 I suppose he's checked that (if-match [(record-matcher (new-baz {:bar ?e})) nil] (some ...)) works as he expects

18:42 amalloy: rata_: that's not what his code expands to

18:43 rata_: why not? what am I missing?

18:43 amalloy: i think he may actually mean `(if-match [(record-matcher ~record) ...])

18:43 rata_: yes... probably

18:43 amalloy: because he's trying to do the record-matcher call in the macro context instead of the expansion context

18:43 rata_: yes... that was what I was missing =P

18:47 amalloy: i don't know if that will fix his problem because he's trying to have compile-time access to the run-time information contained in (new-baz ...)

19:24 argh, clojure has poisoned my mind. i find myself trying to implement lazy sequences for php just so i can generalize existing code

19:32 brehaut: amalloy: lol :)

19:32 its when you start trying to write point free PHP that you know you have lost it

19:34 amalloy: brehaut: surely someone out there has written a haskell=>php compiler

19:34 it's just such a natural combo of languages...

19:34 brehaut: haha

19:34 one of the most academic languages wobbling along ontop of one of the least

20:17 phenom_: anyone else getting a small list for elpa package-list-packages command in emacs ?

20:35 amalloy: phenom_: i get 134

20:45 brehaut: has anybody used matchure?

20:45 TimMc: I AM A GOLDEN GOD

20:46 ahem, sorry

20:46 amalloy: brehaut: rsenior was having trouble with it earlier, maybe send him a $mail?

20:46 TimMc: Just figured out the change of coordinates math for some graphics stuff.

20:46 brehaut: amalloy: cheers

20:47 TimMc: Anybody have recommendations for a matrix lib?

20:47 amalloy: TimMc: http://download.oracle.com/javase/1.4.2/docs/api/java/awt/geom/AffineTransform.html is probably useful?

20:48 TimMc: amalloy: Unfortunately, this is for a Computer Graphics homework assignment, and I think we're supposed to do the math ourselves on this one.

20:49 amalloy: My breakthrough was in understanding the order in which all the component transforms need to happen.

20:52 ...but I really should ask the prof if I can use the Java2D math classes.

20:54 amalloy: TimMc: yeah, if you are going to use a matrix library, you might as well use the one designed for graphics, it seems to me

20:54 TimMc: True.

20:54 amalloy: and trust me, getting the order right will still matter with affinetransform :)

20:55 TimMc: indeed

20:55 amalloy: i vaguely remember similar issues when i was in college

20:55 TimMc: This is the first time I've needed to do anything more than flipping the y coordinates and translating the origin.

20:55 amalloy: ah. fitting to a window, i bet?

20:57 TimMc: Well, anything where I wanted standard (integer) Cartesian coordinates.

20:58 Oh man, I remember writing stuff for my TI-89 graphing calculator... wrote a Mandelbrot fractal program that took 6 hours to run.

20:58 ANyway.

20:59 amalloy: haha good old ti

20:59 my early programs were for the 83

21:00 TimMc: I still have that 89. It's about 13 years old now.

21:01 Maybe I'll write a Scheme interpreter for it some day. The parentheses are easy to reach on that keyboard.

21:19 pppaul: hey dudes

21:19 i'm using lein, and i want to slurp a file: "file.txt" where should i put the file so (slurp "file.txt") works?

21:22 got it

21:22 thanks guys!

21:22 :D

22:40 phenom_: how to you stop a cake swank server?

22:40 amalloy: cake kill

22:53 anthony__: The docs for the logging functions say that log4j is supported, and I'm able to get it to work when running my program from the REPL, but log4j doesn't seem to work after compiling with lein. Is there a better logging library, or am I doing something terribly wrong?

22:58 amalloy: anthony__: well, usually you shouldn't need to compile

22:59 but you need log4j.properties in your classpath, which probably isn't making it into the jar

22:59 anthony__: amalloy: What's the recommended way of running clojure programs? I've always used lein jar (or uberjar).

22:59 foxupa: hello

23:00 anthony__: Yeah, I want it outside of my jar in case I need to change it. But it's in my pwd. I'll mess around with it some more.

23:00 amalloy: anthony__: i think lein run should work without compiling

23:00 anthony__: your cwd isn't included in the classpath when running a jar

23:00 anthony__: amalloy: Oh, gotcha. You mean straight to "lein jar"?

23:00 amalloy: you probably want to add a resources directory

23:00 foxupa: I was wondering if anyone could show me how to redefine the eval function (I want to write metacircular evaluators)

23:01 amalloy: there's an entry in project.clj to specify directories to include straight in the jar

23:01 anthony__: amalloy: Gotcha. I was hoping to be able to run log4j.properties outside of the jar, so I could change it without re-packaging. But including it won't hurt. Thanks for the help.

23:02 scottj: foxupa: maybe call it something different?

23:02 amalloy: anthony__: you shouldn't need to package at all while you're developing

23:03 scottj: foxupa: there is some form I think you put in (ns) that will exclude stuff from clojure.core I think

23:04 anthony__: amalloy: Yeah, I'm not. Logging worked just fine during development. I'm packaging it up to send to a friend to use, and he might want his logging path to be somewhere different than mine. He's smart enough to change the file in the JAR, though, so no biggie.

23:04 amalloy: scottj: :refer-clojure

23:04 foxupa: well what I want is to be able to do (def eval [x] (eval (do (print x) x)))

23:04 for example

23:04 so that any call to the eval function prints out the argument

23:05 amalloy: foxupa: maybe robert.hooke?

23:05 i haven't used it but that sounds like an appropriate tool

23:06 i think it's one of technomancy's toys

23:07 foxupa: thanks amalloy, I think this will do the trick

23:08 amalloy: although it is a bit dissappointing that this can't be done more naturally... is clojure.core somehow protected from redefinition?

23:08 scottj: waht about going into clojure.core and evaling (defn eval [form] (println form) (. clojure.lang.Compiler (eval form)))

23:09 foxupa: scottj, how do I go into clojure.core? Do I just some kind of (use-namespace clojure.core) call to step into it?

23:09 scottj: slime?

23:09 clojurebot: slime-install is an automated elisp install script at http://github.com/technomancy/emacs-starter-kit/blob/2b7678e9a331d243bf32cd8b591f826739dad2d9/starter-kit-lisp.el#-72

23:09 foxupa: scottj, sorry, I'm just giving Clojure a test drive coming from a scheme background

23:09 pdk: i think the idea is clojure.core is imported automatically at start

23:10 try doing say (doc print) or something

23:10 notice "clojure.core/print"

23:10 scottj: in slime ,clojure.core, in repl (ns clojure.core) I think, in code maybe (in-ns..

23:10 pdk: so it's auto :use-ing the names out of core

23:11 practical clojure has a chapter on namespaces and the funky handful of ways to import stuff

23:11 foxupa: scottj: awesome I got it to work... thanks a lot, I was scared for a bit that I wouldn't be able to do this (or have to go through some obscure hack to get it to work)

23:12 scottj, I suppose now I can dive into clojure!

23:12 scottj: like a true schemer!

23:12 tomoj: can't wait until lamina's async works :D

23:12 scottj: (by fiddling with evaluators instead of "real" projects :)

23:12 technomancy: clojurebot: shut up man; that is a terrible link

23:12 clojurebot: 'Sea, mhuise.

23:12 technomancy: clojurebot: forget slime-install

23:12 clojurebot: I don't understand.

23:12 technomancy: ...

23:13 foxupa: scottj, the main pull was that clojure nearly quarters my scheme code base having elegantly implemented most of my machinery into the language

23:15 scottj, just one last question but as clojure is a lisp, I really should be able to completely redefine whatever part of the language I want correct? or are there any subtle limits I should be aware of?

23:16 scottj: foxupa: I don't know but I'd guess there are some

23:16 headlessClown: no custom reader macros

23:16 scottj: headlessClown: easily anyway

23:59 no_mind: is there a way I can identify the datatype of a var ?

Logging service provided by n01se.net