#clojure log - Aug 03 2011

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

0:08 semperos: at the Slime repl I generally just work inside namespaces that I've loaded via a file, but for the first time I was using `in-ns` to create some throw-away namespaces

0:09 I thought when you switched to a new namespace with `in-ns`, you started with a "blank slate"

0:09 so nothing I had `require` or `use` in another namesapce with be available

0:09 is that not the case?

0:14 Pupeno: Hello.

0:14 pcavs: semperos: I believe that is the case, what makes you think that is not?

0:14 semperos: pcavs: working at the repl, switching between namespaces and not having a "blank slate" between namespaces

0:14 dnolen: :D tell me you don't want this awesomeness, https://gist.github.com/1121891

0:20 pcavs: semperos: could you be more precise? certain core clojure libs are defaulted to being loaded in every ns

0:21 semperos: let's say I created a file with a namespace of foo

0:22 then at the repl, I enter a namespace bar by evaluating `(in-ns 'bar)`

0:22 while inside bar, I `(require 'foo)`

0:22 then, say I leave bar and go to the user namespace, `(in-ns 'user)`

0:23 what I'm experiencing at that point is the functions in my file's `foo` namespace, that I required while inside bar, are available in my user namespace at the REPL

0:23 pcavs: what if you change 'user to be 'baz

0:23 same effect?

0:25 semperos: I'm just thinking that there may be some defaults already loaded into the 'user namespace previously, which you forgot to wipe, or from leiningen/whatever you're using for your swank server

0:25 since 'user is the default ns name

0:25 semperos: yes

0:25 that was just an example, the point is that when switching between namespaces, code `required` in one is available in another

0:26 possible "expected" behavior of swank, but it just doesn't make much sense to me

0:26 pcavs: semperos: interesting

0:28 lobotomy: having some problems with multimethods, trying type-based dispatch: http://pastebin.com/i2nHHUs7

0:28 questions: 1) does this sort of "typing" thing make sense in clojure anyway? :) 2) why isn't it working?

0:29 brehaut: lobotomy: types definately exist in clojure, but the signatures of functions are not bound to them as they would be in java

0:35 lobotomy: your definition for make-piece you have defmulti where you mean defmethod

0:36 lobotomy: ...oh ffs

0:36 thanks a lot :D

0:36 brehaut: np

0:38 semperos: lobotomy: for pure type-based dispatch, protocols might be a better fit

0:38 brehaut: semperos: hes doing multiple dispatch however, so multis is right in this case

0:39 tomoj: is it?

0:39 I guess there are some missing parts maybe that justify the use of records and multimethods

0:39 brehaut: tomoj: for make-piece it is

0:39 tomoj: ok

0:40 brehaut: make-edge could definately be a protocol

0:40 semperos: yep

0:40 tomoj: oh, I guess there are going to be more implementations?

0:40 :)

0:41 brehaut: oh, no tomoj you are right, it doesnt need to be multiple dispatch if its always expecting strings for second and third args

0:42 tomoj: I was looking at just that code thinking less than 5 lines do exactly the same thing, but the part left out is where else you're going with it

0:42 (naturally..)

0:44 brehaut: lobotomy: if you dont care about the types of the second and third args, you dont need to make your dispatch function handle them.

0:47 lobotomy: tomoj, i don't know yet where i'm going with it :) right now though, nowhere

0:47 brehaut: lobotomy: which is to say (fn [[a & _] _ _] (type a)) would do for your dispatch function

0:47 lobotomy: hmm, destructuring. good point

0:48 tomoj: (comp type first vector)

0:48 brehaut: tomoj: that was my first though too :P but i think the destructuring is nicer in this case, because its explicit about the arguments

0:48 lobotomy: was also thinking where best to verify the validity of the given edges... a {:pre ...} in make-piece-from-edges i think?

0:49 brehaut: oh, tomoj ffirst rather than first

0:49 tomoj: right

0:49 lobotomy: my first version had a make-piece with a {:pre} that checked if the given things are strings, if so turned them into edges, and checked if they're valid for a piece, but that just seemed ugly

0:49 tomoj: lobotomy: .. so you aren't just using multimethods and records because it looks sorta like some OOP you're used to, are you? :)

0:50 lobotomy: well, the previous version of this program i wrote in java, so hm... ;)

0:50 yeah, i'm kind of contaminated that way, haha

0:50 brehaut: lobotomy you can actually scrap the entire multi for make-piece;

0:51 (defn make-piece [e c n] (Piece. (make-edge e) c n))

0:51 if you (defmethod make-edge Edge [x] x)

0:52 tomoj: I doubt there is need for Pieces or Edges

0:52 Pupeno: I need an embedded database for my app, should I go with Derby?

0:52 tomoj: nor for make-piece

0:53 lobotomy: well, the use case is basically that i want to be able to say (make-piece ["00011" "10100" "00110" "00110"] "purple" "P1") and have it verify that the edges (or strings, whichever) match each other

0:53 brehaut: lobotomy: and if you have a fixed set of types that you need to coerce, you dont need late bound polymorphism, you can just use case (or other cond family form)

0:53 tomoj: why not just use the ints themselves, (filter #(<= 0 % 31)) them (or throw an exception if you insist..)

0:53 lobotomy: tomoj, not sure how things would be clearer without Piece or Edge at all?

0:53 i mean, at this point probably, but once i add the other zillion lines of stuff

0:54 tomoj: then just write {:edges [1 2 3 4] :colour "purple" :name "P1"}

0:54 I suggest adding multimethods and records and these things after you notice you need them

0:54 lobotomy: how to do the error checking though with {}?

0:55 tomoj: before, they just turn 3 lines of code into 30

0:55 lobotomy: for instance, "10101" "01101" is invalid since the corner between consecutive edges can't be both 1 and 0

0:56 you're saying to do the make-piece just with that check, parseInt and that's all? i guess that could work too :]

0:56 tomoj: well, I don't know about any of that, was just looking at the code, so can't really say you don't need multimethods or records

0:56 lobotomy: yeah, the code isn't all, but the rest is rather unfinished

0:56 tomoj: but.. it is generally better to err towards not using them

0:57 lobotomy: in the (near) future i'll need to add a mutable version of edges and hmm... i'll need to link the mutable edges together

0:57 tomoj: ..guess that is not really useful advice, since them problem is just deciding whether or not you need them

0:58 oh god

0:58 wait

0:58 lobotomy: i think at that point it will be necessary to wrap the int in something

0:58 in the mutable edge i mean

0:58 tomoj: you mean mutable like clojure's reference types?

0:59 or mutable like bad evil mutable?

0:59 :)

0:59 lobotomy: i don't know. was thinking of using ref

0:59 what i'd do is build a wire frame kind of thing, for this puzzle solver

0:59 tomoj: whew, thought you meant really mutable

0:59 lobotomy: into which pieces are "added" as the solver proceeds

1:00 and the addition is probably a lot simpler by just changing the int inside the edge

1:00 semperos: tomoj: nothing inherently evil about mutable state; things get interesting with *shared* mutable state, but localized mutability can be used strategically

1:00 tomoj: what puzzle is it, anyway? was curious from the beginning

1:00 lobotomy: since the edge needs to be linked to other edges, and creating a new edge and transferring the links seems more complicated than modifying existing edge's int and not touching the links

1:00 http://www.happycube.com/

1:02 brehaut: oh man. happy cubes

1:02 tomoj: neat

1:02 brehaut: so many hours of suffering and fun

1:02 tomoj: I can feel the frustration watching those flash videos

1:05 lobotomy: here's some ascii art: http://pastebin.com/mp3QNzHB

1:06 brehaut: tomoj: once you have the basic cubes solved, you get the frustration of assembling shapes from multiple cube sets

1:07 lobotomy: anyway, the java version of the solver simply has Edge, MutableEdge, Piece and Hole

1:07 and Structure, which is a bunch of holes plus the solver

1:07 brehaut: lobotomy: why are you repeating the corners?

1:07 lobotomy: why not?

1:08 brehaut: no i mean, what is the benefit you gain from it?

1:08 lobotomy: it's probably simplest to just repeat them :)

1:08 how else would you do it? edges and corners separately?

1:08 that's more complicated, but the benefit is... what?

1:08 brehaut: lobotomy: what about a vector of 16 bools?

1:09 lobotomy: with that, how would it work when you're modeling something like this: http://happysolver.sourceforge.net/realComplex.jpg

1:10 which bools in which vectors would correspond to which holes in the structure you're trying to build?

1:11 (i'm not saying my edge linking solution is the best, but it seems the most intuitive to me)

1:12 brehaut: lobotomy, the bools encode the same information your vector of strings does, but flattened

1:12 and with the corners occuring only once

1:13 (because the end of side of a piece is the beginning of the next side)

1:13 tomoj: in the solutions, are the pieces always arranged in (a subset of) a 3d grid?

1:13 brehaut: yes

1:13 tomoj: (like in the picture, in a single cube, in a flat arrangement)

1:14 lobotomy: brehaut, and why would i want the information flattened?

1:14 the 3d structure doesn't look very flattened...

1:15 brehaut: lobotomy: i like to choose the simplist representation possible; and the simplest one possible is the one i can apply more standard library function

1:15 tomoj: no need to validate that the corners in the input edges match up if there's no room for error because you only specify each corner once

1:16 lobotomy: no need to optimise that bit out since all pieces are immutable and specified only once

1:16 the more important point is the 3d (mutable) structure

1:16 tomoj: originally I was thinking your way made sense, if the pieces never change maybe I still do

1:17 lobotomy: brehaut, what then is the simplest representation possible for that big 3d case? i'm inclined to think flattened won't do

1:17 brehaut: lobotomy: consider this [false false false true true true false true false false false true false false true true false]

1:17 lobotomy: well, of course flattened is possible, but...

1:18 brehaut: so the case of rotations you just need to use cycle drop take

1:19 lobotomy: think about it this way: i have a piece, and a structure with a hole. task: find out if the piece matches the hole

1:19 now, you're saying that the structure is a flat vector of bools?

1:19 where in that vector is the hole? which bools?

1:20 my current solution simply has a Hole, which consists of 4 MutableEdges. done

1:20 when i find a matching piece, i modify the hole's mutable edges (and, possibly, their successor edges - since corners are shared) to incorporate it

1:22 tomoj: if you write the clojure like the java it's going to be ugly

1:23 don't think most idiomatic solutions to this problem in clojure use any mutability or refs or multimethods or records

1:24 lobotomy: hmm, by "this problem" do you mean the entire problem, or just the (immutable) edges and pieces?

1:24 tomoj: ..but I just realized I've only been thinking of the puzzle, and have only a vague idea what an actual solver algorithm looks like, so.. dunno

1:24 brehaut: lobotomy: consider this ##(every? #(== 1 %) (map bit-xor [1 1 1 0 1] [0 0 0 1 1]))

1:24 lazybot: ⇒ false

1:24 tomoj: I meant the entire problem, for that specific puzzle (generalizations might make use of records/multimethods I suppose)

1:25 lobotomy: are you saying my solution is easier to do without mutability, or that there's an idiomatic solution where no mutability is needed?

1:27 brehaut: lobotomy: heres every rotation of a piece ##(take 4 (partition 16 4 (cycle [0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 1 1 0])))

1:27 lazybot: ⇒ ((0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 1) (1 1 0 1 0 0 0 1 0 0 0 1 1 0 0 0) (0 0 0 1 0 0 0 1 1 0 0 0 0 1 1 1) (0 0 0 1 1 0 0 0 0 1 1 1 0 1 0 0))

1:27 clojurebot: ,(let [testar (fn [x y] (if (= (reduce + (filter odd? (range 0 x))) y) (str y " is an square perfect")) )] (testar 10 25))

1:27 lobotomy: (the solver algorithm is a simple depth-first search, not much mystery there)

1:29 tomoj: hmm

1:30 if you have a partial clojure solution written with mutability in mind, I have no idea whether it is easier to write a different (more idiomatic) solution in clojure instead of just finishing it

1:30 lobotomy: are you sure that idiomatic clojure never has any mutability in it anywhere? :)

1:31 brehaut: idiomatic clojure strongly favors immutability

1:31 tomoj: I am sure that that is not true

1:31 lobotomy: i'm basically making a wireframe, then modifying that as the solver proceeds, and that seems like the most natural way of doing this

1:31 in the java version i have multiple solver threads, each creates its own private version of the wireframe

1:31 but the pieces are shared since those are immutable

1:32 brehaut: lobotomy: both breadth and depth first search are algorithms that naturally suits immutable implementation

1:33 lobotomy: and the wireframe is a thing that naturally suits a mutable implementation

1:34 tomoj: we should probably taboo "mutable"

1:34 I don't think we're talking about the same things

1:36 * brehaut seconds

1:41 tomoj: do you have any of the wireframe code written yet?

1:42 well, is that your sourceforge project?

1:44 lobotomy: hmm, no, the sourceforge one is completely different

1:44 brehaut: lobotomy: are you wanting the solver to find arbitrary solutions, or to solve specific shapes?

1:44 lobotomy: mine is unreleased. just wrote it for fun, not looking at the sourceforge version :)

1:44 tomoj: ah

1:44 lobotomy: to solve specific shapes with given pieces

1:45 basically, the problem is: given a list of pieces, and a shape, print out (somehow) the solution, or indicate that one doesn't exist

1:45 my code just prints out the pieces in the solution with ascii art, in a predetermined order (depending on the shape)

1:45 so it's not quite as user friendly as the sourceforge solution ;)

1:47 brehaut: sure, thats the easier one than any arbitrary shape

1:47 lobotomy: my version supports arbitrary shapes actually

1:47 brehaut: you misunderstand

1:48 lobotomy: you mean, given these pieces, figure out which shapes can be built?

1:48 brehaut: yes

1:48 lobotomy: hmm... that could be done fairly easily with my solution: go through each shape, if shape requires at most n pieces, try to solve it with the given n pieces

1:49 brehaut: way more concise than the garbled explaination iwas typing :P

1:49 lobotomy: beyond a certain point the shapes start to require more than n pieces so this will eventually terminate ;)

1:59 tomoj: so you have some canonical order for holes

1:59 a shape is a list of open hole indices

2:00 eh.. a shape is a function from holes to sets of holes

2:01 or neither of those but both mixed together, I dunno

2:13 lobotomy: ok, does representing a shape as a list of hole coords make sense?

2:14 lobotomy: coords? do elaborate

2:22 tomoj: so the simple cube is, uh

2:23 &(for [x [0 1] y [0 1] z [0 1]] [x y z])

2:23 lazybot: ⇒ ([0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] [1 0 1] [1 1 0] [1 1 1])

2:23 tomoj: guess not, he

2:23 eh

2:28 I was thinking in 2d with a bad analogy, not going to understand this problem tonight :)

3:33 Cozey: Hello. How to run a multi module (reactor build) from leiningen's maven integration? Is it possible? I have a project A (lein) depending on B (maven) and I'd like to quickly update A's loaded dependencies (into lib/) when B changes.

4:20 peteriserins: (print) does not print to the screen in uberjar; should I have used Java prints instead?

4:23 raek: print should work...

4:27 peteriserins: ok, it was because of the System/exit call, I assume print uses BufferedWriter or something

4:28 brehaut: ,(doc flush)

4:28 clojurebot: "([]); Flushes the output stream that is the current value of *out*"

4:49 wall: hello

4:52 zarac: hi wall : 0

4:52 wall: can anybody help me reduce code to simple

4:52 code here http://paste.lisp.org/display/123754

4:52 i need convert 12 lines to doseq or any cycle

4:53 index now id numbers from 0 to 11

4:54 id = is

4:54 opqdonut: use for and range

4:56 you can do something like (for [angle (range 0 Math/PI step)] (struct point-8 <stuff>))

4:58 wall: super!!!!!

4:58 thancs

4:58 sorry my bad english

4:59 jonasen: A simple ClojureScript game, http://jonase.github.com/make-adder/ Enjoy! :)

5:17 Fossi: 99.65000000000224% yes ;D

5:17 i guess your print needs a format :)

5:18 jonasen: Fossi: I agree, but I don't think its in clojurescript yet

5:18 Fossi: but nice

5:18 real fun too ;)

5:19 jonasen: Fossi: thanks.

5:50 Pupeno_: I think I'm starting to like http://clojuredocs.org.

5:59 MasseR: Pupeno_: Have you noticed, it doesn't find results with hyphens?

5:59 Well the autocompletion finds

5:59 But if you press enter you get 'no results'

5:59 Try for example maybe-m

5:59 Pupeno_: MasseR: clojuredocs.org? no... generally I arrive through google.

5:59 MasseR: Pupeno_: Ah. I use duckduckgo with !clojure bang pattern

5:59 Makes it kind of useless

6:00 Pupeno_: Yeap: http://clojuredocs.org/search?q=as-file

6:01 MasseR: Hmm.. I think it's an open source project on github.. issue time

6:02 Ah it's a known issue

6:02 Pupeno_: https://github.com/zkim/clojuredocs/issues/34

6:02 MasseR: https://github.com/zkim/clojuredocs/issues/22

6:02 Pupeno_: Damn.

6:03 MasseR: :P

6:03 Pupeno_: I been using sphinx way more than I like... maybe I could look into it later.

6:04 MasseR: Somehow python docs ruined sphinx for me

6:05 I actually like hoogle and hayoo. Signature based searching, which works excellent on a static language such as haskell

6:05 But then again haddock (haskell documentation) has troubles that clojure (whatever engine they use) has fixed

6:14 pyr: reading ring and compojure souce

6:14 source i mean

6:14 i'm not seeing how one differentiates request handlers from response handlers

6:15 meh, i see

6:52 wall: hello. help me please with my problem. how i must visit 2 sequence in code with equal offset. this code (let [a '(1 2 3) b '(4 5 6)] (for [x a y b] (println x y))) don't work I need (1 4 2 5 3 6) at result but this code produce multiple of set

6:55 jonasen: ,(interleave [1 2 3] [4 5 6])

6:55 clojurebot: (1 4 2 5 3 ...)

6:59 manutter: ,(map (fn [a b] [a b]) [1 2 3] [:a :b :c])

6:59 clojurebot: ([1 :a] [2 :b] [3 :c])

7:00 manutter: ,(mapcat (fn [a b] [a b]) [1 2 3] [:a :b :c])

7:00 clojurebot: (1 :a 2 :b 3 ...)

7:10 wall: how write code simple

7:10 (defn paint2 [c g]

7:10 (let [w (.getWidth c) w2 (/ w 2)

7:10 h (.getHeight c) h2 (/ h 2)]

7:10 (doseq [x (:circles *game*)]

7:10 (let [col (interleave (:points x) (:colors x))]

7:10 (doseq [i (range 0 (/ (count col) 2))]

7:10 (draw g

7:10 (ellipse (int (+ h2 (:x (nth col (* 2 i))))) (int (+ w2 (:y (nth col (* 2 i))))) (:r (nth col (* 2 i))) (:r (nth col (* 2 i))))

7:10 (style :background (*colors* (nth col (+ 1 (* 2 i)))))))))))

7:11 ?

7:11 with interleave its very long...

7:12 manutter: You would probably be better off using (map (fn [p c] [p c]) (:points x) (:colors x)) instead of interleave

7:13 This will give you a sequence of [p c] pairs that you could destructure to get the actual point and color

7:14 also by the way it's customary to use something like a github gist or similar service for long code snippets

7:16 hmm, looking at your code more closely you might like something like this...

7:18 wait, no, hrm that won't work

7:34 Yeah, try this: (doseq [{:keys [x y r]} x] (draw g (ellipse (int (+ h2 x)) (int (+ w2 y)) r r)...

7:52 wall: sorry, but map produce list, but i need only call functions (ellipse and style)

7:52 how i can apply each element of 2 sequence to draw?

8:03 pyr: ok, got itre

8:04 oops

8:17 wall: no. iterate - not. i need samething like apply only for 2 sequence

8:24 evrika!!!!

8:24 (defn paint2 [c g]

8:24 (let [w (.getWidth c) w2 (/ w 2)

8:24 h (.getHeight c) h2 (/ h 2)]

8:24 (doseq [x (:circles *game*)]

8:24 (doseq [[y z] (map list (:points x) (:colors x))]

8:24 (draw g

8:24 (ellipse (int (+ h2 (:x y))) (int (+ w2 (:y y))) (:r y) (:r y))

8:24 (style :background (*colors* z)))))))

8:26 MasseR: That's not even hard to read

8:46 wall: sorry, stupid question - how change element in list?

8:47 Scriptor: wall: you don't, usually. Why do you need to change an element?

8:49 wall: other words - i must re-produce list with changed element?

8:50 MasseR: wall: Yes

8:50 Immutable data structures

8:50 But don't worry, it's done 'the right way', meaning that the two lists share a lot of common

8:51 Scriptor: wall: basically, but it's still a good idea to look at the problem from a more high-level persepctive

8:51 to see whether there's a better way of doing it

8:51 wall: а по русски никто не говорит?

8:51 who speak Russia?

8:51 Scriptor: Greek?

8:51 oh

8:52 sorry, this channel is mostly english-speaking, I think

8:52 wall: i see

8:52 but my english bad for describe problem

8:52 Scriptor: try anyway

8:54 wall: this is idea for my first game on clojure. Picture here http://gamehappy.ru/f/i/gamehappy/games/220/640-480_screenshot_3.jpg

8:55 game consist of set of circle which describe set of points and list of colors of small ball

8:55 now i write function move-left which must change state of circles

8:56 function simple get next value in list, and change to previous in circle

8:57 and now i don know how change elements in list

8:59 Scriptor: wall: so move-left changes the state of all the circles?

8:59 wall: no

8:59 only linked circles

9:00 my code here http://paste.lisp.org/display/123756

9:00 maybe simple think

9:00 dnolen: ,(update-in [{:points {:x 1 :y 2}}] [0 :points :x] inc)

9:00 clojurebot: [{:points {:y 2, :x 2}}]

9:01 dnolen: wall: ^ ?

9:04 wall: update-in work with hash

9:04 not list

9:04 dnolen: ,(update-in '(1 2 3) [1] inc)

9:04 clojurebot: #<NullPointerException java.lang.NullPointerException>

9:04 Scriptor: wall: it's a list of colors, right?

9:05 dnolen: ,(update-in [1 2 3] [1] inc)

9:05 clojurebot: [1 3 3]

9:05 wall: yes

9:05 Scriptor, yes

9:05 dnolen: ,(update-in (into [] '(1 2 3)) [1] inc)

9:05 clojurebot: [1 3 3]

9:05 Scriptor: yep, I think what you actually have is a vector

9:05 so update-in will work with that

9:06 wall: dnolen, (let [a '(1 2 3 4)] (update-in a [2] inc)) - not work

9:07 Scriptor, i must rewrite using list to using vector?

9:08 Scriptor: wall: in the code you posted, isn't *colors* already a vector?

9:09 wall: not *colors*. see field :color in structure one-circle

9:09 this field have info about state of circle

9:09 *colors* need only then show circle on screen

9:10 dnolen: wall: you can't efficiently or easily update inside the middle of a list.

9:11 wall: ok. i'm rewriting use vector

9:11 Scriptor: good idea, lists are better for iterating through one by one

10:10 ambrosebs: I'm trying to perform this type of conversion: [1 2 3 4] -> [[[1 2] 3] 4] any hints of how to approach this?

10:11 im trying to convert a function call into a lambda calculus function call, with only one argument

10:11 (add 1 2) => ((add 1) 2)

10:13 Somelauw: Anybody already developing for android?

10:15 sthuebner: ambrosebs: do you mean something like this:

10:15 ,(let [add (fn [x y] (+ x y)) add-1 (partial add 1)] (add-1 2))

10:15 clojurebot: 3

10:15 sthuebner: or:

10:15 ,(let [add (fn [x] (fn [y] (add x y)))] ((add 1) 2))

10:15 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: add in this context, compiling:(NO_SOURCE_PATH:0)>

10:16 sthuebner: ,(let [add (fn [x] (fn [y] (+ x y)))] ((add 1) 2))

10:16 clojurebot: 3

10:16 ambrosebs: I have the raw form (add 1 2), I want to transform it into the raw form ((add 1) 2)

10:16 dont want to execute it

10:17 TimMc: some kind of reduce, maybe

10:18 dpritchett: Is it normal to restart one's interpreter every time you finish editing a function in your source file?

10:18 TimMc: ambrosebs: Can you guarantee at least 2 elements?

10:19 dpritchett: I went to #python and #django asking for advice on how to re-import classes loaded with "from myapp.models Person" without having to restart the interpreter and the unanimous response was "you have to restart your interpreter".

10:19 ambrosebs: TimMc: yes

10:20 if it's a function call, it will have an argument

10:20 at least

10:20 tufflax: ,(let [form '(add 1 2 3 4 5)] (reduce (fn [f x] (list f x)) (first form) (next form)))

10:20 clojurebot: (((((add 1) 2) 3) 4) 5)

10:20 ambrosebs: phew!

10:21 tufflax: thanks :)

10:21 tufflax: np

10:21 TimMc: dpritchett: When you work from Emacs, it is not uncommon to have a REPL open in another pane and just keep sending your edited functions down to the REPL for reevaluation.

10:22 dpritchett: Exactly! I assumed that was doable in other interpreted languages too. Perhaps I just need to try #python at a different hour.

10:22 TimMc: I do things a little differently -- I use the REPL to refine a function, then paste it into my source files and run my unit tests.

10:23 dpritchett: That's pretty much what I do too tim

10:24 TimMc: I'm sure someone has cooked up (or will) a hot-swap thingy for Clojure, a la Eclipse.

10:24 That's a joy to work with when doing Java servlet dev.

10:24 dpritchett: There's ring middleware for it, I discovered this on Noir

10:25 https://github.com/ibdknox/noir/blob/master/src/noir/server.clj#L8

10:26 It's pretty sweet that my django *server* restarts itself automagically whenever i save a file on its path... not sure why the interpreter can't hot reload things without a full restart

10:26 Ah well... obviously this isn't really a Clojure question, I just wanted to get confirmation that the emacsy way of doing things actually worked the way i remembered it.

10:33 pepijn: ClojureScript bootstrap says script/bootstrap: 28: jar: not found

10:33 Any ideas?

10:34 Oh, and has anyone tried CouchDB with ClojureScript yet?

10:46 bsteuber: talking of clojurescript

10:46 without optimizing, shouldn't I be able to call cljs stuff from a javascript-console?

10:47 I can call stuff, but e.g. keywords don't work

10:48 cljs.core.name(cljs.core.keyword('foo')) => "î.'foo"

10:48 pepijn: end of wifi, good bye

10:48 bsteuber: however, the same works fine using brepl

11:05 icey: Is apache web server + tomcat the way most people deploy clojure web applications?

11:09 (i'm familiar with lein-beanstalk and clojure on heroku; but I have a bunch of little single serve apps that i want to put online so i'd just as soon put them on a vps at linode or something)

12:13 zvrba: this complains on .isProbablePrime about no matching field found: (let [x (BigInteger. "13")] (.isProbablePrime x))

12:13 what am I doing wrong?

12:14 hiredman: zvrba: read the javadoc for the method you are trying to call

12:15 ejackson: hiredman: reading those things is usually where I go wrong :P

12:15 zvrba: ah!

12:15 forgot the other mandatory argument

12:16 when I write a dot and press TAB for completion, in which packages does slime look?

12:19 technomancy: zvrba: it's impossible to get instance methods for objects where the type is unknown

12:19 zvrba: i know

12:19 technomancy: slime's currently not hooked up to hinting, though it wouldn't be impossible

12:19 zvrba: what hinting?

12:19 technomancy: try C-h TAB in slime to find out what it's bound to

12:19 jweiss: can anyone suggest where i might find an algorithm that does the following - traverses a tree with n threads, such that no child node is processed before its parent? seems simple enough, but i can't seem to find one that honors the restriction and uses the threads efficiently.

12:19 technomancy: zvrba: slime could theoretically be tied into type hints

12:20 nobody's bothered yet since the compiler's going to get chucked out and rewritten

12:20 zvrba: i get message about C-h TAB being undefined.

12:20 technomancy: sorry, C-h k TAB

12:20 maybe in the future once the compiler does type inference and exposes it to tools, swank will tie into that

12:20 zvrba: slime-indent-and-complete-symbol

12:20 does eclipse plugin do type inference?

12:21 technomancy: though, I asked something much simpler: in which packages does completion look into?

12:21 technomancy: I know that I simply get a list of all accessible methods, but from which Java packages?

12:22 technomancy: zvrba: hah; I didn't even know it did that. I don't know if that's intentional or not.

12:22 no idea where it's coming from.

12:23 zvrba: and even better, it would be enough if each completed method name would be prefixed by its class

12:23 that would go a long way before type inference is here

12:23 joly: jweiss: if a breadth-first search is ok, you could put make a nodes-to-visit queue and have the individual threads pull from it. As long as the node is processed before you put the children into the queue, it should work

12:25 jweiss: joly: yeah, that's the problem, i can't just queue up all the nodes at once. so how do i have the main thread wait to queue up the children? once the tree branches i'd need multiple threads doing queueing also

12:26 the only (ugly) solution that would actually work that i came up with is to queue up all at once, and have the worker thread just re-queue an item if its parent hasn't been processed

12:27 joly: jweiss: the main thread would put the first item on the queue, any worker would retrieve it, process it, then put its (multiple) children on the queue.

12:27 hiredman: why not have the thread that processed a parent queue up it's children?

12:28 e.g. put the root on a work queue n threads are pulling from, one thread pulls it off processes the root, and places the immdediate childred on the queue for work, rinse and repeat

12:28 jweiss: hiredman: that is a better idea

12:28 it does require breadth first traversal, which since i'm using clojure.zip, i'd have to write, but that's ok

12:30 manutter: well, if each worker processes 1 node, and then puts the immediate children on the queue, that's breadth-first automatically

12:30 joly: exactly

12:33 well, like breadth-first anyway. some threads could get easy tasks and pull ahead of those doing slower tasks

12:33 and switching to a stack the threads pull from should give you something like depth-first

12:34 manutter: Yeah, the parallelism makes terms like "first" a bit ambiguous.

13:35 lobotomy: so i've figured out i probably want a (defstruct wire :name :i :inverted :successors), and with it a (defn set-wire! [wire i inverted successors] (dosync (alter wire assoc :i i :inverted inverted :successors successors)))

13:35 where the idea is that :inverted is another wire, and :successors is a vector of other wires

13:36 hmm, and of course (defn make-wire [name] (ref (struct wire name)))

13:36 so, should the :inverted be a ref to the other wire, or deref'd plain wire?

13:36 likewise for :successors

13:37 dnolen: lobotomy: defstruct is deprecated.

13:38 lobotomy: well damn :D

13:38 defrecord then?

13:39 hmm, (doc defrecord) tells me "Alpha - subject to change"

13:45 or just use a map instead of defrecord? hmm, that should be fine at this point

13:55 hmm... if i store the dereffed ref, it seems to copy the data? so that won't work

13:56 and when i do (dosync (alter w0 assoc :inverted w1)) then (dosync (alter w1 assoc :inverted w0)), i get a stack overflow

13:56 so: what's the correct way to do circularly linked datums in clojure?

13:59 dnolen: lobotomy: plain maps are fine. circularly linked data is not really possible. better to do this via some relational abstraction of one's own.

13:59 lobotomy: not really possible? what?

13:59 hiredman: dnolen: it is possible via mutable refs

13:59 lobotomy: are you serious?

14:00 dnolen: hiredman: yes, but not recommended by any means.

14:00 lobotomy: or Java arrays etc.

14:00 technomancy: also possible with laziness IIRC

14:00 hiredman: lobotomy: please stop trying to print cyclic graphs

14:00 technomancy: but more trouble than it's worth

14:00 lobotomy: what is the recommended way of doing cyclic things then?

14:00 hiredman, good point ;)

14:01 dnolen: lobotomy: why do you need a cyclic data structure in this case?

14:01 joly: things like graphs can be done with maps: {:a [:a :c] :b [:c] :c [:a :b]}

14:01 technomancy: "doing cyclic things" isn't something you want to do

14:01 joly: the graph has a cycle even though the data structure doesn't

14:02 lobotomy: cyclicness is how i modeled it in java, seemed the most straightforward way

14:02 dnolen: lobotomy: cyclic data structure are code smell in Clojure from what I can tell.

14:03 lobotomy: this is a wireframe for a puzzle solver basically. e.g. a cube, with each "wire" an edge. edges are linked to each other (and to an inverted version of themselves)

14:03 dnolen: lobotomy: in order to have a cyclic data structure you need to have some notion of identity, in Clojure those can only be represented via low level facilities or reference types.

14:03 but Clojure emphasizes values, not identities

14:05 lobotomy: the edges are linked to each other because that seemed the easiest way to deal with the corners, which are shared by more than one edge

14:05 dnolen: lobotomy: write graph using a map.

14:05 write the

14:05 lobotomy: modify a wireframe edge => also checks the beginning or end of each linked edge and modifies that too if necessary

14:06 hmm, a 3-d graph with a map... need to think about that

14:08 hmm, joly's map example seems workable here

14:09 so i'd make one big map with the whole graph in it as symbols

14:10 the hardest part in this solver is building the wireframe, but that's probably just as hard (or easy) with the map as with the link-these-together method

14:10 dnolen: lobotomy: an it'll be sanely printable.

14:11 lobotomy: so's my circularly linked thing, as long as you only print the name of each successor/inverted

14:12 dnolen: lobotomy: but you had to write that conditional logic right?

14:14 lobotomy: what conditional logic? foreach edge in pile_of_edges: print edge " " edge.inverted " " (map name edge.successors)

14:24 devn: dnolen: So, forgive me if this is way off base, but is part of the goal of core.logic to have an ad-hoc type system in clojure? Sort of a drop-in typeclass system?

14:24 dnolen: lobotomy: oh yeah I see yr point there.

14:24 ambrosebs: dnolen has evil plans

14:25 dnolen: ha!

14:25 devn: dnolen: I was talking to a Scala guy at my Clojure meetup last night and he was talking about Scala's type system and I mentioned core.logic => ad-hoc type systems. I didn't have sufficient ammunition to sell him on the idea, so I'm curious if there's a blog post or a writeup somewhere that I could give to him.

14:26 Then again, I might totally misunderstand the aims of core.logic, I just remember that being brought up at some point.

14:27 dnolen: devn: no I have no set plans as of yet.

14:27 devn: dnolen: but that doesn't mean you haven't considered it. :)

14:27 dnolen: open questions - 1) is it fast enough yet? 2) will Clojure provide the necessary hooks? 3) do we need constraint solver?

14:28 st3fan: hooks?

14:28 yarrrrrr!

14:29 dnolen: devn: there is plenty of prior art - Typed Racket, H-M in Prolog, Qi/Shen, so to me it's not a matter of possibility, just time and interest

14:30 however it also my experience that most FP people don't understand logic programming and can't see the relationship between their type checker and logic programming.

14:31 not language implementors / researcher of course, but the users.

14:31 devn: dnolen: *nod*, so, I'm sure you've thought about this. Can you imagine a way to abstract the knowledge of logic programming in a way that would provide the benefits without the learning curve?

14:31 dnolen: devn: no

14:32 logic programming is as deep and profound as object oriented and functional programming - there is no easy path.

14:32 ambrosebs: why would users need to know LP to use a type checker?

14:32 dnolen: ambrosebs: exactly.

14:33 they don't, but since they're don't understand they're skeptical about ad-hoc type checker claims.

14:33 ambrosebs: ah

14:33 so in a "generating interest" sense

14:34 night everyone

14:34 jweiss: am i wrong to think clojure.zip is not suited for concurrent programming (since the notion of "current location" doesn't really make sense)?

14:36 hiredman: jweiss: how so?

14:37 jweiss: hiredman: well, if i have multiple threads going through the zipper and editing nodes, how do i merge them together?

14:37 hiredman: uh

14:37 of that won't work, how did you think it would?

14:37 of course

14:38 jweiss: i didn't. i used zippers when my app was single threaded, now i'm trying to make it multithreaded, so just confirming that i probably shouldn't keep using zippers

14:39 i could use refs but the nature of my app is such that i don't want to repeat transactions

14:39 and i shouldn't have to since there will never be conflicting changes

14:44 dnolen: devn: part of my interest in putting core.logic together was/is to get people excited about exploring Functional/OO/Relational concepts from the same language. Besides Mozart/OZ I'm not aware of another language that lets you do this so seemlessly.

14:48 well non-Lisps, you have Allegro Common Lisp and Racket of course.

15:06 devn: dnolen: thanks for your comments. that gives me something to think about.

15:24 dnolen: devn: I'm definitely planning on revisiting the idea at after the pattern/predicate stuff is sorted. as with the pattern/predicate stuff there's a higher chance of success if people are willing to help contribute ideas/code to help push the project along. hopefully next year around this time there'll be something to show for.

15:36 netrealm: Question, how would I get "cake repl" to switch to my project's namespace automatically?

15:38 amalloy: netrealm: you can put a :startup form in your project.clj

15:39 it gets evaled when you start the repl

15:39 user317: is there a "type" function in clojure, like haskells/ghci's :t command

15:39 amalloy: &(type ())

15:39 lazybot: ⇒ clojure.lang.PersistentList$EmptyList

15:39 amalloy: but of course clojure is dynamically typed, so that's the "runtime" type, not some sort of compile-time type like haskell has

15:40 user317: &(type reduce)

15:40 lazybot: ⇒ clojure.core$r

15:40 user317: thats not to usefull :(

15:40 amalloy: user317: well, functions don't have type signatures. not much you can do about that

15:41 &(doc reduce)

15:41 user317: is there any way to do that kind of intraspection from the interpreter?

15:41 lazybot: ⇒ "([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as wel... http://gist.github.com/1123583

15:41 user317: ah thank you

15:41 amalloy: for which, out of curiosity? telling you about doc, or that functions don't have type signatures?

15:43 user317: telling me about the doc ;)

15:43 just need a way to explore the language, ghc's :t command was pretty useful when i first started coding in haskell

15:44 amalloy: *nod* just :t can tell you a lot about a function for sure

15:45 MasseR: Good to see other haskellists here

15:45 *haskellers

15:48 user317: what does the '^' symbol mean?

15:48 lobotomy: hey guys, what's a better way to do this: http://pastebin.com/Xug6HApt

15:48 dnolen: user317: for type-hinting

15:49 Chousuke: or arbitrary metadata actually

15:49 lobotomy: I'm not sure what that does :p

15:50 lobotomy: just creates a map of stuff

15:50 tried doing that with map, mapcat, concat and whatnot, but couldn't quite

15:50 mattmitchell: i'm trying to get :or working with de structuring a hash-map, I'm doing something wrong... is :or even possible in this scenario? https://gist.github.com/1123602

15:50 Chousuke: well as long as you have a seq of [k v] pairs you can put that into a map

15:50 lobotomy: already the flatten in the keyword generation bit looks ugly to me

15:51 amalloy: i haven't looked at the code, but i heard someone say flatten and i'm 80% sure the code doesn't work

15:52 dnolen: Chousuke: true, I didn't actually realize the following worked.

15:52 Chousuke: so, given keywords, (into {} (map (fn [x] [x {:name (str x) :i (ref 0)}]) keywords))

15:52 dnolen: ,(meta ^long [])

15:52 clojurebot: {:tag #<core$long clojure.core$long@fe0ce9>}

15:53 Chousuke: hm

15:53 that looks weird

15:53 why does the function long get put as the metadata

15:54 amalloy: mattmitchell: try https://gist.github.com/1123606

15:54 mattmitchell: amalloy: oh man, duh :) thank you!

15:57 lobotomy: ,(into [] (map #(list (keyword (str "w" %)) (keyword (str "w" % "-"))) (range 2)))

15:57 clojurebot: [(:w0 :w0-) (:w1 :w1-)]

15:57 lobotomy: see, this is what i mean: looking for [:w0 :w0- :w1 :w1-]

15:58 tried getting there with map etc, didn't work, so i just wrote that simple loop

15:58 but there has to be a better way :)

15:59 i mean, you could add flatten to that i guess, but is that recommended?

15:59 dnolen_: ,(apply concat (map #(list (keyword (str "w" %)) (keyword (str "w" % "-"))) (range 2)))

15:59 clojurebot: (:w0 :w0- :w1 :w1-)

16:00 dnolen_: lobotomy: ^

16:02 lobotomy: hmm, ok. isn't that essentially the same as with flatten?

16:02 or does flatten do an extra pass over the list?

16:02 amalloy: flatten is evil and sinful, and will trick you if you ever depend on it

16:02 user317: whats the difference between (list 1 2) and #(list 1 2)

16:04 amalloy: compare ##(apply concat [[[1 2]] [3 4]]) and ##(flatten [[[1 2]] [3 4]])

16:04 lazybot: (apply concat [[[1 2]] [3 4]]) ⇒ ([1 2] 3 4)

16:04 (flatten [[[1 2]] [3 4]]) ⇒ (1 2 3 4)

16:05 dnolen_: user317: # is shorthand for fn.

16:05 ,(map #(* % 2) (range 10))

16:05 clojurebot: (0 2 4 6 8 ...)

16:05 lobotomy: yeah i see, flatten happens to work here, but in general it might be overzealous

16:05 what about the rest of the thing then? ;)

16:06 user317: dnolen_: so "*" is the implicit argument?

16:06 amalloy: % is

16:06 hiredman: erm

16:06 user317: right ;)

16:06 hiredman: it is pretty explicit

16:06 amalloy: hiredman: is the implicit name of the argument, if you like

16:07 user317: amalloy: so only 1 argument or does this support variable arguments as well

16:07 lobotomy: ooh, (into {} (for [k keywords] [k {:name (str k) :i (ref 0)}]))

16:07 it seems into is what i wanted here

16:08 user317: &(#(* %1 %2) 3 2)

16:08 lazybot: ⇒ 6

16:10 joly: ,(#(vector %&) 1 2 3 4 5 6)

16:10 clojurebot: [(1 2 3 4 5 ...)]

16:12 dnolen_: ,(#(vector (* %1 %2) %&) 1 2 3 4 5)

16:13 clojurebot: [2 (3 4 5)]

16:13 user317: dnolen_: cool, thanks

17:05 hiredman: clojurebot: ping?

17:05 clojurebot: PONG!

17:06 ibdknox: it's very excited about that ping.

17:06 hiredman: ~guards

17:06 clojurebot: SEIZE HIM!

17:07 ibdknox: lol

17:07 hiredman: ~\o

17:07 clojurebot: Excuse me?

17:07 hiredman: ~ o/

17:07 clojurebot: \o ... High five!

17:30 gtrak: is there a simple way to move a bunch of values from one map to different keys in a second?

17:31 hiredman: ,(doc rename)

17:31 clojurebot: No entiendo

17:31 hiredman: ,(doc rename-keys)

17:31 clojurebot: Gabh mo leithscéal?

17:31 gtrak: ah, I'll have a look

17:31 hiredman: pffft

17:31 ,(doc clojure.set/rename-keys)

17:31 clojurebot: Cool story bro.

17:32 hiredman: ,(use 'clojure.set)

17:32 clojurebot: nil

17:32 hiredman: ,(doc clojure.set/rename-keys)

17:32 clojurebot: "([map kmap]); Returns the map with the keys in kmap renamed to the vals in kmap"

17:32 gtrak: clojurebot is stateful?

17:35 hiredman: code loading (require,use,load,etc) is inherently stateful

17:36 lucca: In Xanadu did Kubla Khan / A stateful clojurebot decree...

17:37 hiredman: I've looked a little at throwing away the classloader used to load the clojure runtime that runs in the sandbox, and using a new instance of the clojure runtime every time but I have gotten it to work yet

17:37 (or a new clojure runtime every 10 minutes or something)

17:38 lucca: does all the repetitive internal classloading leak memory?

17:40 hiredman: classloaders can be gc'ed once all the classes they have loaded have been gc'ed

17:41 lucca: hmmmmm. So in practice if you execute new incoming code in a loop (like clojurebot), it does... but there are ways around that by re-allocating the classloader.

17:53 * srid became curious to learn Clojure, so he picked up 'The Joy of Clojure' (hoping for a concise, hardcore read ahead)

17:53 technomancy: that's a good way to sum it up

18:12 vertegal: /clear

18:15 XPherior: Is it legal to use destructuring in doseq?

18:16 I have a sequence, ([1 2] [3 4] [5 6] [7 8]) and I want to iterate over it, two elements at a time.

18:17 brehaut: ,(doseq [[a b] [[1 2] [2 3]]] (prn (+ a b)))

18:17 clojurebot: 3

18:17 5

18:18 brehaut: XPherior: ^

18:18 XPherior: Weird. Wonder why that isn't working for me..

18:19 Oh, wait. I lied.

18:19 The data I want to iterate over is this: [1 2 3 4 5 6]

18:19 ,(doseq [[a b] [1 2 3 4 5 6]] (prn (+ a b)))

18:19 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: Long>

18:19 brehaut: XPherior: ##(partition 2 [1 2 3 4 5 6])

18:19 lazybot: ⇒ ((1 2) (3 4) (5 6))

18:20 XPherior: Oh man. Cool Clojure functions strike again. :)

18:20 That does it for me. Thanks man.

18:21 brehaut: no worries

18:22 XPherior: Hm.. Can you iterate over two sequences at once? Such as [1 2 3 4] and [5 6 7 8]?

18:22 sritchie: ,(map vector [1 2 3 4] [5 6 7 8])

18:22 clojurebot: ([1 5] [2 6] [3 7] [4 8])

18:24 XPherior: Cool :)

18:24 Functional programming blows my mind, heh

18:25 Hm, okay. One more. Can you turn something like [1 2 3 4 5 6] into [(1 2) (2 3) (3 4) (4 5) (5 6)] ?

18:26 Oh wait. I think I can actually do that one, haha

18:26 sritchie: ,(partition 1 2 [1 2 3 4 5 6])

18:26 brehaut: ,(partition 2 1 [1 2 3 4 5 6])

18:26 clojurebot: ((1) (3) (5))

18:26 ((1 2) (2 3) (3 4) (4 5) (5 6))

18:26 sritchie: whoops, wrong order!

18:26 XPherior: I was close. Thanks both. :)

18:26 brehaut: XPherior: keep in mind that partition-all might be useful in some case too

18:27 ,(parition-all 2 [1 2 3])

18:27 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: parition-all in this context, compiling:(NO_SOURCE_PATH:0)>

18:27 brehaut: ,(partition-all 2 [1 2 3])

18:27 clojurebot: ((1 2) (3))

18:27 brehaut: ,(partition 2 [1 2 3])

18:27 clojurebot: ((1 2))

18:27 XPherior: Ah, that's pretty cool!

18:28 You guys are smart.

18:30 amalloy: i love (partition 2 1 ...)

18:36 XPherior: Thanks guys! See ya~

20:10 st3fan: if i add a depencency to my project.clj and then run lein deps, lein swank, should those classes be available from the repl ?

20:10 like i can access them with (new com.foo.bar.SomeClass) without having to import them?

20:14 oh nevermind .. i see the real error now, in the window running lein swank

20:24 is there an easy way to time the execution speed of some block of code?

20:25 Raynes: &(doc time)

20:25 lazybot: ⇒ "Macro ([expr]); Evaluates expr and prints the time it took. Returns the value of expr."

20:28 st3fan: yay

20:43 is there something like (repeat 10 (foo)) .. to call a block of code N times?

20:44 technomancy: (doc repeatedly)

20:44 clojurebot: "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it"

20:44 st3fan: oh repeat already does something different

20:44 ahh repeatedly :)

20:44 fullets: dotimes might also do what you want

20:46 technomancy: yeah, depends on if you want a return value or not

20:46 functions named after adverbs are the best, amirite?

20:47 fullets: undoubtedly

20:48 technomancy: (is (definitely (process-finished?)))

21:12 darevay: Hi everybody.

21:14 groovy2shoes: oi, darevay

21:15 darevay: A while ago, I asked about proxy-super and reflection on the ML (http://goo.gl/1l1an). Sadly, no one responded so I'm asking here.

21:17 amalloy: it's a limitation of java, i think. you can't call super.foo(this) in a proxy

21:17 uh. nm

21:17 haha

21:18 ataggart: just got on, but is this about reflection inproxy?

21:18 darevay: ataggart: http://goo.gl/1l1an

21:19 ataggart: yep, easy to fix though

21:19 one sec

21:19 https://github.com/clojure/tools.logging/blob/master/src/main/clojure/clojure/tools/logging.clj#L141

21:19 darevay: ataggart: that's what i like to hear :)

21:20 ataggart: the problem is that the "this" var doesn't have a known type

21:20 it can't since proxy could be a lot of things

21:20 darevay: I could have sworn I tried that to no avail. I will try again now.

21:27 pschorf: has anyone worked with a websocket client using aleph (or another clojure library)?

21:34 hiredman: ataggart: but the runtime class of a proxy is generated at compile time, no? so this should be hintable

21:35 ataggart: which class?

21:35 you can proxy n number of interfaces

21:36 hiredman: right, but (proxy ...) creates a class that implements and inherits from the specified class/interfaces and the creates an instance of that class

21:36 ataggart: ah I see what you mean

21:37 not sure

21:37 hiredman: it may be trick because of update-proxy

21:37 tricky

21:37 you would be able to swap in your own fn without the proper hints

21:45 darevay: ataggart: thanks. I don't have it working yet, but I think I see what I was doing wrong. The proxy's actually in a macro, so inserting the hints is complicated.

21:45 st3fan: i'm looking at the source for clojure.sql

21:45 does anyone know why there is both with-connection and with-connection* ?

21:45 where the first calls the second

21:45 ataggart: it shouldn't be any more complicated than surrounding the proxy-super calls in a (let [^Foo this this] ...)

21:49 darevay: I've observer, maybe incorrectly, that the ^Hints get eaten by the reader (or something) so I have to use with-meta: http://w01fe.com/blog/2009/07/dynamic-type-hints-in-clojure-macros/

21:59 currymj: what's the best way to learn how to use penumbra? I don't know opengl at all, should I try to learn it in C first?

22:05 darevay: ataggart: Actually, it's not the macro. It seems like the "let this" trick doesn't work when the method is protected. https://gist.github.com/1124352

22:06 ataggart: ah, yes, you can't call protected methods

22:06 does it work with the reflection when called?

22:07 darevay: Yeah. It works fine. I just want the reflection gone :)

22:07 ataggart: odd, I thought the reflector only pulled public methods

22:07 darevay: ... without gen-class

22:07 ataggart: I'm surprised it works at all

22:09 darevay: I guess it could be worse then.

22:10 Thanks for your help though.

23:11 Hi everybody. For Seesaw, there are some system-wide settings that a user of a Seesaw-based app might like to override, most notably the look & feel. I was thinking of having a ~/.seesawrc.clj file or something where they could put that stuff. Is that a dumb idea? Should I just stick with Java system properties or a properties file?

23:36 st3fan: what does it mean if my macro fails with "Can't let qualified name"

23:36 does that mean i need to generate the name?

23:37 cemerick: st3fan: you're trying to establish a local binding in the code emitted by a macro? Use a gensym.

23:38 st3fan: `foo# ?

23:38 cemerick: You are emitting a let form, right? In that case, `(let [foo# (some-fn)] (do-something-with-foo foo#))

23:41 st3fan: i'm doing this now: http://pastie.org/2317797

23:42 amalloy: st3fan: that's fine, but a little unidiomatic, in two ways

23:42 as cemerick says, you could more easily write `(if-let [value# (get ~key)] value# ...)

23:43 st3fan: is that 'auto gensym' ?

23:43 amalloy: indeed

23:43 cemerick: yes

23:43 amalloy: &`(let [foo# 1] foo#)

23:43 lazybot: ⇒ (clojure.core/let [foo__14246__auto__ 1] foo__14246__auto__)

23:43 st3fan: yeah cool

23:43 amalloy: in this particular function, though, you can be even more clear with `(or (get ~key) (set ...))

23:44 cemerick: There's nothing there that will let a qualified name, though. Presumably there's a `get` macro you're also defining (since the core get fn won't take a single arg)?

23:46 st3fan: hm yeah i have get/set/delete .. this is a little memcache wrapper

23:47 i'm doing this:

23:47 cemerick: right; so, you're not using a gensym where you should be

23:47 st3fan: http://pastie.org/2317814

23:47 amalloy: st3fan: are those macros? there's no reason they couldn't be functions

23:47 st3fan: they are functions indeed

23:47 amalloy: then they're not letting qualified names either

23:49 fwiw, there's not much point in & body and ~@body if you're not wrapping them in a (do) at some point

23:49 or, at any rate, there could be plenty of use; but more likely what happens would surprise you

23:50 st3fan: yeah something is not right there

23:51 should the macro wrap the body in (do) or should the caller do that?

23:51 * amalloy isn't going to do any more guessing without all the code and/or a stacktrace

23:53 st3fan: yeah sorry

23:53 let me fix it and i'll post it

23:57 cool this works pretty well

23:57 the code is at http://pastie.org/2317844

23:58 amalloy: st3fan: i don't really see why memoize should be a macro either

23:59 st3fan: hm how would yo prevent the body from being evaluated then?

23:59 amalloy: (memoize "foobar" 60 #(do (Thread/sleep 2500) (* 2 21))) ;; more composable, i suspect

23:59 st3fan: oh

23:59 :-)

Logging service provided by n01se.net