#clojure log - Feb 09 2011

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

0:00 amalloy: &(class 1)

0:00 sexpbot: ⟹ java.lang.Integer

0:01 Raynes: &(type 1)

0:01 sexpbot: ⟹ java.lang.Integer

0:55 cobol_expert: http://stackoverflow.com/questions/4938195/in-clojure-is-there-are-recursive-version-of-code-logging

0:55 ^ not mine, but i'm curious

1:08 amalloy: cobol_expert: it doesn't make sense to "automatically" apply this to every sub-function because everything is a function

1:08 but there is a tracing feature somewhere in contrib

1:09 http://stackoverflow.com/questions/2352020/debugging-in-clojure

1:14 arohner: is there an xml parser that returns a vector in the same format as c.c.prxml?

1:24 no_mind: I have a lazy sequence of maps, like this ({"key0" "itemvalue0"} {"key1" "itemvalue1"} {"key2" "itemvalue2"}) . I want to merge all the itemms of seq into one map. How do I do this ?

1:26 khaliG: is it normal that the order of function defns matters when using require?

1:30 oh i see, have to use declare around that.. that's odd :/

2:07 defn: amalloy_: CDT, maybe?

2:23 khaliG: what's the idiomatic way of updating a vector in an agent?

2:24 i can see how to add an element to it, for example, but what if you want to change one element somewhere else

2:42 scottj: how do you get the var associated with a local? does this require eval? (let [x a-var] (var x)) won't work. I want a function (defn foo [x] ...(var x))

3:15 khaliG: wth does replace do for a vector?!

3:17 scottj: ? (replace {1 2} [1]) => [2]

3:17 aamar: same thing as a seq, no?

3:19 khaliG: ive been playing with it on the repl for 15 minutes and i still dont understand what it's doing..

3:20 scottj: it's like s/1/2/

3:20 search and replace

3:20 khaliG: right that's what i want to do but i cant get it to work the way i expect

3:20 scottj: paste something

3:21 khaliG: say i have a vector [1 2 3 4 5] and i want to replace the 4 with "four"

3:21 scottj: ,:test

3:21 clojurebot: :test

3:22 scottj: ,(replace {4 "four"} [1 2 3 4 5])

3:22 clojurebot: [1 2 3 "four" 5]

3:22 khaliG: that works, but it does something completely different with what i was trying [4 "four"]

3:23 scottj: ,(doc replace)

3:23 clojurebot: "([smap coll]); Given a map of replacement pairs and a vector/collection, returns a vector/seq with any elements = a key in smap replaced with the corresponding val in smap"

3:23 scottj: note "given a *map*"

3:23 khaliG: map vs vector

3:23 scottj: or the name of the arg, smap

3:23 khaliG: i read that doc several times too :/

3:24 scottj: happens to the best

3:24 khaliG: i didn't parse the map as an actual map not just a collection of pairs

3:24 scottj, thanks.

4:29 * khaliG gives up on his vector of structs wrapped in an agent for a JTable model

4:30 khaliG: what's the best clojure data structure/approach for this? :/

4:33 http://www.clojure.pastebin.com/bmuwjzBt

4:36 AWizzArd: khaliG: I do this with a closure over a proxy

4:37 khaliG: AWizzArd, tried to do the same thing really

4:37 but im stuck with finding a good mutable data structure for a table

4:37 AWizzArd: (let [data (atom nil)] (proxy [AbstractTableModel TableModelHelper] [] ...))

4:38 khaliG: AWizzArd, does your table allow user edits?

4:39 AWizzArd: And my TableModelHelper is a definterface that works directly on data, and offers getTableData, setTableData, setTableCell, clearTable, etc

4:39 khaliG: oh that is cool

4:39 what does setTableCell do?

4:39 as in behind the scenes

4:39 AWizzArd: My docstring says: "Resets table-data vector with 'data' and updates the table."

4:40 khaliG: so you build a whole new table?

4:40 AWizzArd: (.setTableCell my-proxy new-data)

4:40 (.setTableData my-proxy new-data) I mean

4:40 not Cell

4:40 Yes, this builds a whole table.

4:40 khaliG: ok

4:40 AWizzArd: When the user clicks on the "Request" button it queries data from the server and can simply put it into the table.

4:40 khaliG: well if i'm only changing one cell i dont want to rebuild a whole table (just because i'm lazy)

4:40 AWizzArd: The interface gives me direct access to the atom.

4:41 khaliG: exactly, that is what (setTableCell [row, column-key, data]) is for.

4:41 khaliG: how is your table stored internally?

4:42 AWizzArd: As I showed above: let [data (atom nil)]

4:42 or (atom []) I had

4:42 khaliG: so you have a vector of rows?

4:42 AWizzArd: Yes.

4:43 setTableData will (reset! table-data data) the atom, and it fires via (.fireTableDataChanged ^AbstractTableModel this)

4:43 khaliG: understood

4:44 AWizzArd: This approach I found to be pretty useful. May work for you.

4:44 khaliG: my tables are tiny so i dont mind doing it that way

4:44 AWizzArd: Scales very well.

4:45 For huge tables however one wants handlers that can take streaming data from a web server, and updates the table on the fly and not only when all data has arrived at the client side.

4:50 khaliG: getting the feeling in clojure i wont find nice and easy to use mutable structures where i can just call a set! on them, it will be much harder than that

4:52 ejackson: khaliG: not at all - its really easy.

4:53 khaliG: I spent yesterday banging around with JFreeChart which is the dark heart of mutability, and its tremendously easy.

4:55 AWizzArd: khaliG: What about an atom and reset! ?

4:55 (let [x (atom 10)] (println x) (reset! x 55) (println x))

4:55 ,(let [x (atom 10)] (println x) (reset! x 55) (println x))

4:55 clojurebot: #<Atom@10463c3: 10>

4:55 #<Atom@10463c3: 55>

4:55 khaliG: yea i get that part

4:56 but something like making a new vector thats different by one element at a given index?

4:56 AWizzArd: As I see it, it fits very exactly what you asked for. Only that it is called 'reset!' and not 'set!'.

4:56 khaliG: replace works on value not index

4:56 AWizzArd: ,(assoc [10 20 30 40 50] 2 10000)

4:56 clojurebot: [10 20 10000 40 50]

4:57 khaliG: man i would never have guessed assoc would do that!

4:57 AWizzArd: But this is a totally different issue now. A moment ago you criticized that Clojure does not offer you a mutable data structure that you can just set!.

4:57 Vectors are tries under the hood.

4:58 Their key is the index in the vec.

4:59 khaliG: assoc+set will do the trick for my problem

4:59 AWizzArd: ,(let [a (atom [10 20 30 40])] (println @a) (swap! a assoc 2 99) (println @a))

4:59 clojurebot: [10 20 30 40]

4:59 [10 20 99 40]

5:13 khaliG: assoc will become my new best friend

5:14 yay my table reflects user input changes :)

5:37 AWizzArd: khaliG: grats

5:57 khaliG: is it possible to return an agent from a method in a proxied java class?

6:02 doesn't look like it, not just an agent but any random method added

6:03 TobiasRaeder: morning

6:03 khaliG: morning

6:13 AWizzArd, how did you define your helper class?

6:17 AWizzArd: khaliG: definterface

6:17 khaliG: thanks

6:20 hard to find docs on it :/

6:28 tscheibl: is it a bug that I have to 'rm -rf classes' first before i do 'lein ring war'? .. otherwise I get some 'duplicate entry' error

6:34 khaliG: AWizzArd, do you have a small example of definterface? i've looked everywhere without any luck

6:39 AWizzArd, nm, i figured it out

7:33 AWizzArd: khaliG: even though you figured it out, here an example of definterface: https://github.com/clojure/clojure/blob/master/src/clj/clojure/gvec.clj

7:33 This was used for implementing (vector-of :int) & co.

8:22 jcromartie: let's say I have n students, and want to divide them into tables of m students each

8:22 I can get a bunch of possible tables from c.c.combinatorics/combinations

8:22 but that is only all tables of 5 over the whole set of students

8:28 ejackson: and you want ?

8:34 jcromartie: sets of tables which only contain different students

8:34 say

8:34 '(#{#{jim bob} #{sally sue}} #{#{jim sue} #{sally bob}} ...)

8:36 fliebel: jcromartie: I still don't get it, but I'm thinking abotu something with shuffle, partition, distinct, etc...

8:37 jcromartie: basically, given a classroom... how many seating arrangements are there

8:37 with a fixed table size

8:40 yeah I've been tinkering with this for a while but it just hasn't "clicked"

8:43 most of the time I come up with some insane number of possibilities

8:43 because I haven't limited it right

8:45 fliebel: jcromartie: Logos!

8:46 jcromartie: hm that might be a good idea, actually

8:46 although I think I have an algorithm, starting with the set of all possible table arrangements

8:48 fliebel: jcromartie: So, you have x persons, sitting at a 2x tables in pairs?

8:48 no x/2

8:49 jcromartie: no

8:50 x persons, sitting at x/n tables in groups of n

8:53 fliebel: jcromartie: And you want to know?

8:53 jcromartie: how many ways you can arrange seats at the tables

8:54 fliebel: Without permutations of the same persons for one table, I assume?

9:00 kilo_: hi

9:01 AWizzArd: Hey kilo_.

9:01 kilo_: newbie here

9:02 AWizzArd: Welcome.

9:02 joegallo: well, welcome. and hello.

9:02 kilo_: hi AWizzArd

9:02 thanks ! i'm planning to start of f by installing clojure box.

9:02 fliebel: jcromartie: Hm, there seem to be *a lot* of combinations :P

9:02 kilo_: :)

9:02 hi

9:02 jcromartie: fliebel: yup

9:03 especially with 30 kids and tables of 5

9:03 er, 25

9:03 fliebel: (distinct (map set (repeatedly #(map set (partition 5 (shuffle (range 20)))))))

9:05 jcromartie: yeah the shuffle is the trick

9:06 fliebel: jcromartie: That would go on forever.

9:06 jcromartie: so say I have the set of unique tables

9:06 basically, (set (map set (c.c.combinatorics/combinations students n)))

9:07 that's easy

9:07 1.5 seconds later...

9:07 I have 7288 tables

9:07 fliebel: good :)

9:07 AWizzArd: kilo_: did you already see http://java.ociweb.com/mark/clojure/article.html ?

9:09 jcromartie: now from there, I've got this

9:09 (remove #(some % (first tables)) (rest tables))

9:09 which finds the rest of the potential tables for the first table

9:09 easy

9:10 kilo_: i got this : http://news.ycombinator.com/item?id=1086562

9:10 AWizzArd: yes, got it today

9:16 fliebel: jcromartie: ##(distinct (map #(set (map set (partition 2 %))) (clojure.contrib.combinatorics/permutations (range 6))))

9:16 sexpbot: java.lang.ClassNotFoundException: clojure.contrib.combinatorics

9:17 jcromartie: permutations are too intensive, fliebel

9:17 http://www.wolframalpha.com/input/?i=25!

9:17 fliebel: I see, that are a lot of permutations...

9:18 jcromartie: but I think I've got it

9:18 fliebel: jcromartie: paste?

9:18 jcromartie: starting with the combinations it's pretty easy to find a valid set for any one table

9:18 yeah just a minute

9:28 ejackson: jcromartie: sorry, I stepped away. Do want the number of possible combinations, or to actually realise the sets of possible combinations ?

9:28 edoloughlin: Trying to add tests to an existing leiningen project... I've tried creating $PROJDIR/test/core.clj, $PROJDIR/test/$PROJDIR/core.clj and $PROJDIR/test/$PROJDIR/test/core.clj but I'm still getting "could not locate XXX on classpath" errors. Any ideas?

9:33 ejackson: jcromartie: the former is, I think, \sum_{i=1}^{5} (5i)C5

9:33 jcromartie: hm weird

9:35 ejackson: about 72 000

9:36 jcromartie: out of memory

9:36 awesome

9:36 :P

9:37 ejackson: the factorials like to explode

9:37 khaliG: there is an algorithm for generating them lazily so you don't run out of memory

9:39 fliebel: hm, probably another dead alleyway: ##(let [s (map set (combinations (range 20) 5))] (reduce (fn [t n] (if (not-any? #(seq (clojure.set/intersection n %)) t) (conj t n) t)) [(first s)] (next s)))

9:39 sexpbot: java.lang.Exception: Unable to resolve symbol: combinations in this context

9:46 jcromartie: that would explode in terms of computations

9:47 although maybe not too bad

9:47 raek: edoloughlin: how do you name the source and test namespaces? where do you put their corresponding files? what requires and uses do you have?

9:48 edoloughlin: what we need to know to debug your problem would be all the 'ns' forms of your files, along with the file path for each one

9:52 jowag: Hi, in deftype, do I have to implement all methods of the chosen interface or not?

9:53 edoloughlin: raek: I'm trying to retrospectively create tests on a lein project that doesn't have any. I've just created a core.clj file in the test subdirectory - there are no other test files. Do you want a directory listing? It's all of the form $PROJ/src, $PROJ/src/controllers, $PROJ/src/domain etc. and I have $PROJ/test

9:53 jowag: e.g. is this correct? (deftype A [] IFn (invoke [this] (do something)))

9:54 edoloughlin: Sorry: that should have been $PROJ/src/myproj/controllers etc. - I omitted the top level namespace

9:57 raek: edoloughlin: there is no automatic relationship between source and test code

9:58 edoloughlin: the test namespaces are ordinary namespaces containing ordinary code

9:58 edoloughlin: raek: So what does 'lein test' look for as its starting point?

9:58 raek: so it sound like there's something wrong with when you in the test namespace require/use the source namespace

9:59 edoloughlin: I think it loads all source files under test/

9:59 but I'm not sure, so check the lein docs on that one

9:59 edoloughlin: raek: Ok. Thanks.

9:59 raek: (I usually launch my tests straight from emacs)

10:03 fliebel: jcromartie: How is your code doing?

10:03 jcromartie: meh

10:03 the issue is something I failed to mention: a set of restrictions on what exactly defines a valid table

10:04 :P

10:04 there are a bunch of students who cannot sit together

10:04 and so by filtering on that, I get a limited number of tables

10:04 fliebel: jcromartie: Oh, this starts to look more and more as a logic programming problem ;)

10:04 jcromartie: yeah

10:04 but actually

10:04 it might be impossible to sit this particular set of restrictions

10:05 I think a better approach would be a Monte Carlo simulation

10:05 and make the restrictions less rigid

10:05 so you can score the seating

10:05 fliebel: jcromartie: If ti is impossible, Logos will tell you.

10:05 jcromartie: hm, nea

10:05 neat

10:05 link/

10:05 ?

10:05 (https://github.com/swannodette/logos)

10:05 fliebel: $google clojure logos

10:05 sexpbot: First out of 11900 results is: Logos v0.4 - Closing in on SWI-Prolog ? - Clojure | Google Groups

10:05 http://groups.google.com/group/clojure/browse_thread/thread/564d7885630549db

10:06 fliebel: I ordered The Reasoned Schemer to learn this stuff :)

10:06 jcromartie: $google logos clojure

10:06 sexpbot: First out of 12000 results is: Logos v0.4 - Closing in on SWI-Prolog ? - Clojure | Google Groups

10:07 http://groups.google.com/group/clojure/browse_thread/thread/564d7885630549db

10:07 jcromartie: weird

10:07 in my browser I get a bunch of stuff about Clojure logo graphics :P

10:07 AWizzArd: (:

10:08 you can try bing instead and see if that performs better

10:08 fliebel: Or DuckDuckGo, or…

10:11 jcromartie: fliebel: I'm afraid this is all greek to me

10:11 I've never done Prolog

10:12 fliebel: jcromartie: That is why I ordered the book… It's Italian to me. I can follow it a bit, but not write it.

10:13 jcromartie: well then maybe in that case I should say it's all Thai to me or something

10:15 fliebel: jcromartie: I think the musicians example is useful to you. If you extend that a little, you could use it to determine valid neighbors.

10:19 ejackson: jcromartie: if you can assign a score to the set of arrangements then indeed, a MC approach is a good one. You could optimise that score using simulated annealing pretty easily.

10:19 logic programming is going to give you all the solutions, which is not what you want, you just want one that is good enough.

10:20 fliebel: ejackson: Why would logic programming do that to you? doesn't that depend entirely on how you write it?

10:21 $google Monte Carlo simulation

10:21 sexpbot: First out of 627000 results is: Monte Carlo method - Wikipedia, the free encyclopedia

10:21 http://en.wikipedia.org/wiki/Monte_Carlo_method

10:21 ejackson: fliebel: I'm no expert, but it operates by performing a search for the complete set of suitable solutions.

10:22 clgv: ejackson: but prolog for example stops with the first valid solution and you have to use special statements to get all solutions

10:23 ejackson: clgv: i did not know that

10:23 fliebel: Hm, I don;t know about Logos, but if it does this stuff lazily, you could do (first) on it.

10:30 jcromartie: fliebel: the issue is when it gets fuzzy... say you have a set of restrictions that makes it impossible from a logic programming standpoint

10:31 ejackson: jcromartie: such as ? It sounds a lot like the Zebra problem.

10:33 jcromartie: well, let's say you really have restrictions that yield no solutions

10:33 it would be better, in this case, to let it be "good enough"

10:34 ejackson: then optimising a score is superior

10:34 clgv: jcromartie: if there are restriction that make you problem unsolvable - can't you do a mathematical analysis in advance to see if you can get crtieria on that?

10:34 ejackson: (as an aside http://intensivesystems.net/tutorials/logic_prog.html for the zebra problem)

10:36 jcromartie: clgv: I don't know that much math.

10:38 great, thanks ejackson

10:49 fliebel: Hah, when you're talking about the devil, you step on his tail :) The Reasoned Schemer just arrived :D

10:53 ejackson: fliebel: good luck, its a tough read :)

10:53 jcromartie: huh looks like http://kanren.sourceforge.net/ is pretty much broken

10:53 links, that is

10:53 ejackson: yeah, I had little luck with that either

10:54 fliebel: ejackson: Thanks :)

11:30 semperos1: anyone know how to get slime's M-. working on Windows? I do have an unzip utility on the path, but I still get errors

11:38 dnolen: anybody ever tried constraint logic programming in Clojure a la Mozart/Oz ? Or played around with this, http://jacop.osolpro.com/ (Java Constraint Solver)?

11:39 companion_cube: i've not played with it in clojure, but i know a bit of jacop

11:39 dnolen: companion_cube: any opinions, thoughts about it?

11:39 companion_cube: it's cool :)

11:40 most of the API is creating objects

11:40 dnolen: companion_cube: anything specific you used it for that you can talk about? :)

11:41 companion_cube: i did not use it, i've worked a bit with one of the guys that writes it

11:41 dnolen: companion_cube: heh, cool.

11:41 * raek just realized that unconstrained (i.e. non-clojurian/functional) mutation is basically a case of the "Action at a Distance" anti-pattern

11:42 raek: letting two threads share an unsynchronized mutable object is not much different from abusing global variables

11:43 AWizzArd: right

11:43 ejackson: so it is.

11:53 gko: If I want to use SLIME for both Clojure and Common Lisp, should I really stick to ELPA's SLIME (20100404) or can use CVS version? (swank-clojure in ELPA's wants SLIME 20091016)

11:55 puredanger: anyone out there worked with emacs + lein + cdt ? I'm looking for advice on how to get emacs-cdt working with separate lein swank

11:56 I have "lein cdt" working targeting my process in emacs with "lein swank" but I would really like to be running the cdt repl in emacs as well (maybe a separate emacs if that's easier)

11:57 The lein cdt hooks seem to install the jdt options for lein swank such that I can't start two lein swanks as they collide on the jvm debug ports

11:57 is there a technomancy in the house?

11:59 raek: Now I feel that I really understand what "Mutable stateful objects are the new spaghetti code" means

12:07 ejackson: raek: aren't insights like that great !

12:10 technomancy: puredanger: I haven't used cdt yet, sorry. it may have port numbers hard-coded in?

12:11 puredanger: technomancy: it does fer sure

12:11 technomancy: time for a patch then

12:11 puredanger: technomancy: yeah, maybe I'll try that. just hard to believe no one hasn't had this issue already

12:13 technomancy: I guess lots of people only keep one swank server running at once or at least don't start cdt until they need it

12:15 ohpauleez: puredanger: I use cdt with lein-cdt, but I use nailgun, sorry

12:40 cinch: technomancy: when my project.clj has a :main section and i call "lein swank", it runs the main instead of starting swank, is that normal or did i misconfigure something?

12:42 technomancy: cinch: :main should point to a namespace that contains a -main function; it shouldn't have anything happening at the top level except def/defn forms.

13:01 hv: wow! java chokes on (Double/parseDouble "2.2250738585072012e-308")

13:03 cinch: technomancy: thanks for the info. i think i found a minor bug, which happend when i had (defn -main [] ) instead of -main with a body. (brb)

13:08 khaliG: when using proxy, how do you call another method in the superclass -- i'm thinknig (.method this) which seems to compile at least

13:09 amalloy: khaliG: that sounds right to me. are you having trouble with it?

13:10 khaliG: amalloy, yeah, but it may be unrelated

13:11 raek: khaliG: that sounds right. in java, the bytecode for foo() is the same as this.foo()

13:11 fogus`: ,(doc proxy-super)

13:11 clojurebot: "([meth & args]); Use to call a superclass method in the body of a proxy method. Note, expansion captures 'this"

13:13 amalloy: khaliG: https://gist.github.com/27effcd9c46a0ca6f701 works as expected

13:13 raek: ah. my utterance would be for the particular situation where you don't override that method.

13:14 amalloy: you should only need proxy-super if you want to call a superclass's method when you also override that method

13:14 fogus`: (inc amalloy)

13:14 sexpbot: ⟹ 5

13:16 khaliG: yea i think my program is failing for an unrelated reason, thanks guys

13:16 amalloy: khaliG: if the superclass method you're trying to call is protected you have to jump through some hoops

13:17 khaliG: nope, not protected it's a method of AbstractTableMOdel and i'm calling it like (.fireTableChanged this)))))

13:18 but it's not forcing a redraw of the table for some reason

13:19 ooh, my mistake! i should have called .fireTableDataChanged

13:19 amalloy: khaliG: swing, what fun

13:19 khaliG: sweet :)

13:19 amalloy, yes but it's much much better in clj

13:20 fogus`: "Clojure: Making Swing less repulsive since 2007"

13:21 khaliG: fogus`, well said

13:25 amalloy: Scriptor: pharen looks just enough like clojure to make me comfortable, and enough like CL to trip me up :)

13:26 Scriptor: amalloy: thansk, though I swear any CL-yness is completely accidental :p

14:00 mattmitchell: i'm using :require in my namespace, which uses the :as option to bring in a function. Is it possible to access this same :as function from another namespace?

14:01 amalloy: mattmitchell: i don't think so. you can use alias or immigrate or something, which are in contrib, but it's generally frowned on

14:01 mattmitchell: amalloy: oh really? interesting.

14:02 raek: mattmitchell: :require-:as and :use-:only only affects the namespace they occur in. to get the same effect in another namespace, you have to specify it there too.

14:02 mattmitchell: raek: ok i'll do that. thanks.

14:04 raek: the point is to let each namespace author shorten fully qualified names (like foo.bar/some-fn) to something shorter (like b/some-fn or some-fn) whatever way the author of that namespace feels like

14:07 lotia: greetings all. is there a way to have lein use the version of clojure and clojure-contrib from clones of their respective git repos?

14:07 amalloy: $google lein checkout dependency

14:07 sexpbot: First out of 1200 results is: technomancy/leiningen - GitHub

14:07 https://github.com/technomancy/leiningen

14:07 amalloy: bah

14:08 anyway lotia, i think lein calls them checkout dependencies; that's about all i know, but it should be enough for you to find out how to use them

14:08 danlarkin: you can also use a SNAPSHOT, that's probably closer to what you really want

14:10 lotia: amalloy, danlarkin: thank you

14:12 raek: lotia: I think SNAPSHOT versions are what you are looking for. (unless you want a less than a few days old version or apply your own patches, in which case I would recommend using the checkouts feature)

14:13 http://build.clojure.org/snapshots/org/clojure/ <-- version can be found here

14:13 lotia: raek: this is more from an i'm curious perspective rather than how would i use it for a real project perspective

14:14 raek: e.g. [org.clojure/clojure "1.3.0-SNAPSHOT"]

14:15 ok.

14:15 lotia: raek: thanks

14:17 raek: SNAPSHOT = use a frequently built version, leiningen checkouts = override that with version with a checked-out/cloned version in the file system

14:20 shikaga_: Question: I have 2 files in the same directory and I include (:use class1) in the namespace of class2. But when I try to compile I get an error that says that class1.clj cannot be found in the classpath

14:20 What am I doing wrong?

14:22 What confuses me even further is that my test file created automatically by leiningen has no problem locating the file when using "lein test"

14:24 khaliG: is there a switch like construct?

14:24 amalloy: khaliG: there are cond and case, depending on what you want

14:25 khaliG: amalloy, case sounds like what i want, i have some keys and i want to eval an exp depending on key

14:27 amalloy: khaliG: there's also plain old maps: ##(let [options {:a first, :b second} type :a data [0 1 2 3]] ((options type) data))

14:27 sexpbot: ⟹ 0

14:27 khaliG: very cool

14:28 amalloy: multimethods are a nice generalization of all this; case is an optimized version when all your key types are compile-time literals

14:33 raek: shikaga_: are you sure that the names of the namespaces matches the paths of the source files?

14:34 shikaga_: also, you have to use their fully qualified names, even though they are in the same directory

14:36 shikaga_: Yeah

14:36 I think I am not fully understanding how namespaces are working

14:36 investigating now

14:36 thatnks

14:40 pdk: it's not like java where every .java file has to have a public class with the same name as its filename

14:44 amalloy: shikaga_: heh. here i am, putting off writing an article about managing clojure namespaces, and not even #clojure is a safe haven :)

14:45 rsenior`: amalloy: ping

14:45 amalloy: rsenior`: pong

14:46 Scriptor: quick question, what does clojure use internally as its hash function for hashmaps?

14:46 amalloy: Scriptor: Object.hashCode()

14:47 Scriptor: ah, thanks!

14:47 rsenior: amalloy: the issue I was talking to you about yesterday, I finally traced it down and was able to get better example code around it http://groups.google.com/group/leiningen/browse_thread/thread/cd433a9e8ac689c1

14:48 hiredman: that is not a lein issue

14:48 that is the clojure compiler

14:49 amalloy: rsenior: weird

14:49 rsenior: really?

14:50 hiredman: lein doesn't do anything with classloaders

14:50 rsenior: when I ran it from the command line, without lein, it seemed to work ok

14:50 doesn't compile/eval-in-project run compilation in an ant created classloader?

14:51 hiredman: no, it starts a new jvm (at least in all releases, dunno about on master)

14:51 it does use ant to launch the new jvm, but the classloader won't be shared between them

14:54 rsenior: I'm still a little puzzled as to why it would work from the command line (passed in as -e to clojure.main, just like how Leiningen does it)

14:54 hiredman: for a simple solution to your multimethod problem, you could dispatch on the name of the class instead of the class

14:55 rsenior: *shrug*

14:56 rsenior: yeah, I've talked through some workarounds with coworkers, that was one of them

14:59 khaliG: is it idiomatic to define small helper functions using let?

14:59 kryft: I read "idiotic" :P

15:00 amalloy: khaliG: yeah, that's fine

15:00 you can use letfn if you like, though i don't

15:00 brehaut: khaliG: yes i think it is. especially for functions that closure locals but are growing large

15:01 khaliG: cool thanks

15:01 nah i'm lazy less syntax to learn :P

15:03 amalloy: my thoughts exactly

15:13 khaliG: hm it doesnt like (. Boolean class)

15:14 amalloy: khaliG: Boolean is already the class

15:15 khaliG: oh yea, good point

15:15 amalloy: &(map class [Boolean Boolean/TYPE])

15:15 sexpbot: ⟹ (java.lang.Class java.lang.Class)

15:16 amalloy: hm, not the point i intended to make.

15:16 &[Boolean Boolean/TYPE]

15:16 sexpbot: ⟹ [java.lang.Boolean boolean]

15:18 fliebel: weird… ##(class boolean)

15:18 sexpbot: ⟹ clojure.core$boolean

15:18 amalloy: fliebel: boolean is a function

15:19 &(boolean 10)

15:19 sexpbot: ⟹ true

15:19 fliebel: amalloy: I know, so what did Boolean/TYPE just return?

15:19 amalloy: &(str Boolean/TYPE)

15:19 sexpbot: ⟹ "boolean"

15:19 amalloy: grr

15:20 hiredman: Boolean/TYPE is used by the clojure compiler internally for the clojure readable name of the boolean primitive's class

15:20 which is, I dunno, Z I think

15:20 amalloy: http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Boolean.html#TYPE

15:20 hiredman: yeah, i think it's Z

15:20 hiredman: ,(Class/forName "Z")

15:20 clojurebot: java.lang.ClassNotFoundException: Z

15:21 hiredman: well, I should say "type" not "class" above

15:21 fliebel: So, Boolean/TYPE is not just a symbol, but something magic for the compiler, that evaluates to a primitive?

15:22 hiredman: Boolean is a symbol too

15:22 amalloy: ,(.getMethod Class "isArray" (into-array []))

15:22 clojurebot: java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Class;

15:22 amalloy: ,(.getMethod Class "isArray" (into-array Class []))

15:22 clojurebot: #<Method public native boolean java.lang.Class.isArray()>

15:22 hiredman: there is by default, an entry in all namespaces that maps the symbol Boolean to the class Boolean

15:23 amalloy: somehow or other you can find the class name for primitive booleans :P

15:23 anthony__: If I have an external file with a bunch of forms (def "a" 1) (def "b" 2) etc...and I want to read/eval all of them, how do I do that? (eval (read-string (slurp "file"))) only does the first one.

15:23 hiredman: there is no class for primitives though

15:23 amalloy: hiredman: yes there is

15:23 hiredman: no there isn't

15:23 there is a type

15:24 primitive arrays have a classname (due to the jvm sort of kind of sometimes treating arrays as objects)

15:24 ,(Class/forName "[Z")

15:24 clojurebot: [Z

15:24 hiredman: ,(Class/forName "Z")

15:24 clojurebot: java.lang.ClassNotFoundException: Z

15:24 amalloy: from the javadoc for Class: "The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects."

15:25 hiredman: that is a java specific fiction, I believe

15:25 amalloy: hiredman: kindasorta

15:26 &(.getComponentType (class (boolean-array 2)))

15:26 sexpbot: ⟹ boolean

15:26 pdk: in javaland

15:26 amalloy: is a Class object, which represents the primitive type boolean

15:27 pdk: having primitives not be able to be treated like composite objects is supposed to be a good idea for some reason

15:27 fliebel: interesting

15:27 hiredman: amalloy: it very well may be, but sexpbot is ignored, so *shrug*

15:27 pdk: THE PRIMITIVE BOXING ARMY MARCHES FORWARD

15:27 amalloy: ,(.getComponentType (class (boolean-array 2)))

15:27 clojurebot: boolean

15:27 amalloy: pdk: i don't think anyone thinks it's a good idea, but it was a convenient idea when java was written

15:27 hiredman: ,(class (.getComponentType (class (boolean-array 2))))

15:27 clojurebot: java.lang.Class

15:27 fliebel: hiredman: Why is sexpbot ignored?

15:28 amalloy: fliebel: he doesn't like sexpbot

15:28 hiredman: fliebel: it does a lot of annoying things

15:28 at least it used to, hard to say now since it's been on ignore

15:28 amalloy: heh

15:29 i think Raynes listens to community complaints if it does something annoying in #clojure, but of course you're entitled to ignore it

15:29 fliebel: hiredman: Only thing I ever noticed it doing without explicit command is mentioning Clojars updates.

15:29 hiredman: fliebel: that is clojurebot, unless sexpbot does that too

15:29 amalloy: no, just clojurebot

15:29 fliebel: hang out in #sexpbot sometime. there are a lot of features that are explicitly disabled in #clojure to reduce clutter

15:30 but anyway, this discussion was about primitive types, not the robot wars

15:31 khaliG: heh :)

15:33 fliebel: amalloy: Sorry, I was poking at hiredman to test LauJensen's statement that he is rude and insulting. False so far :) But about the primitives… Is there a way to get to Boolean/TYPE without actually using that?

15:33 amalloy: fliebel: two ways have just been demonstrated: ##(Boolean/TYPE) and ##(.getComponentType (boolean-array 0))

15:33 sexpbot: (Boolean/TYPE) ⟹ boolean

15:33 (.getComponentType (boolean-array 0)) java.lang.IllegalArgumentException: No matching field found: getComponentType for class [Z

15:34 hiredman: fliebel: for what purpose?

15:34 amalloy: er

15:34 &(.getComponentType (class (boolean-array 0)))

15:34 sexpbot: ⟹ boolean

15:34 hiredman: I have been rude and insulting to LauJensen, but he deserved it

15:34 fliebel: hiredman: Curiosity, I wondered why I should write Boolean?TYPE rather than jus [B or something.

15:35 amalloy: fliebel: ^"[B" is an array of bools, not a bool

15:35 is the typehint for an array of bools, that is

15:35 hiredman: Boolean/TYPE is readable bby the reader, [B isn't

15:35 fliebel: I see.

15:36 amalloy|afk-fore: man

15:36 nick length limitations

15:36 hiredman: the compile may provide something like ^booleans for type hinting, it does for some of the other primitives

15:36 fliebel: amalloy: Can I aslo do ^Boolean/TYPE for a type hint?

15:36 ah

15:36 hiredman: compiler

15:54 andyfingerhut: In Clojure 1.2, is there a way to declare a method with a return value that is an array of Java primitives specifically? That is, not just defaulting to an Object, which all Java arrays are, but specifically an array of primitives?

15:54 Sorry, I meant all of that "in a definterface"

15:55 amalloy_: andyfingerhut: we had a long discussion about this like half an hour ago; you probably want to just check out the logs. tl;dr: ^"[D" should be the type-hint for an array of doubles

15:56 &(class (double-array 1))

15:56 sexpbot: ⟹ [D

15:56 andyfingerhut: Sorry I missed it.

15:56 hiredman: ^doubles actually

15:58 https://guthub.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L975

15:59 andyfingerhut: So I can AOT compile a program with either ^"[D" or ^doubles as the type hint for a method return value in a definterface, but if I then try to do clojure.contrib.repl-utils/show with the name of the interface, I get a run time error NoClassDefFoundError: java/lang/doubles

15:59 Is the type hint working, but there is perhaps a bug in repl-utils/show?

16:01 hiredman: definterface may not know how to do the ^doubles thing

16:01 andyfingerhut: Or the ^"[D" thing, apparently.

16:02 amalloy_: hiredman: oh, that's handy. what about an array of double arrays?

16:04 andyfingerhut: definterface seems to have the same limitation in type-hinting arguments to methods: Java primitives can be hinted fine, and individual references of Object or any subclass, but not arrays of any kind (that I've found a syntax for).

16:04 hiredman: amalloy_: I think you are best off using ^objects in that case

16:05 andyfingerhut: you could inspect the output of the definterface macro

16:05 andyfingerhut: hiredman: You mean the byte codes it emits?

16:05 Or just the macroexpansion?

16:06 hiredman: the second

16:06 andyfingerhut: I'll try that...

16:06 hiredman: you may need to pull the form apart and inspect the metadata on different pieces too

16:08 khaliG: is there a looping construct to perform side-effects over a sequence?

16:09 (this is for setting the width for table columns in swing)

16:09 fliebel: khaliG: doseq?

16:10 khaliG: fliebel, sounds liek the thing, thank you

16:25 scottj: can anyone explain this behavior, (defn ^{:a 1} foo []) (meta foo) => no {:a 1} then (defn ^{:a 2} foo []) (meta foo) => {:a 1}

16:34 that's in clojure 1.2. something must be different in 1.3 bc all those meta calls return nil

16:34 raek: scottj: I get nil both times (1.3)

16:34 scottj: the metadata you put on the symbol ends up on the var, rather than the function object

16:35 but that behaviour in 1.2 looks a bit weird to me

16:35 (meta #'foo)

16:37 khaliG: is there a way to print to string?

16:38 raek: khaliG: pr-str

16:38 khaliG: raek, cheers

16:38 brehaut: ,(with-out-str (prn "hello"))

16:38 clojurebot: "\"hello\"\n"

16:38 raek: &(pr-str [:foo "bar"])

16:38 sexpbot: ⟹ "[:foo \"bar\"]"

16:38 scottj: raek: in 1.2 the (meta foo) will return old data while (meta #'foo) returns latest

16:40 the reason I wanted to put the data on the function instead of the var is it seems easier to get at. if I have foo then (let [x foo] (meta x)) will work while it won't if the data's on the var I'm not sure how to get to it if there's indirection

16:43 fliebel: scottj: Maybe you could do a macro to do (def (with-meta (fn)))

16:43 raek: scottj: what are you using the metadata for?

16:45 scottj: raek, type checking. I have an abstraction that can be either maps or fns

16:46 something like (defn slice? [x] (or (instance? slice.core.Slice x) (and (fn? x) (:slice (meta x)))))

16:47 raek: then I believe what fliebel makes sense.

16:48 if you are inspecting the functions rather than the vars

16:48 *what fliebel suggested

16:48 scottj: well I'd be happy to inspect the var but in the function slice? I pasted I'm not sure how to do that since calling (var x) will fail

16:49 raek: in general, you can't go from function object to var object

16:50 scottj: as in (defn foo [x] (var x)) (foo map) ?

16:50 raek: var is a special form.

16:50 the symbol representing the var must be known at compile time

16:50 scottj: yeah, so there's no macro trickery to make that work you'd have to call (foo #'map)?

16:51 raek: then you can't use it with anonymous functions, or functions that has been letted or passed though a function parameter on the way...

16:52 scottj: ok so was fliebel saying (def fn-name (with-meta (fn declaration...)) instead of defn?

16:52 raek: if you need the metadata on the function, then put it on the function

16:52 yes

16:52 (def foo (with-meta (fn [x] ...) {:a 1}))

16:54 scottj: gosh that's annoying that defn doesn't work that way bc now I have to set the metadata for arglist etc manually

16:54 raek: you can write a macro for that...

16:55 scottj: I think this will work, thanks for the help!

16:55 raek: np.

17:07 semperos: trying to do a basic gen-class

17:07 here's my code

17:07 https://gist.github.com/819398

17:07 stacktrace included for when I run "lein compile"

17:08 what am I doing wrong?

17:09 raek: semperos: the JVM doesn't allow names with dashes in them (the "-" prefix is removed by clojure, so it doesn't count)

17:09 semperos: heh

17:10 now I remember that

17:10 raek: thank you

17:10 raek: (this is why - in namespace names are translated into _ in file names)

17:11 semperos: raek: yep

17:11 I'm a little spoiled by recent JRuby use

17:11 which auto-converts between underscored and camel-cased method names

17:11 so you can write it either way in your jruby

17:12 I pay attention to is for namespaces, wasn't even thinking about it for the function call, but makes perfect sense

18:03 jhulten: I am having an issue reading a property file... https://gist.github.com/819513

18:03 If anyone has pointers, it would be appreciated.

18:25 markskilbeck: How would I send color-coding escape characters to something like println?

18:26 belief: Hey guys, what is the best resource to getting started learning clojure for an experienced Java developer?

18:27 pdk: the books programming clojure or practical clojure would work

18:27 grab a primer on lisp like the online version of sicp as well perhaps

18:28 belief: thanks pdk

18:28 will check them out

18:28 markskilbeck: belief: http://clojure.blip.tv/file/982823/

18:28 clojurebot: #<RuntimeException java.lang.RuntimeException: java.lang.Exception: 502>

18:29 pdk: you so silly clojurebot

18:29 markskilbeck: chuckle chuckle

18:29 belief: thanks markskilbeck had not come across those videos

18:38 rata_: hi

19:23 _Vi: "user=> (ns qqq (:use some.namespace))" -> It parse some/namespace.clj. How to make it to parse the file again?

19:23 (without reloading JVM)

19:26 dakrone: _Vi: (ns qqq (:use [some.namespace] :reload-all))

19:28 _Vi: dakrone, Thanks, it works.

19:31 dakrone: np

19:39 amalloy: markskilbeck: re color codes, you should be able to include any characters you want in your string with \x or \u escapes

19:40 markskilbeck: amalloy: thanks

19:40 amalloy: hm, not \x, i guess

19:40 &"\u000a\u0007"

19:40 sexpbot: ⟹ "\n"

19:41 amalloy: results in \n and a bell noise in my repl

20:16 no_mind: I have a string with & characters in ti. I want to split into smaller strings at & characters and store sub strings as a vector, in the order they appear in original string. How do I do this ?

20:17 brehaut: ,(vec (.split "foo&bar&baz" "&"))

20:17 clojurebot: ["foo" "bar" "baz"]

20:18 brehaut: no_mind: does that answer your question?

20:19 secondly, if you are doing this for HTTP, im sure there a library in ring to do it for you

20:19 no_mind: brehaut: yup, thanks

20:29 amalloy: brehaut: what, no regexes?

20:30 no_mind: I have couple of webpages as html files. Is there a library that can take html pages, fill values from database and render the page. These are html forms and I want to edit some entities in the application

20:31 brehaut: amalloy: fine ##((comp vec (partial take-nth 2) (partial re-seq #"[^&]*")) "foo&bar&baz")

20:31 sexpbot: ⟹ ["foo" "bar" "baz"]

20:31 brehaut: no_mind: sounds a lot like enlive

20:32 no_mind: amalloy: any advantage of using regex in this situation ?

20:32 brehaut: no_mind: its a joke at my expense

20:32 no_mind: ok

20:41 mec_: with emacs (clojurebox) is there a way when i eval in a buffer to send it to the repl so the result is printed instead of just flashing in the messages window?

20:48 amalloy: mec_: C-c C-c evaluates a top-level form, so that will probably work?

20:51 mec_: amalloy: C-c C-c is just giving me an error, i usually use C-x C-e or M-C-x, but that will only return the result in the messages window not the repl

20:52 amalloy: mec_: C-c C-c wants you to run C-c C-k at least once to compile the whole file, so that the namespace exists

20:52 not ideal, but...

20:53 qed: amalloy: can't you just C-x C-e the (ns ...) and then C-c M-p, set the namespace in the repl, and then C-c?

20:53 C-c C-c rather

20:53 amalloy: qed: probably, yes

20:53 qed: my way sounds more complicated to explain, but i think is a bit more natural

20:54 i dont like to load everything into the REPL at once usually

20:54 amalloy: qed: i usually load it all, myself. what do you use incremental loading for?

20:55 qed: amalloy: ill walk through code -- looking at the way functions behave along the way

20:55 in order to get a feel for the code

20:56 amalloy: qed: for other people's code, or your own?

20:57 qed: both sometimes :)

20:58 i like to load up incrementally -- it usually goes pretty quick and by the time im done i have more of it in my head and can make better decisions about design etc.

20:58 C-c C-k seems like a sledge hammer -- i like to whittle

20:59 amalloy: fair enough

21:01 qed: amalloy: but of course, if i make some sweeping change like renaming something throughout several files then I C-c C-k like a mad man :)

21:03 mec_: This is mainly for a scratch file that doesnt have a (ns ...) so I can keep track of dev in the repl. I really just want whatever I eval to behave as If i copied it into the repl first and hit enter

21:04 qed: mec_: check out C-h C-x C-e and see what it calls versus what C-c C-c calls

21:06 mec_: C-c C-c just gives namespace error, C-h C-x C-e is undefined

21:06 qed: err C-h k C-x C-e

21:06 mec_: slime-eval-last-expression

21:06 no_mind: is it possible to merge two vectors and create a new vector ?

21:07 brehaut: ,(concat [1 2 3] [:a :b])

21:07 clojurebot: (1 2 3 :a :b)

21:07 qed: ,(apply conj [1 2 3 4] [5 6 7 8])

21:07 clojurebot: [1 2 3 4 5 6 7 8]

21:07 qed: brehaut's is the right way though :)

21:07 amalloy: no_mind: well yes, but the usefulness of an answer will depend on what you mean by "possible" and "merge"

21:08 (and also possibly "vector")

21:08 qed: :D

21:08 brehaut: i've found that most of the time with clojure it's best to phrase your question in terms of what you're trying to achieve

21:08 err no_mind

21:08 brehaut: heh

21:08 qed: an example would be better is what i'm saying...

21:08 no_mind: amalloy: let me rephrase, say have two vectors [a b c] and [d e] I want to create a vector which has [a b c d e] , in that order

21:09 qed: ,(concat [1 2 3] [4 5])

21:09 clojurebot: (1 2 3 4 5)

21:09 mec_: ,((comp vec concat) [1 2 3] [4 5 6])

21:09 qed: seems to do the job, no_mind -- no?

21:09 clojurebot: [1 2 3 4 5 6]

21:09 brehaut: $findfn [1 2 3] [4 5] [1 2 3 4 5]

21:09 sexpbot: [clojure.set/union clojure.core/lazy-cat clojure.core/concat clojure.core/into]

21:09 brehaut: qed, like that? ;)

21:09 * qed 's jaw drops

21:10 mec_: zomg i wants it

21:10 qed: i was going to suggest into actually

21:10 brehaut: $findfn inc [1 2 3] [2 3 4]

21:10 sexpbot: [clojure.core/map clojure.core/pmap clojure.core/keep]

21:10 brehaut: ,(doc keep)

21:10 clojurebot: "([f coll]); Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values will be included. f must be free of side-effects."

21:10 amalloy: haha pmap. way to go sexpbot, solve these problems with the magic of threading

21:11 mec_: interesting

21:11 brehaut: huh. keep is cool

21:11 qed: ,(into [] (concat [1 2 3] [4 5 6]))

21:11 clojurebot: [1 2 3 4 5 6]

21:12 brehaut: ,(into #{} (concat [1 2 3] '(4 5 6 1))

21:12 clojurebot: EOF while reading

21:12 brehaut: bah

21:12 qed: naughty!

21:12 amalloy: into is the right answer, though

21:12 mec_: where can i get findfn

21:12 qed: mec_: sexpbot ;)

21:12 amalloy: mec_: nobody's bothered to write a version that doesn't live in sexpbot

21:12 qed: $findfn #{:a 1} [1 2 3]

21:12 sexpbot: []

21:13 qed: $findfn [1 2 3] [3 2 1]

21:13 sexpbot: [clojure.core/rseq clojure.core/reverse]

21:13 amalloy: but you can ask him via /msg sexpbot findfn blah blah blah

21:13 * qed runs off to look at how they implemented findfn

21:13 gfrlog: I can't bind symbols in a macro can I? ("Can't use qualified name as parameter"...)

21:14 amalloy: gfrlog: there are two ways to do it depending on your goal

21:14 gfrlog: e.g., local variables that I want the caller to be able to access

21:14 I know about the x# thing

21:14 amalloy: ah, then you want the other answer

21:14 brehaut: haha the other answer

21:14 gfrlog: :) I guess so, because I'm assuming x# is inappropriate here

21:14 mec_: ,(source findfn)

21:14 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

21:14 qed: binary answers, only in clojure/.

21:14 gfrlog: since I want it to work before being rewritten

21:14 amalloy: &`(let [~'x 10])

21:14 sexpbot: ⟹ (clojure.core/let [x 10])

21:14 brehaut: mec_ its part of sexpbot, rather than clojure

21:15 amalloy: $whatis sexpbot

21:15 sexpbot: sexpbot is http://github.com/Raynes/sexpbot

21:15 qed: mec_: cd-client could be nice for you

21:15 gfrlog: holy jackwagon

21:15 qed: lol

21:15 mec_: ah ok

21:15 qed: jackwagon...

21:16 https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/clojure.clj

21:16 amalloy: https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/clojure.clj#L156 for findfn,

21:16 qed: :)

21:16 gfrlog: amalloy: could you explain what is going on with your 3 kinds of quotes? I've not seen most of thoes outside a macro

21:16 amalloy: gfrlog: macros aren't special; ` works anywhere

21:16 qed: $`(let [x 10])

21:16 amalloy: but i can't defmacro in sexpbot or clojurebot

21:16 qed: ,`(let [x 10])

21:16 clojurebot: (clojure.core/let [sandbox/x 10])

21:17 amalloy: &`(let [x 10])

21:17 sexpbot: ⟹ (clojure.core/let [clojure.core/x 10])

21:17 gfrlog: this is witchcraft, right?

21:17 qed: ,`(let [~x 10])

21:17 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context

21:17 amalloy: lol

21:17 qed: ,`(let ['x 10])

21:17 clojurebot: (clojure.core/let [(quote sandbox/x) 10])

21:17 qed: ,`(let [~'x 10])

21:17 clojurebot: (clojure.core/let [x 10])

21:17 amalloy: gfrlog: http://hubpages.com/hub/Clojure-macro-writing-macros is something i wrote recently and is semi-on-topic

21:18 search for ~' to skip to the relevant part

21:19 _Vi: I want clojure.lang.PersistentArrayMap, but with overridden toString. How it's better to do it?

21:19 amalloy: _Vi: ##(doc proxy)?

21:20 sexpbot: ⟹ "Macro ([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which cre... http://gist.github.com/819794

21:20 qed: ,'~`'~'!

21:20 clojurebot: (clojure.core/unquote (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote !)))))

21:20 qed: *evil grin*

21:21 gfrlog: amalloy: that is quite

21:21 qed: I thought proxy had fallen out of favor...

21:21 gfrlog: I think ~' works though, since I'm getting other errors; so thanks!

21:21 amalloy: quite...anything in particular?

21:22 gfrlog: quite describably by adverbs maybe?

21:22 amalloy: qed: maybe. i don't know any better way to get actual implementation inheritance

21:23 qed: amalloy: reify?

21:23 brehaut: amalloy: the alternative would to reify the whole interface, closuring the map in question i think

21:23 amalloy: right, but you have to do the whole interface

21:23 qed: ^^ -- My understanding is that since 1.2 you should almost always be using reify

21:24 proxy is niche

21:24 brehaut: qed but this is the niche in question is it not?

21:24 hiredman: proxy will generally be much slower

21:24 * qed shuts up and actually reads the question

21:24 qed: and then hiredman comes in and owns everyone's face

21:24 _Vi: (proxy [clojure.lang.PersistentArrayMap] [{:key "val"}] (toString [] "qqq")) ;; What's wrong here?

21:25 hiredman: _Vi: why are you doing that?

21:25 qed: _Vi: the parens. lisp is a filthy, filthy language.

21:25 _Vi: How to create map {:key "val"}, but with overridden toString?

21:26 brehaut: _Vi you would want to closure over that map; its not a property of the proxy object itself

21:27 _Vi: brehaut, How to do it?

21:27 brehaut: (let [map {:key "val}] (proxy ...)

21:27 )

21:27 qed: ahhh yes...

21:27 brehaut: and dont call it map, thats a terrible name

21:27 * qed was busy googling for brehaut's answer

21:27 brehaut: (shadows a core method)

21:28 hiredman: brehaut: no

21:28 brehaut: haha no all of it, or one particular part?

21:28 hiredman: _Vi: I question your need to override .toString

21:28 brehaut: all of it

21:28 qed: lol

21:28 amalloy: brehaut: proxying a closure won't be any better than reifying one

21:28 qed: no.

21:28 fin.

21:28 amalloy: and if you're going to all the work, you might as well be fast with reify

21:28 _Vi: hiredman, I'm inserting it to javax.swing.DefaultListModel.

21:29 hiredman: _Vi: and why does that require an overriden .toString?

21:30 tomoj: brehaut: shadowing isn't terrible

21:30 _Vi: hiredman, It is displayed as '{:key "value"}' in gui instead of, for example, 'value'.

21:31 gfrlog: ,(class *out*)

21:31 clojurebot: java.io.StringWriter

21:31 hiredman: _Vi: if you want "value" you should put in value

21:31 _Vi: hiredman, And how to retrieve the details of selected list item then?

21:33 (let [q {:key "val"}] (proxy [clojure.lang.PersistentList] [q] (toString [] "qqq"))) ;; works

21:33 hiredman: _Vi: I don't have your code here, and I don't know what you are doing, but it seems like storing stuff you don't want to display in a swing coponent is a bad idea

21:33 _Vi: (let [q {:key "val"}] (proxy [(type q)] [q] (toString [] "qqq"))) ;; why doesn't it work?

21:34 qed: there's too much java implicit in this question for me to be genuinely helpful.

21:35 hiredman: component

21:35 qed: hiredman: you're going to have to offer more than that if you want him to understand you

21:35 hiredman: and the javadoc for javax.swing.DefaultListModel says it is based on Vector, which is a bad idea in general

21:35 qed: _Vi: i dont mean to be rude, but im guessing your first language is not english

21:37 _Vi: qed, What is not meaningful and needs revision?

21:37 qed: hiredman: is there a reason deftype shouldn't be considered here?

21:38 brehaut: _Vi: (str (let [m {:key "val"}] (proxy (Object) [] (toString [] "123"))))

21:38 hiredman: qed: why should it be considered?

21:38 gfrlog: what's the easiest way for me to create a "middleware" java.io.Writer to use with *out*?

21:38 qed: hiredman: im asking you an open question -- does it have any bearing on this discussion in your opinion?

21:38 tomoj: brehaut: what's m for?

21:38 brehaut: _Vi: you need to pass the class or interface you want to proxy to the first arg of proxy (as per (doc proxy)); no superconstructure args. b) probably should use reify if its just the tostring you want and c) everything hiredman says

21:39 tomoj: presumably you'd do something smart with it insdie the proxy

21:39 hiredman: deftype shouldn't generally be considered because defrecord is far more useful

21:39 tomoj: that sounds nuts

21:39 hiredman: I should say in most cases

21:39 qed: I think proxy is definitely wrong here

21:40 err I'll concede in a similar fashion and say that, in most cases, proxy is wrong

21:40 hiredman: (into list (vals {:key "value"})

21:40 qed: it used to be the only way, but we have so many more options to solve problems like this post 1.2

21:40 hiredman: proxy, if anything, would be more correct in this case, because proxy would allow you to overide a method without have to implement the entire interface

21:41 brehaut: _Vi: corrected for tomoj's observation (str (let [m {:key "val"}] (proxy (Object) [] (toString [] (:key m)))))

21:41 "val"

21:41 tomoj: qed: isn't this a problem not worth solving?

21:41 qed: tomoj: DeMorgan's

21:42 tomoj: is this problem worth solving? (I expect not)

21:43 _Vi: brehaut, If I replace "str" with ":key" I get "nil" instead of "\"val\"", so it's not like a map.

21:43 tomoj: er, figured you wanted me to rephrase, but now that I think about it, what do you mean, "DeMorgan's"?

21:43 qed: tomoj: tomoj the double negative :)

21:44 brehaut: _Vi: are you wanting a map, or are you wanting something you can pass to your swing thingimy that takes a map and returns a string for display

21:44 qed: is not this a problem not worth solving?

21:44 http://en.wikipedia.org/wiki/De_Morgan's_laws

21:45 _Vi: brehaut, I want subclass of map that is like PersistentHashMap, but with little bit of my functionality (toString).

21:45 tomoj: did you read it before linking it to me? I was considering sending you that link :)

21:45 qed: tomoj: actually ive completely screwed that up -- for some reason i think of demogran when i think of double negation

21:45 brehaut: _Vi: you do not want a subclass; this is not java. prefer delegation over inheritance

21:45 hiredman: _Vi: why do you need a subclass of PHM?

21:47 _Vi: hiredman, To make an object that have certain differences from PHM but still compatible with it in all other places.

21:47 qed: tomoj: sorry about that :D

21:47 hiredman: _Vi: why do you need that?

21:48 _Vi: hiredman, Here I'm trying to use it for DefaultListModel (but may be this can be useful in other places as well).

21:48 hiredman: that doesn't make sense

21:48 brehaut: _Vi are you familiar with the idea 'seperation of concerns'?

21:48 hiredman: just call a make-displayable function on it before hand

21:48 qed: _Vi: http://en.wikipedia.org/wiki/Separation_of_concerns

21:50 brehaut: _Vi: the basic idea here is that the data model aspect of your program (represented by the persistent hash map) is a seperate aspect to displaying it in a DefualtListModel. Because of this you should not have a piece of code that acts in both roles

21:51 _Vi: brehaut, OK, considering creating separate special object like DisplayableItem with reference to the map.

21:51 brehaut: _Vi if all you need is a ToString, theres already a built in type that provides ToString for you easily: String. you wont need to go to the effort of creating a new type.

21:52 _Vi: just make a function that takese your map and produces a string that is the display value

21:52 also sorry about the dotnet there

21:53 _Vi: because your map is immutable, any object that just returns a tostring of it equivalent to just that string anyway

21:53 qed: aside: I constantly wonder about Java in clojure programs and what role it should play in practice

21:53 _Vi: brehaut, OK. Considering Clojure's classes as final and non-extendable (not-easily-extendable) for future.

21:54 brehaut, The map is not just a string. When accessed from other places it is like a map.

21:54 brehaut: qed its interesting eh; theres definate merit to it, but where does that leave clr clj, or js-clj or whatever

21:54 _Vi and in those places, just provide the map

21:55 qed: brehaut: i dont know man -- i kind of find using java in clojure programs to be sort of dirty -- it's not an objective criticism, it's more of a visceral reaction on my part

21:55 tomoj: I'd bet if we had to write everything from scratch in pure clojure, clr and js wouldn't even be on the map

21:56 _Vi: qed, Is using Java in Clojure like using asm in C?

21:56 qed: _Vi: no not at all

21:56 brehaut: qed sure but at the same time, imagine clojure's web libs without all the stuff ring builds on

21:56 qed: clojure was /built/ to use java

21:56 tomoj: s/we/they/

21:56 sexpbot: <tomoj> I'd bet if they had to write everything from scratch in pure clojure, clr and js wouldn't even be on the map

21:56 qed: i just find it sort of repugnant

21:56 tomoj: someday I'm going to murder you, sexpbot

21:57 qed: tomoj: sexpbot knows more clojure than you do

21:57 he spends all day in this channel, every day, logging, watching, waiting, plotting...

21:57 _Vi: qed, It makes the code less lispy?

21:58 qed, Public channel logs is one of the source of information. Sometimes I find answers there.

21:58 qed: _Vi: my opinion is somewhat extreme. java is so disgusting to me that even something as innocent as java.lang.String can make me want to kill someone

21:58 but that is definitely not the whole story

21:58 using java is a huge win for clojure

21:58 i just personally go out of my way to not use it

21:59 _Vi: qed, To love Clojure, while hating Java? Strange feeling?

21:59 qed: i like the lisp in clojure -- i like the JVM in clojure, but the Java, well, that's another story

22:02 brehaut: tell me im being irrational, spoiled, etc.

22:02 brehaut: nah

22:02 i have no love for java.lang

22:03 qed: that sounds like the seed of a rap song

22:03 i gotz no luv 4 java.lang, son

22:03 brehaut: haha

22:04 qed: brehaut: did you go to clojure conj?

22:04 brehaut: qed nope; im literally on the wrong side of the world

22:04 qed: if you're on the wrong side and im on the "right" side, then we're all on the wrong side

22:04 brehaut: haha

22:06 qed where is your wrong side?

22:07 gfrlog: I bet he lives on the wrong side of the earth's crust

22:07 brehaut: hes a hyperborian?!

22:08 gfrlog: that is a strange word

22:09 something starting with "hypo" might do

22:10 ,(clojure.java.io/make-output-stream "/dev/null")

22:10 clojurebot: java.lang.IllegalArgumentException: No single method: make_output_stream of interface: clojure.java.io.IOFactory found for function: make-output-stream of protocol: IOFactory

22:10 brehaut: gfrlog: in Hellboy, the Hyperboreans are the first race of man, and the decendants live secretly deep under the earth, occasionally rising up to try to reclaim their land

22:10 Hyperborea was actually supposed to be on teh top of the world; eg the artic

22:11 gfrlog: okay. So I shouldn't take hints from the etymology then

22:11 brehaut: nope

22:11 gfrlog: hypocrustian

22:11 hypocrustacian?

22:12 anybody know the easiest way to replace *out* with /dev/null?

22:12 zippy314: gfrlog: (binding [*err* (java.io.PrintWriter. (writer "/dev/null"))] ... )

22:12 gfrlog: ,(clojure.java.io/output-stream "/dev/null")

22:12 clojurebot: java.security.AccessControlException: access denied (java.io.FilePermission /dev/null write)

22:13 gfrlog: zippy: that looks good, thanks

22:13 zippy314: just replace *err* with *out* (I was copying from my code)

22:13 gfrlog: right

22:13 Scriptor: anybody know exactly which algorithm Object.hashCode() uses?

22:14 gfrlog: doesn't it return an int?

22:14 ,(class (.hashCode "hooha"))

22:14 clojurebot: java.lang.Integer

22:14 hiredman: for the default impl .hashCode could just be the pointer address

22:14 gfrlog: ,(.hashCode 382)

22:14 clojurebot: 382

22:14 Scriptor: yea, that seems to be the typical case

22:14 hiredman: the impl for a specific class can be whatever

22:14 amalloy: Scriptor, hiredman: yes, for Object hash is just the memory address

22:15 brehaut: ,(.hashCode (Object.))

22:15 clojurebot: 15771477

22:15 brehaut: thats closer to the 'default'

22:15 amalloy: &((juxt hash str) (Object.))

22:15 sexpbot: ⟹ [5749406 "java.lang.Object@57ba9e"]

22:16 brehaut: " (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the JavaTM programming language.)" – http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#hashCode()

22:16 amalloy: &((juxt #(Integer/toHexString (hash %)) str) (Object.))

22:16 sexpbot: ⟹ ["aa6e7e" "java.lang.Object@aa6e7e"]

22:17 brehaut: have some ellipsis for that preceeding quote: … …

22:18 amalloy: $sed -brehaut s/(.*)/...$1...

22:18 sexpbot: <brehaut> ...have some ellipsis for that preceeding quote: … ….........

22:18 amalloy: hm. more dots than i expected, but w/e

22:18 hiredman: ^- if I actually saw that output it would be annoying

22:18 amalloy: hiredman: yeah, but that's me being annoying, not sexpbot :)

22:19 but enabling and/or encouraging, you're right i'm sure

22:25 bytecolor: is this an appropriate way to bind *out* to /dev/null? (binding [*out (java.io.OutputStreamWriter. (java.io.FileOutputStream "/dev/null"))] (println "foo"))

22:25 I missed the response to the previous question, if there was one...

22:25 hiredman: http://commons.apache.org/io/api-release/org/apache/commons/io/output/NullOutputStream.html

22:28 bytecolor: I missed an asterisk in *out*, and a period after Stream :/

22:29 amalloy: hiredman: funny stuff in there. i like the BrokenOutputStream

22:33 bytecolor: (alter-var-root (var paip.eliza1/variable?) (fn [_] #(some #{%} '(x y z))))

22:33 is there a proper way to do that? basically change a function in another namespace?

22:34 that's a hackish way I figured out that works, but it just feels wrong on a number of levels ;)

22:35 tomoj: one level likely being just what you're trying to do

22:35 why do you want to change it?

22:45 amalloy: sritchie_: ping

23:09 $mail sritchie http://commons.apache.org/io/api-release/org/apache/commons/io/input/SwappedDataInputStream.html looks like it would help with your pymath or whatever the problem library was

23:09 sexpbot: Message saved.

23:15 amalloy: brehaut: how interested would you be in a version of findfn that worked like: $findfn (map $ [1 2 3]) [2 3 4] returns inc?

23:16 brehaut: that would be cool

Logging service provided by n01se.net