#clojure log - Jan 28 2011

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

0:16 _mst: Raynes: this might not help at all, but you could try 'A z' or 'A k' from the group buffer. I remember in the dim dark past having groups default to being "zombie" or "killed" and not showing up by default...

2:11 brehaut: is there anyone online who has seen my site and wanted to punch me for the choice of colors?

2:13 zvrba: what is your site?

2:14 brehaut: brehaut.net

2:14 it was eye searingly yellow

2:14 zvrba: was?

2:14 brehaut: yes

2:14 zvrba: i still want to punch you in the face

2:14 WAS?

2:14 it still is!

2:14 it looks like a cartoon commercial for a film from 1950s

2:15 esp. because of heading fonts

2:15 the text contrast is bad, it's hard to read

2:15 orange on yellow... bad combo

2:15 brehaut: ok so you havent got the new version of the css thats for certain

2:16 zvrba: and yellowis shadow around the biggest headings is rather corny

2:17 http://media.brehaut.net/style/wendigo-base.css

2:17 that's the CSS referenced from the page html

2:18 brehaut: you may be surprised to learn that that file is subject to change

2:18 and i get the latest version here

2:23 zvrba: well, this is the first time i loaded this page, so it is not some strange caching problem

2:23 brehaut: well then

2:23 you would have detested the previous version if you think the current version is too yellow

2:23 zvrba: hehe

2:23 it's not "too"yellow. it just looks like a cartoon commercial

4:32 Dranik: hi all!

4:33 is it possible to define several classes in one clojure file using gen-class?

4:34 clgv: would that mean using multiple ns-statements? then it's considered bad style as far as I heard.

4:35 ejackson: yup.

4:35 Dranik: how about the macro (gen-class ) ?

4:36 what's wrong with that code:

4:36 (gen-class

4:36 :name My1

4:37 :methods [[myMethod [] String]])

4:37 (defn -myMethod [this] (println "myMethod called") "")

4:37 (.myMethod (My1.))

4:39 clgv: do you get an error with that?

4:40 Dranik: yep. It can't find My1

4:40 but I don't compile it

4:40 I run it interactively from command-line

4:41 guess, that's the point, it should be compiled...

4:51 ejackson, ok, I see that creating multiple ns-statements in one file is a bad style. But is it technically possible?

4:51 ejackson: I've never tried ;)

4:51 Dranik: :-(

4:54 fliebel: Dranik: Why would you want it?

4:55 Dranik: fliebel, I want to create macros for several architectural patterns

4:55 for now I'm trying to implement Factory

4:57 fliebel: Dranik: Have you tried singleton? :) I thought design patters where not very useful in functional programming.

4:57 clgv: uuuuh sounds a bit far from clojure.

4:57 Dranik: why do you want to do that?

4:58 in clojure you can simply use factory-methods which are nothing special at all: normal functions that return objects ;)

4:58 Dranik: clgv, fliebel, that's not for functional programming. I try use clojure as a meta-language implementing another language on top of it

4:59 I want to use it from java

4:59 I hate writing copy-pasted code for patterns. I want clojure macros which will do all the job

5:07 clgv: Dranik: I don't know if that will work. But you should let us know when you tried and gathered some experience,

5:08 Dranik: clgv, interesting, hugh? :-)

5:23 ejackson: oooh redis-clojure.....

5:24 bobo: oh, is it more updated perhaps?

5:25 it claims to be 1.2.7 but links to ragnard's github where latest is 1.0.4

5:26 or 1.2.4 in the 1.2 branch

5:28 ejackson: yes, I'm looking at the forks now.... I suspect it starts with ghoseb

5:28 dunno though

5:32 TobiasRaeder: morning

5:32 bobo: ejackson: let me know if you get any clarity in it :-) and whats different in 1.2.7

5:33 ejackson: bobo: yeah, I've written a simple thing around jedis for myself, but this looks good.

5:33 morning TobiasRaeder

5:34 TobiasRaeder: anyone tried to do something with clojure + servlet api 3.0 yet?

5:38 bobo: ejackson: does jedis support pubsub? or blocking stuff

5:38 ejackson: bobo: no idea, i'm just using the basics

5:38 but i imagine it does

5:38 bobo: ok, il take a look later then =)

5:45 LauJensen: Morn'

5:46 ejackson: bobo: yup jedis does pubsub

5:46 LauJensen: morning

5:49 bobo: ejackson: awesome

5:52 LauJensen: user=> (project (table :t1) [:id (case :status (>= :wage 500) "High" (< :wage 500) "Low" :else "Weird")]))

5:52 SELECT t1.id,CASE WHEN (wage >= 500) THEN High WHEN (wage < 500) THEN Low ELSE Weird END AS status FROM t1

5:56 TobiasRaeder: @LauJensen morning

5:56 LauJensen: Morning TobiasRaeder

6:52 shortlord: is there a way to get the line number that caused a RunTime Exception? ust .getMessage and .getStacktrace is not very helpful

6:55 or at least print the whole exception inclusive complete stacktrace. .getStacktrace only has one line as output

7:01 clgv: shortlord: (use 'clojure.stacktrace) and (print-stack-trace *e) or more often better choice: (print-stack-trace (.getCause *e))

7:08 edoloughlin: How can I test if something is a map?

7:08 shortlord: clgv: that sounds great, but I need the stacktrace as a string to display it in a processing window. Is there anything comparable to print-stack-trace that returns the string or would I have to rebind *out* or something like that?

7:09 edoloughlin: Sorry, just found map?

7:21 Fossi: shortlord: look at the implementation. should be somewhere in there ;)

7:51 bartj: , (+ 1 1)

7:51 clojurebot: 2

8:10 robonobo: g'day

8:10 clojurebot: clojure-maven-plugin is http://github.com/talios/clojure-maven-plugin

8:11 robonobo: is there a way to kill all threads except for the one i'm one at the repl?

8:51 edw: Ah, yes, hello.

8:51 Wrong window. Again.

9:00 AWizzArd: robonobo: http://download.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html

9:02 robonobo: AWizzArd: what if I don't have the "references" to the thread anymore? I have a bunch of threads started with (future) that run forever in my app, but that I have to restart from time to time during development.

9:02 Another way would be to just restart my slime. Is there a way to do this from emacs?

9:03 tomoj: ,i + sayoo + TAB + RET + start it again

9:03 clojurebot: java.lang.Exception: Unable to resolve symbol: i in this context

9:03 tomoj: :/

9:04 robonobo: tomoj: was that for me?

9:06 AWizzArd: robonobo: You can construct your futures in a way that they check on a var *run* from time to time and quit running if *run* = false.

9:06 raek: robonobo: the Future object that is returned by 'future' can be used to shut the thread down. just keep a reference to each Future object

9:07 if you want to be able to start new threads again, it can be a good idea to give each "generation" of threads an atom that contains a boolean for whether that generation should still run

9:08 thus you avoid the problem when a thread misses the false value if you set *run* to false and then to true again

9:12 robonobo: ok, thanks guys

9:15 raek: you could perhaps let the threads have an outer loop like (future-call (fn [] (do-stuff) (recur)))

9:15 that would let you redefine do-stuff and it the new version will automatically be used

9:19 robonobo: java.lang.ThreadDeath doesn't sound very good

9:20 raek: I also recommend looking into thread interruption. it is a bit more to read, but it is good to know about

9:20 robonobo: raek: i'll do that

9:21 raek: the book "Java Concurrency in Practice" is really good

9:24 robonobo: can anyone search clojuredocs.org? i get a 500 error.

9:25 mrBliss: robonobo: same here

9:25 robonobo: dammit

9:25 chouser: there's find-doc at the REPL

9:26 robonobo: chouser: yeah, i know, but it doesn't have the nice examples and relevant functions, etc

9:28 chouser: yes, but if it's only the search on clojuredocs that's broken... anyway, just making sure you were aware

9:30 robonobo: shutting a future down = cancelling it?

9:36 raek: yes. that was what I meant before. (although, I did not say it)

9:37 cancelling a future causes its executing thread to be interrupted

9:55 robonobo: holy hell the repl knows my name

9:55 "Connected. Robin, this could be the start of a beautiful program."

9:55 tonyl: woow

9:56 ejackson: robonobo: yes, and when you make embarrasing coding errors its emails them to the googlegroup....

9:57 robonobo: all heil the allmighty slime

10:05 edw: Is it normal for a "jar t ..." of a jar made with "lein uberjar" to take, like, forever to run?

10:07 hoeck: edw: yes, the jar tool is horribly slow

10:07 edw: Some O(n^2) stuff going on in there?

10:07 Or maybe O(x^n)...

10:08 hoeck: edw: exactly, they screwed sth. up there

10:09 edw: Thank God Sun didn't just use tar... :/

10:09 hoeck: edw: but unzip -l ueber.jar works too and just as fast as you would expect

10:09 stuartsierra: JAR is actually just ZIP with some extensions.

10:10 ZIP utilities can usually unpack JAR files.

10:11 edw: Right, of course! I should have thought of that. Thankfully jar is still running, so I can take satisfaction in C-c-ing it.

10:12 Boom! Done in less than a second. Jar elapsed time: at least five minutes.

10:14 I put (:gen-class) in my ns form, but the output jar doesn't have a java class for the namespace. Any ideas?

10:16 stuartsierra: edw: you need to explicitly AOT-compile the namespace.

10:17 edw: I did "lein compile; lein uberjar"; should that have worked?

10:17 mefesto: edw: did you specify a :main or :aot in your project.clj?

10:17 raek: edw: you have to explicitly list that namespace in our project.clj

10:17 *your

10:18 mefesto: edw: https://github.com/technomancy/leiningen/blob/stable/sample.project.clj

10:18 edw: Ah, let me look into that. Thanks!

10:19 smnirven: yoohoo

10:21 zoldar: hello, I'm trying to port hiccup to clojure-clr. I've hit a weird build error: http://dpaste.com/362811/ . The source is available here: https://github.com/zoldar/hiccup-clr . What may be the cause of that wrong namespace resolution?

10:27 stuartsierra: zoldar: that kind of error usually indicates a mismatch between the name of the file and the name of the namespace it loads.

10:28 zoldar: that's weird, I've just double checked if there are any typos

10:28 I just put contents of every

10:28 oops

10:28 stuartsierra: It appears to be expecting a namespace "hiccup.form_helpers" with an underscore.

10:29 zoldar: I've just put contents of every file into repl

10:29 and all except one evaluated ok

10:29 stuartsierra: But Clojure will expect "hiccup/form_helpers.clj" to contain "hiccup.form-helpers" with a dash.

10:29 zoldar: it does

10:30 I mean I know

10:30 stuartsierra: Something is trying to find the namespace 'hiccup.form_helpers' with an underscore.

10:30 zoldar: I also get this error for hiccup.core

10:30 stuartsierra: Maybe ClojureCLR is not munging file names correctly?

10:30 zoldar: I suppose

10:31 does the author hang out here any time

10:31 ?

10:31 I mean I rather think that I'm doing something wrong

10:31 or maybe that's some side effect of other issue

10:32 stuartsierra: Sorry, I don't know.

10:38 abedra: stuartsierra, did you get a chance to review CLJ-689?

10:38 stuartsierra: no

10:39 abedra: Now that hudson is doing maven releases we should make sure it gets reviewed and completed

10:39 stuartsierra: ok, added to my TODOs

10:39 abedra: cool

10:39 I'm happy to work with you on it if you would like

10:39 I just want to make sure it gets attention and you have been inside hudson the most recently

10:39 stuartsierra: ok

10:40 abedra: in the middle of stuff right now, I'll ping you later to go over it.

10:41 chouser: We've just invented a convention for our codebase

10:41 memoized version of functions end in a pencil

10:41 so, (defn myfunc✎ (memoize myfunc))

10:41 abedra: stuartsierra, no hurry

10:42 * chouser smiles placidly

10:42 abedra: stuartsierra, there's plenty of things to do :)

10:42 stuartsierra: chouser: how do you type that?

10:42 chouser: CTRL-V

10:42 you don't have a pencil key on your keyboard?

10:43 stuartsierra: I have an old Kinesis with PS/2 plugs.

10:43 abedra: chouser, well the cool kids with the kinesis keyboards do

10:43 chouser: do they really?

10:43 abedra: chouser, damn skippy

10:43 chouser, they even have pencil macros

10:44 edw: Okay, so is `lein uberjar' supposed to take forever once I've included :aot and :main clauses to my project.clj?

10:45 stuartsierra: chouser: you're one of those nuts who redefines fn as the lambda character, aren't you?

10:45 abedra: stuartsierra, be careful now...

10:45 chouser: no, really not. This is my first excursion into unicode-in-my-clj land.

10:46 and I'm inordinately amused

10:46 abedra: :)

10:46 stuartsierra: chouser: all right, but watch out for the slippery slope towards Snowman.

10:46 abedra: stuartsierra, hey i've got snowmen

10:46 stuartsierra, in my git dirty tracking

10:47 stuartsierra: Where's the unicode character for a steaming pile of s***?

10:47 abedra: stuartsierra, it's the eclipse icon

10:48 stuartsierra: ah, of course

10:48 * abedra ducks and covers

10:48 chouser: Ctrl-Shift-U 270e Enter

10:49 abedra: chouser, nice

10:49 it's now a macro on my keyboard

10:49 chouser: ha!

10:49 abedra: 270e

10:49 tonyl: ɰe

10:49 chouser: fail

10:50 abedra: 270e

10:50 chouser: abedra: I think that's a gnome key sequence

10:50 abedra:

10:50 ✎✎✎✎✎✎✎✎✎

10:50 chouser: heh

10:50 abedra: there

10:50 tonyl: ɰ that is the s#$t symbol

10:50 mm

10:51 abedra: chouser yeah gnome isn't all too happy with that

10:52 I want a metal fingers character

10:52 besides the standard \m/

10:55 test: is there a Clojure/Java library which converts three-digit country codes to two-digit country codes ?

10:55 raek: like U+2603 SIGN OF THE HORNS ?

10:55 sritchie: hey all, one quick question -- if I have a function that returns a sequence of arguments (in this case, a vector with x and y coordinates) is there an idiomatic way to pass the contents of that vector in as arguments to another function (rather than the vector itself?

10:55 raek: (fictional)

10:55 test: raek, to me ?

10:55 abedra: raek, exactly!

10:55 stuartsierra: sritchie: apply

10:56 sritchie: ah, got it, that's great

10:56 thanks!

10:57 raek: chouser: I had no idea about that keyboard shortcut. awesome!

10:57 chouser: raek: just learned it myself

10:57 raek:

10:58 $title http://☃.net/

10:58 sexpbot: Page has no title.

11:01 raek: test: no :-) maybe there is something in java.util.Locale http://download.oracle.com/javase/1.4.2/docs/api/java/util/Locale.html

11:01 * raek doesn't know, really

11:02 stuartsierra: test: If it's a direct mapping, you could just copy-and-paste the list into code as a literal map.

11:07 Dranik: I have a macro with a list (a b c) which is bound to some binding lst. how to return a b c from the macro using lst? `~@lst throws an error, and `(~@lst) returns (a b c)

11:08 raek: Dranik: a macro can only expand into one thing. maybe you could expand into a (do ...)?

11:08 stuartsierra: You can't do that without symbol macros, which clojure does not (yet) support.

11:08 edw: join #lein

11:08 D'oh.

11:08 raek: what are symbol macros?

11:08 Dranik: raek, good idea, I'll check it out!

11:09 raek: (assuming a, b and c are only executed for side-effects)

11:09 Dranik: hell no, that doesn't work..... :-(

11:10 edw: Does anyone have lein uberjar invocations that last a very long time? I don't know if it's hung or just doing something very slowly e.g. reaing a jar file.

11:10 qbg: I don't see how symbol macros would help here

11:10 stuartsierra: qbg: you're right, any macro, symbol or othrewise, can only expand to one expression.

11:10 qbg: Dranik: Why do you need such a macro?

11:11 Dranik: qbg, I make my own version of gen-interface on top of the standard gen-interface

11:11 the only difference is that i analyze it's arguments and return two things

11:11 the first one is usual gen-interface

11:12 and the second -- a binding which contains the results of analysiz

11:12 *sorry for spelling

11:12 qbg: Where do you use the results of analysis?

11:13 Dranik: qbg, I'm trying to create a macro for a pattern "decorator"

11:13 so I save the list of methods in some binding

11:13 qbg: So you are using this macro in another macro?

11:13 Dranik: and use this binding when generate decorated class

11:13 nope

11:13 raek: Dranik: I think it's easier to split up macro functionality into functions rather than macros

11:13 Dranik: I use the binding in another class

11:14 raek, may be

11:14 raek: (but I'm not quite sure I understood your problem)

11:14 qbg: Sounds like you want a function

11:15 raek: macros are just the icing...

11:18 edw: Dranik: It's a bit of a cliche, but patterns are considered an adaptation to the brain-damaged nature of OOP by Lisp types. How hard is it to just define a procedure that just calls a procedure, doing something to the input or output?

11:19 Dranik: edw, yep, you're right

11:19 clgv: edw: lol I wouldn't let that stand as definition for patterns in general ;)

11:19 Dranik: edw, what I'm doing -- is practicing. I'm just having fun.

11:20 edw: Dranik: Okay; I've done that sort of thing just for fun.

11:20 clgv: I agree with you, but it's not a bad 1st order approximation of a definition.

11:25 sritchie: hey all -- is there a clean way to multiply all elements in a sequence by a factor, other than (map #(* factor %) my-seq)

11:25 qbg: (map (partial * factor) my-seq) ;)

11:26 More seriously, what is wrong with the map approach?

11:26 sritchie: oh, nothing, I was just wondering if there was a "scale" function or something

11:27 pdk: failing map you could do a for loop

11:27 qbg: Not built in

11:27 pdk: Yeah, for would be nice too

11:28 sritchie: I'm working for a group that formerly used a mess of python code -- the conversion to clojure is going to be something like 10% of the lines, and I'm becoming addicted to cutting lines

11:28 qbg: &(for [x (range 10)] (* x 3))

11:28 sexpbot: ⟹ (0 3 6 9 12 15 18 21 24 27)

11:29 sritchie: that's cleaner, I think

11:30 qbg: It makes it harder to use with ->, ->> though

11:30 sritchie: (defn scale[seq fact]

11:30 (for [x seq] (* x fact)))

11:30 qbg: haven't seen those forms yet, I'll check out the docs now

11:31 tomoj: should probably be [fact seq] ?

11:32 sritchie: tomoj: yup, that looks better

11:33 tomoj: for ->> compat

11:33 (->> (range) (take 10) (scale 0.5))

11:34 it makes me happy that python->clojure is losing you a lot of code

11:35 sritchie: tomoj: it's an application to run a pretty involved analysis NASA MODIS tiles -- I'm switching us over to clojure and cascalog, so the process can run on Hadoop

11:36 hadoop's data shuffling sheds quite a bit of code, but clojure is doing its part

11:36 pdk: i recall reading the docstrings for -> and ->>

11:36 tomoj: so are you developing hive queries?

11:36 pdk: going "wtf do these even do"

11:36 then i saw a code example and went OHHHHH

11:36 tomoj: better question: are you using stuartsierra's clojure-hadoop?

11:37 ejackson: pdk: you and me both.

11:37 ohpauleez: sritchie: Any reason why you just didn't use Hadoop Streaming and keep the current codebase?

11:37 wolverian: on our clojure course we're not even recommending reading docstrings since they're pretty much completely unusable for learning. might work as a reference.

11:37 ohpauleez: wolverian: Really? I think they're pretty good

11:37 sritchie: ohpauleez: the code base was in need of some serious, serious cleanup -- each step has to be triggered manually

11:38 ohpauleez: ahh

11:38 cool! sounds like a fun project

11:38 edw: wolverian: I learned `sed' from the manpage. I know what you mean about docstrings...

11:38 sritchie: ohpauleez: so, the options were, revamp the python code, or go to clojure!

11:38 tomoj: not using clojure-hadoop, though it looked great -- cascalog is a layer on top of cascading

11:38 ejackson: and you told the serpent to GTFO !

11:39 wolverian: ohpauleez: some people will be able to learn from them, but mostly they're written for people who already understand most of the concepts of clojure. learning a new language and a new idiom is ... different.

11:39 sritchie: so, essentially hive queries

11:39 http://bit.ly/9ATc7B

11:39 ohpauleez: haha, if you're job entails having to pick between (or work in) Clojure and Python, you have yourself a pretty sweet job

11:39 haha

11:39 edw: Okay this is odd, `lein uberjar' hangs but interactively, the uberjar command works fine. WTF?

11:40 sritchie: ohpauleez: I'm being careful not to ruin it! My side job is iPhone stuff in objective C, where the thought / typing ratio is inverse to clojure's

11:47 chouser: what does it mean when proxy says "Incompatible return types"?

11:49 ohpauleez: sritchie: I don't mind obj-c, I kind of like it, but I've never used it to dev OSX stuff, only used GNUStep and C-libs

11:50 sritchie: ohpauleez: I actually do like coding in it -- it's just that it can be quite verbose. I notice that I type quite a bit more to realize an idea -- in clojure,I find myself sitting for ten minutes, then writing down a short function that does the job

11:51 ohpauleez: I'm partial to the second way, I suppose, but objective-C's really not bad

11:51 ohpauleez: for sure. Clojure has total zen appeal

11:51 I am as well

11:52 dnolen: sritchie: I like Objective-C as well. XCode makes typing it out fairly pleasant. The only thing that drives me *insane* is not literal support for NSDictionary NSArray

11:52 s/not/no

11:52 sexpbot: <dnolen> sritchie: I like Objective-C as well. XCode makes typing it out fairly pleasant. The only thing that drives me *insane* is no literal support for NSDictionary NSArray

11:53 sritchie: yeah! I needed to do a set operation for a piece of code that clustered points on a map, and had to break out NSMutableSets

11:54 felt like a heavy datastructure for the operation involved, but of course that's just because sets aren't primitive

11:56 btw, what's the difference between -> and ->>?

11:56 I'm having real trouble googling the second, and the doc strings are the same

11:56 ohpauleez: sritchie: One dumps the result as the first arg, the other dumps it as the tail arg

11:56 Dranik: why aren't macros arguments evaluated? I've looked into the macros source, it is just a function

11:57 (defdefmacro (fn [&form &env name & args] ...

11:57 (def defmacro (fn [&form &env name & args] ...

11:57 chouser: Dranik: do you mean "why is it designed that way" or "by what mechanism are the differentiated"?

11:57 Dranik: the second

11:57 sritchie: ohpauleez: got it

11:58 chouser: Dranik: The metadata of the var

11:58 ,(:macro (meta #'defn))

11:58 clojurebot: true

11:58 Dranik: chouser, could you explain a bit more?

11:58 chouser: ,(:macro (meta #'filter))

11:58 clojurebot: nil

11:58 ohpauleez: sritchie: Cool, if you need some examples ping me. Also, Clojure Docs usually has good examples: http://clojuredocs.org/quickref/Clojure%20Core

11:59 chouser: Dranik: does that make sense?

11:59 Dranik: chouser, well, I'm near to it :-)

11:59 chouser, what metadata should I set in order not to evaluate the function arguments?

12:00 chouser: Dranik: you should define a macro instead of a function

12:00 sritchie: ohpauleez: this looks really good! What's trying to do is shorten up the function here: https://gist.github.com/2a15289d7bf3b2e64f49

12:01 Dranik: chouser, I see. But I dig into the defmacro source and see a pure function

12:01 how is it done that way?

12:01 sritchie: just as practice. It feels like there's a pattern here... I want to write (map -> dist [(+ ul-x) (- ul-y)]), or something like that, but one can't map a macro

12:01 qbg: Dranik: Macros are functions at their core

12:02 sritchie: ohpauleez: also, not very clear!

12:02 ohpauleez: sritchie: Yeah, threading is really only used when it helps readability

12:02 Dranik: qbg, yeah, I know, because I look in the source of defmacro. What I can't get is how that function is implemented that it does not evaluate its arguments

12:02 chouser: Dranik: When Clojure is compiling your code and it sees (foo ...), it finds the var foo, checks to see if it's metadata claims it's a macro, and if so calls the function *right then*, with undocumented arguments that are subject to change.

12:03 qbg: &(meta #'for)

12:03 sexpbot: ⟹ {:macro true, :ns #<Namespace clojure.core>, :name for, :file "clojure/core.clj", :line 3582, :arglists ([seq-exprs body-expr]), :added "1.0", :doc "List comprehension. Takes a vector of one or more\n binding-form/collection-expr pairs, each followed by zero or mor... http://gist.github.com/800556

12:03 qbg: See the :macro true part?

12:03 That is how

12:03 Dranik: :-)

12:03 qbg: You should define your macros with defmacro though

12:04 Dranik: qbg, ok, then where is the definition of that meta :macro true in the source of defmacro?

12:04 qbg: Check out the .setMacro call after the definition defmacro

12:05 Dranik: qbg, I got it, thanks!

12:06 qbg: sritchie: (map + dist [ul-x (- ul-y)])

12:07 sritchie: qbg: oh, great

12:09 AWizzArd: I have (defmacro foo ([a] (foo a 2 3)) ([a b] (foo a b 3)) ([a b c] `(+ ~a ~b ~c)))

12:09 Why do the calls (foo 10) and (foo 10 20) lead to a stack overflow?

12:09 (foo 10 20 30) works nicely.

12:10 qbg: Quote the output!

12:10 ohpauleez: yeah

12:10 nice catch

12:11 AWizzArd: I am aware how to fix it. I just would think that the version I just pasted here should work too.

12:12 (defn bar ([a] (foo a 2 3)) ([a b] (foo a b 3)) ([a b c] (+ a b c))) also works fine.

12:12 uuhm, replace the 'foo's with 'bar's.

12:13 qbg: I can imagine a macro calling itself going bad

12:13 Dranik: is it possible to add private properties to a class generated by the gen-class facility?

12:13 pdk: uh

12:13 wouldn't -> and ->> be defined recursively for example

12:13 qbg: pdk: They don't call themselves from their definition though

12:13 AWizzArd: Well, a macro can call itself in its expansion.

12:14 qbg: They are used in the expansion, not the definition

12:14 AWizzArd: But it seems it can't do that outside of the expansion, during the "outer macroexpansion time".

12:14 qbg: To be able to compile itself, it needs to compile itself first...

12:17 sritchie: qbg: actually, that almost works -- the weird part of mine was that I need (- ul-y (second dist))

12:17 qbg: so, the ul-y has to be positive, and - has to be applied to it

12:18 qbg: Your gist must be wrong then

12:18 ohpauleez: sritchie: If you find yourself needing positional pieces of a seq a lot, consider making heavy use of destructuring in your let blocks

12:19 qbg: No..

12:19 ohpauleez: let forms*

12:19 sritchie: qbg: yeah, you're right, the gist with threading is wrong

12:19 qbg: Yeah, you wanted ->>

12:20 Complete overkill: (map #(%1 %2 %3) [+ -] [ul-x ul-y] dist)

12:21 sritchie: overkill, but that's what I'm trying to do! it's sort of silly for an example this small

12:23 mapping the threading macro would get it done, but that's not possible

12:24 qbg: Unless you wanted to do it at compile time

12:26 You could write an anonymous macro macro, but that would be extreme overkill

12:28 sritchie: qbg: I'll think more about what the function is doing, I think -- I have an upper left point, and I to get the coordinates in a coordinate system that moves right in x, down in y

12:28 qbg: I think the answer is to write another function that makes that clear

12:29 I get my ul-x and ul-y by doing the same thing that I do in the body of the function

12:59 mefesto: clojuredocs down?

13:01 sritchie: qbg: I ended up using your overkill solution -- I defined that anonymous function as "distance", with args [dir start magnitude]

13:01 qbg: so now it's clear what the map is doing

13:01 tonyl: mefesto: not for me

13:01 sritchie: here's the final code :

13:01 https://gist.github.com/799942

13:01 mefesto: tonyl: searching fails for me

13:02 tonyl: mefesto: it seems that the search functionality is not functioning

13:05 chouser: maybe because it's not functional

13:07 hiredman: should have used a monad, then it would certainly be functional

13:13 mattmitchell: how can i save the name of a function as a string/keyword in a var, then call it later?

13:13 eval works, but well... that doesn't seem right

13:14 mefesto: mattmitchell: resolve ?

13:14 ,(resolve 'clojure.core/inc)

13:14 clojurebot: #'clojure.core/inc

13:14 mefesto: ,((resolve 'clojure.core/inc) 5)

13:14 clojurebot: 6

13:14 mattmitchell: mefesto: ok cool, so then how can i execute it?

13:15 semperos: functions are first-class citizens

13:15 why can't you just pass the function itself?

13:15 mattmitchell: semperos: well because there are a number of different things i want to do based on the name

13:15 mefesto: mattmitchell: i believe that a var in function position of a form will execute

13:26 does c.c.command-line/with-command-line now allow overriding -h? it seems to always trigger the help output

13:29 chouser: mefesto: hasn't it always?

13:30 mefesto: chouser: dunno this is my first time using it. i have an entry for [host h "Hostname" "localhost"] and was hope that would override -h

13:30 chouser: just curious, i can use --host no problem

13:31 chouser: ah

13:31 raek: mattmitchell: if you want the function itself, you can deref/@ the var. though, as mefesto said, using a var as a function will invoke what's in it

13:31 chouser: I don't see a way after a quick glance. Yet another example of my only-slightly-better-than-nothing contributions to contrib.

13:32 mefesto: chouser: c.c.command-line is a great contrib! :)

13:33 i can tell it'll be very handy for some of the things i currently have on my plate

13:42 chouser: mefesto: well, that's nice, thanks. :-)

13:43 mefesto: chouser: is there a way to force a print-help? for example, if a user doesn't provide one or more file names i'd like to print an error plus the usage.

13:46 AWizzArd: Is there a way as in CL to find out that a file/ns is in the process of being loaded, but not compiled?

13:47 I would like to build a closure that sets newline to (java.lang.System/getProperty "line.separator") while a module is being loaded.

13:48 I could do (let [newline (java.lang.System/getProperty "line.separator")] (defn foo ...)) but think this would put MY line.separator into an ATOed .jar

13:48 This could be \r\n for Win, but I would like foos newline to be \n on Linux

13:48 But without having to look it up every time.

13:49 mefesto: what's the clojure way to print to the error stream? (.println System/err "...") or is there something like (println *err* "...")?

13:54 AWizzArd: Best would be: (eval-when :load (defconstant nl (java.lang.System/getProperty "line.separator")))

14:00 raek: hrm, my combination of having lein in ~/.bin/, using emacs-starter-kit and durendal

14:01 ...somehow causes emacs to not be able to launch "lein swank"

14:05 technomancy: raek: there's a bug in OS X where $PATH settings in .profile are not picked up by GUI apps; could be that

14:05 raek: I'm running ubuntu

14:06 ldh: technomancy: they acknowledge that as a bug? ;)

14:06 raek: in the C-x m shell, lein does not work, but in the C-x M-m shell it does

14:06 technomancy: ldh: no, but that doesn't mean it's not a bug

14:06 ldh: technomancy: agreed

14:08 edw: ldh: Isn't there a way to create a properties file that contains PATH elements that get added at login in OS X? I once went to the trouble of doing that, and it solved that problem.

14:08 technomancy: you have to create an XML file, which is a solution I can't recommend in good conscience

14:09 (mostly for DRY violations)

14:09 edw: You *can* use the plist editing app, if you don't want to get too much blood on your hands.

14:09 ldh: edw: the way which works for me is to add them to /etc/launchd.conf, but you're still repeating yourself

14:10 edw: Well ldh, we're talking about .bashrc vs .profile vs .login. There's a pre-existing problem...

14:28 chouser: stuartsierra: is there a way to get lazytest:watch to load files with *warn-on-reflection* on?

14:29 stuartsierra: hmm

14:29 not that I can think of

14:29 chouser: hm, ok.

14:29 stuartsierra: You can set! it in a source file, temporarily.

14:29 chouser: there's no root binding established

14:30 stuartsierra: alter-var-root, maybe?

14:30 chouser: ah, maybe.

14:33 stuartsierra: yep, that did it, thanks.

14:34 stuartsierra: welcome

14:34 raek: technomancy: robert.hooke question: what happens if I reevaluate an add-hook expression?

14:34 I see in the code that there is an add-unless-present function

14:35 if I reevaluate the hook function too, will it think it's a distinct one?

14:36 technomancy: raek: you can pass a var in if you need to preserve equality across recompiles

14:36 I think

14:39 raek: technomancy: ok, thank

14:39 s

14:39 technomancy: lemme know if that doesn't work

14:39 else you can just put a conditional remove-hook before the redefinition, but that's sorta lame

14:40 stuartsierra: abedra: ping

14:40 technomancy: it's a great way to get around defmulti defonce-annoyance though

14:40 raek: I found an interesting usage of robert.hooke

14:40 technomancy: (def mymulti nil) (defmulti mymulti [...]) ;; and magically it's no longer annoying

14:40 raek: I have a namespace that defines operations on data stored as maps

14:41 it includes an "adorn" function that by default does nothing

14:41 other namespaces can hook that function to add their own keys to the map when that function is called

14:42 technomancy: hrm; why not just an atom of fns?

14:42 raek: basically, I use this as an alternative to memoize

14:42 stuartsierra: fogus: ping

14:42 raek: other namespaces can tell what data they will need later

14:43 technomancy: raek: oh, I see; so it's important the hook args get passed all the way through.

14:43 I thought it was just for side-effects

14:43 cool

14:43 raek: I use it to "compile" lists of points into java Path2D objects

14:45 the graphics code can add its bookkeeping data in the datastructure itself, and the first namespace does not need no know any details

14:45 technomancy: composable.

14:46 raek: (I'm coding a clone of the board game "Carcassonne")

14:46 technomancy: oh, fun.

14:48 raek: maybe I should call this approach the "Christmas Tree Pattern" - you have a map and let other namespaces adorn it with whatever data they need

14:49 (namespace qualified keywords suddenly become very handy)

14:50 edw: Is there a way to get lein to be a little more verbose? I have a `lein compile' that's taking forever and I'd like to see what's going on.

14:51 stuartsierra: meow

14:51 wrong window

14:54 tonyl: lol

14:56 Raynes: stuartsierra: That's horrifying. Should I ask what window that belonged to?

14:57 brehaut: morning

14:59 fliebel: raek: I'm very curious to see your game. my curiosity is aimed at the code, playing is of secundair importance. Is it plain java 2d?

15:00 raek: yes

15:00 https://github.com/raek/thiudinassus

15:00 my friend and I have just got started with it

15:02 fliebel: raek: cool, I found it on your web days ago, but without the link.

15:02 raek: fliebel: more readable form: http://raek.se/thiudinassus.html

15:02 fliebel: I see squares...

15:03 raek: that's gothic.

15:04 fliebel: what is the robert/hooke for, you wher talking bout earier?

15:04 raek: it's used for thiudinassus.tile/adorn-tile

15:04 and for thiudinassus.graphics/adorn-tile

15:04 fliebel: (sorry, typing with one hand because cat ocupies chair.

15:04 raek: it's not on github yet

15:04 fliebel: okay

15:05 raek: the html you see is fresh from my working directory

15:05 fliebel: cool, thanks, i'll keep an eye onit :)|

15:25 Raynes: cemerick: hi

15:26 cemerick: Raynes: hello :-)

15:56 AWizzArd: Anyone here with a very recent Clojure?

15:57 I found something in 1.2 that looks like a bug and would like to know if 1.3alpha still has this and if it is a bug :)

15:57 chouser: oh, I have 1.3alpha3 or so

15:57 AWizzArd: good

15:58 chouser: gotta go in a couple minutes though

15:58 AWizzArd: chouser: it is a very small example, 5 lines or so

15:59 chouser: first start with an atom (def my-atom (atom nil)). Now add a closure (let [lalala 1] (defn foo [a b c] (println a b c))) which does not access the value it closes over. Then please add the macro (defmacro bar [x y z] `(~(deref my-atom) ~x ~y ~z))

16:00 If you now (bar 10 20 30) it will most likely print them out. Should work as expected.

16:00 Can you confirm that so far?

16:00 ooh, I forgot one step: (reset! my-atom foo)

16:00 before calling bar

16:00 chouser: CompilerException java.lang.IllegalArgumentException: Can't call nil

16:00 ah

16:01 yes, works.

16:01 AWizzArd: chouser: now please update your closure to access its val: (let [lalala 1] (defn foo [a b c] (println a b c lalala))). Then again (reset! my-atom foo)

16:01 And now please call (bar 10 20 30) again. I would expect it to print 10 20 30 1. But in my Clojure it fails.

16:02 "No matching ctor found for class [...]"

16:02 chouser: prints 10 20 30 here

16:02 AWizzArd: did you (reset! my-atom foo)

16:02 So that my-atom will see the new version?

16:03 chouser: oh, no.

16:03 IllegalArgumentException No matching ctor found for class user$eval69$foo__70 clojure.lang.Reflector.invokeConstructor

16:03 AWizzArd: yes, same here

16:03 I tend to say this is a bug. But perhaps it is a feature? ;)

16:04 tonyl: I don't think let is meant to make a closure over a def/defn

16:04 I can't remember well, but I might be wrong

16:04 chouser: AWizzArd: interesting -- I'll have to ponder this another time. gotta go.

16:04 AWizzArd: tonyl: that is what closures are for

16:04 chouser: thanks for confirming it

16:05 raek: I guess you could as well write it as (def foo (let [lalala 1] (fn foo [a b c] (println a b c lalala))))

16:05 tonyl: ^

16:06 AWizzArd: tonyl: it allows to add static final fields with fastest possible access

16:06 raek: but I don't think there's any difference

16:06 tonyl: raek: you beat me to the example

16:06 oh then it is something else then

16:06 AWizzArd: raek: this also throws the same exception

16:06 * tonyl mmmm

16:06 AWizzArd: closures are the equivalent to objects in the world of functional programming

16:07 tonyl: close enough comparison

16:07 AWizzArd: Although I mainly used this as a replacement for the non-existing defconstant

16:08 hiredman: ping

16:08 hiredman: hmm?

16:09 AWizzArd: (defn foo [a] (let [x (SimpleDateFormat. "yyyy-mm-dd HH:mm:ss")] <body>)) <-- will the compiler optimize this?

16:09 So that not in each invokation of foo a fresh SimpleDateFormat is created?

16:09 hiredman: no

16:10 AWizzArd: Is there any way to have this object instantiated once as a constant, without the need for lookups other than with a closure?

16:10 hiredman: def it, but date formats are not thread safe

16:10 AWizzArd: (let [x (SimpleDateFormat. "yyyy-mm-dd HH:mm:ss")] (defn foo [a] body)) <-- here x is a static field and known to be final.

16:11 hiredman: that doesn't deal with non-thread-safeness

16:11 AWizzArd: A defed var also requires a lookup.

16:11 Thread safety is in my case no problem.

16:14 dnolen: AWizzArd: in 1.3.0 the vars are no longer default to dynamic, so is this really an issue anymore?

16:14 AWizzArd: dnolen: The "problem" is: you can do: (def x 1) ... (def x 2)

16:14 Clojure must not assume that x is constant.

16:15 So it needs at least some kind of indirection, some lookup.

16:15 It may be faster for 1.3 when dynamics are gone by default. But still needs some lookup.

16:16 mattmitchell: would someone mind taking a look at this macro? i'm attempting to learn how they work, but not getting past this: https://gist.github.com/800959

16:16 line 2, attempting to use a keyword for defn

16:17 bartj_: how can I access enums in Clojure

16:17 I tried:

16:17 AWizzArd: bartj_: enumeration-seq

16:18 bartj_: (enum-name/option) without success

16:18 AWizzArd: dnolen: something like (defconstant sym val) could be nice. It would create a final static field to access the val.

16:19 raek: AWizzArd: what class would that field belong to?

16:20 AWizzArd: raek: NS maybe

16:20 mrBliss: Just generated a random string with java.security.SecureRandom: "pdickava". Almost dick and java in the same random string ;-)

16:20 raek: mattmitchell: (defmacro solr-doc [type args] `(defn ~(symbol (name type)) [~args] (prn "test")))

16:21 AWizzArd: raek: and one really could not change the name without full recompilation

16:22 bartj_: for eg: http://www.google.com/codesearch/p?hl=en#5xpftBF0e98/trunk/java/src/com/google/i18n/phonenumbers/PhoneNumberUtil.java&q=INTERNATIONAL%20package:http://libphonenumber%5C.googlecode%5C.com&sa=N&cd=3&ct=rc

16:22 raek: AWizzArd: iirc, classes for namespaces are only emitted when doing AOT.

16:22 bartj_: has an enumeration on line 304

16:23 raek: (please correct me if I'm wrong)

16:23 AWizzArd: raek: I don't know enough about the internals of the JVM. There might be a way to implement defconstants.

16:23 mattmitchell: raek: ok i get it. thank you.

16:23 AWizzArd: raek: but perhaps the bug I mentioned above can simply be fixed :)

16:25 raek: ,java.util.concurrent.TimeUnit/SECONDS

16:25 clojurebot: #< SECONDS>

16:25 raek: bartj_: ^

16:25 enum values are stored in static fields, iirc

16:25 bartj_: oh!

16:27 raek: They're a bit strange, since they're an invention of Java and are regular classes in the JVM.

16:27 hrm, maybe they had a special attribute in the class definition too.

16:28 bartj_: raek: if you could look at the example URL

16:28 I am trying to access the PhoneNumberFormat enum as follows:

16:28 PhoneNumberUtil/PhoneNumberFormat

16:28 without success

16:29 raek: ah, is it a nested class?

16:29 (an enum type defined inside another class, in this case)

16:30 bartj_: from what I can see, there is only one class?

16:30 PhoneNumberUtil

16:30 raek: com.google.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat/INTERNATIONAL

16:30 bartj_: may I ask why the $ ?

16:30 Raynes: Inner class.

16:31 raek: it is the way the JVM names inner classes

16:31 bartj_: forgive my ignorance, but enums are classes ?

16:31 raek: yes... :)

16:32 bartj_: arggh, Java!

16:32 raek: Java and backwards compability

16:32 pdk: maps with keyword symbols as keys

16:32 feels good man

16:32 bartj_: thanks a lot

16:33 raek: np

16:33 also, import-static in contrib could be worth checking out

16:43 bartj_: raek: thanks for the tip on import-static; no more XL size variable names

16:57 stuartsierra: import-static is kind of a hack.

18:04 lazy1: clojurebot: help

18:04 clojurebot: http://www.khanacademy.org/

18:04 lazy1: :) Forgot about that

19:50 bdesham: hi all... is there a defmulti- that acts like defn- to make a non-public multimethod?

20:00 tonyl: not as far as i know, but why would you want a non-public multimethod

20:08 chouser: bdesham: you can make any var private by setting :private in it's metadata to true

20:08 bdesham: chouser: ok, thanks

20:09 tonyl: I was under the impression that if I'm writing e.g. a library, I should make all of the "utility functions" private... is that right?

20:11 tonyl: bdesham: I guess, I just never do. trying to keep everything open. It makes me think a lot if my function to be of general use

20:11 I didn't know about manually making private vars though, good to know.

20:12 bdesham: tonyl: ok, gotcha

20:16 I'm writing a small library that others might find useful... any examples of other libraries I should look at to see how to package it, etc.? (I'm more or less a Clojure newbie)

20:17 lazy1: bdesham: You can take https://github.com/weavejester/hiccup for example (1'st that came to mind)

20:18 bdesham: lazy1: that looks like it'll work, thanks

20:19 lazy1: I think it's a pretty standard structure. For packaging - I think http://clojars.org/ is the widely used method

20:19 And think about your namespace, I got burned with fs :)

20:20 Raynes: lazy1: https://github.com/Raynes/fs-revolution

20:20 lazy1: Miki is annoying. :p

20:21 Note that that fork is mostly a joke. Not sure I actually want to maintain that.

20:21 bdesham: lazy1: heh, ok thanks :-)

20:32 lazy1: Raynes: I'm honored :)

20:35 Raynes: BTW - http://www.catb.org/~esr/writings/anarchist.html was some inspiration

20:35 Raynes: :)

20:37 lazy1: Seriously though, it's totally a joke and I intend to update the README to reflect that. I took a chance on this one, knowing I'd come off as a huge asshole. :p

20:38 I got to try out the git-hg plugin in the process. Works fairly well.

20:39 lazy1: Don't worry, I like the joke

20:40 You might even switch to hg before you know it

20:40 GTG, TTYL

20:41 Raynes: I might decide to write code in COBOL as well. Highly unlikely.

21:33 brehaut: is there a method to test if something is an isntance of a class?

21:33 s/method/function/

21:33 sexpbot: <brehaut> is there a function to test if something is an isntance of a class?

21:34 tonyl: &(doc instance?)

21:34 sexpbot: ⟹ "([c x]); Evaluates x and tests if it is an instance of the class c. Returns true or false"

21:35 brehaut: tonyl: thanks

21:46 qbg: I just realized that being able to do (extend-type nil ...) means that you don't need the Null Object pattern...

22:06 dnolen: qbg: yeah there are two useful things with protocols which I didn't understand until recently. Extending nil, and extending Object to provide default implementation.

22:07 qbg: I mention this because some students next to me in a software development class have to implement a BST in Java; it is so much better in Clojure...

22:42 hiredman: AWizzArd: I don't know if you are aware of the change in 1.3 to assume that vars are not dynamic unless declared to be

22:43 it apparently makes vars much cheaper

22:43 since unless the var is declared to be dynamic you don't have to pay the price of checking to see if the var is rebound

22:45 if I recall, at the conj, rich said something like "I've never seen hotspot inline away the dynamic lookup check" but with non-dynamic vars hotspot will inline var lookups apparently

23:55 semperos: I've never done database connections with Java, I see that I'm supposed to put the driver on my classpath; I know Leiningen automatically puts stuff in its default folders on the class path

23:56 but do folks just put it somewhere globally? if so, any convention?

23:56 mefesto: semperos: which database are you working with?

23:56 semperos: just learning with mysql

23:57 going to play around with clojureql abit

23:57 mefesto: i been wanting to play with that as well :)

23:57 what do you mean 'globally'?

23:57 semperos: I imagine folks use the mysql driver for more than one project

23:57 and Leiningen cleans out lib for certain actions

23:58 wasn't sure where folks stuck it, or if they just copy it into the lib of each project they need it for

23:58 * semperos doesn't have any real Java packaging or dependency experience, but has survived thus far

23:58 mefesto: yeah but it uses maven's dependency management so it'll get cached in your $HOME/.m2/repository automatically

23:58 semperos: ah

23:59 I was approaching it manually

23:59 so this would be the Leiningen directive: [mysql/mysql-connector-java "5.1.6"]

23:59 ?

23:59 mefesto: so just declare the dependency in your project.clj and it'll download just the first time ... afterwards other projects will just copy it from your local repo

23:59 semperos: yeah, I use Leiningen

23:59 mefesto: yeah, looks like 5.1.14 is the latest

23:59 semperos: didn't think about the database connector being available that way, but as it's a jar, it makes perfect sense

23:59 mefesto: at least the latest in the maven repo

23:59 semperos: right

23:59 that's one thing I've noticed, as I've started using more Java libs

Logging service provided by n01se.net