#clojure log - Aug 27 2010

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

0:00 technomancy: fielcabral: best bet is to use elpa

0:00 fielcabral: OK. Thanks!

0:00 technomancy: it may work from trunk, but not many people do that, so breakage there takes a while to get fixed.

0:18 eshira: hi, i'm trying to run a jar file that I made using "lein jar" I do: ava -classpath /Users/eshira/.clojure/clojure-contrib.jar:/Users/eshira/.clojure/clojure.jar -jar cljservice-1.0.0-SNAPSHOT.jar but I still get Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/IFn

0:18 Caused by: java.lang.ClassNotFoundException: clojure.lang.IFn.

0:18 any ideas?

0:19 hiredman: you can't use -cp or -classpath with -jar

0:20 eshira: really, huh... oh java

0:22 ok, so I set up my classpath such that "echo $CLASSPATH" prints out:

0:22 :/Users/eshira/.clojure/clojure.jar:/Users/eshira/.clojure/clojure-contrib.jar. But "java -jar lein-compiled.jar" still gives me the error

0:23 hiredman: CLASSPATH is ignored if you specify -cp -classpath or -jar

0:24 technomancy: the java command-line launcher is really terrible

0:24 eshira: of course, that makes sense of course

0:24 so my goal is to develop compojure apps faster w/o having to "lein uberjar" all the time

0:25 technomancy: it's pretty clear being able to launch CLI java was added as an afterthought in the 90s when everyone assumed java was all about running in web browsers, then nobody bothered to fix it once applets fell flat on their face.

0:27 tomoj: eshira: don't you have a repl open while you're developing?

0:30 eshira: tomoj: yes. I guess I'll just do a :reload

0:31 i'm just used to the rails (and others) auto-reload when in dev mode

0:31 tomoj: hmm

0:31 what dev environment do you use?

0:32 eshira: right now, I do a "lein repl". I use vim as my editor.

0:32 tomoj: ah

0:33 maybe vimclojure would help

0:33 if you have an editor that has decent support for clojure, you can just start the server in the repl there and reload function definitions or entire files in the editor

0:36 eshira: i have vimclojure set up, but it breaks when i'm using lein

0:37 swhat do you mean by reloading? b/c when I run "(run-jetty {..} ...)", it blocks the REPL.

0:40 dnolen: eshira: you can start jetty w/o blocking the REPL

0:41 eshira: how would I do that?

0:42 dnolen: eshira: in the options map to run-jetty, :join? false

0:43 eshira: but as tomoj said with a decent environment (Enclojure, Emacs, VimClojure) you can just send new definitions to the REPL.

0:43 eshira: but if you don't want to do that, Ring has a cool feature where you can automagically reload specific namespaces when you refresh your browser

0:44 technomancy: (future (run-jetty [...])) ;; is another option

1:01 eshira: thanks

1:46 bortreb: I think I found a bug

1:46 let's say I define a function for making a sphere like so:

1:47 (defn sphere [& {r :radius [x y z] :position :or {r 10 position [0 0 0]}}] (println x))

1:47 now, when I call (sphere) , nil is printed, but it should be 0

1:48 hiredman: no

1:48 position is [0 0 0] and x is nil

1:49 bortreb: ah

1:49 I see

1:49 I thought it somehow called itself again with the new map but that doesn't make sense after all

1:49 thanks, hiredman

2:30 LauJensen: Good morning all

2:37 old_sound: good afternoon!

2:38 LauJensen: ,UGT

2:38 clojurebot: java.lang.Exception: Unable to resolve symbol: UGT in this context

2:38 LauJensen: :)

2:38 technomancy: UGT is broken

2:39 hiredman: clojurebot: please show us that ugt is not broken

2:39 clojurebot: Ack. Ack.

2:39 hiredman: ugh

2:39 clojurebot: please show us that ugt \is not broken

2:39 clojurebot: x \is y is z

2:39 hiredman: stupid bot

2:40 clojurebot: ugt now!

2:40 clojurebot: ugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html

2:40 LauJensen: hiredman: I meant that the concept was broken :)

2:41 old_sound: my local time, is useless now?

2:43 LauJensen: old_sound: it depends. technomancy suggested that we go with UGT, but to each his own

2:43 I though it was a good idea, because of the very repetitive "Good morning, Good evening, Hi its afternoon here, oh where are you from?" etc etc

2:49 old_sound: ok, good morning then

2:57 LauJensen: hehe, sorry I hope I didn't kill the mood old_sound :)

2:57 old_sound: np

2:58 the rules, abide them we must! :P

2:58 LauJensen: Alright, in that case I have a few suggestions more :)

2:58 old_sound: hoho

2:59 "suggestions

2:59 "

3:03 incandenza: 44

3:25 bartj: how do I avoid a reflection warning for this:

3:25 (.get hash "key")

3:25 (.get ^HashMap hash "key") doesn't seem to work

3:25 or even (.get ^java.util.HashMap hash "key")

3:27 LauJensen: (.get ^java.util.HashMap hash ^String "key") ?

3:31 bartj: LauJensen, that did it! thanks.

3:31 LauJensen: np, bartj What did the reflection warning say ?

3:32 bartj: gah, I actually gave #^java.util.HashMap

3:33 I am sorry I gave: ^#java.util.HashMap

3:33 LauJensen: k

3:34 bartj: and it gave: No dispatch macro for: j

3:34 java.lang.ClassNotFoundException: ava.util.HashMap

3:34 I tend to use ^ here but not in my code for some strange reason sometimes

3:34 may I ask why was #^ replaced with ^

3:35 or deprecated rather

3:35 it sure does remove the confusion as to which is first - either ^ or #

3:35 but, is there any other reason ?

3:35 LauJensen: bartj: Yes I think #^ was needed for something else, but it slipped my mind

3:36 When you get a CNF exception, its typically a typo or an unqualified name

3:36 And I dont think you need the string hint, in which case it shouldn't be there

3:37 bartj: LauJensen, thank you for the tips

3:37 LauJensen: np

3:49 spariev: hi, can't figure out this reflection warning - http://gist.github.com/553005

3:50 oh, nevermind, problem solved with typehint on parameter

3:51 LauJensen: which parameter?

3:51 Bahman: Hi all!

3:52 spariev: LauJensen: parameter to the whole fn, I've updated the gist

3:52 LauJensen: ah right, otherwise you missed the 'or'

3:53 Badabing, Bada-bahman!

3:54 spariev: It's amazing how some mistakes become clear seconds later you write about them :)

3:55 LauJensen: Its called the Rubber plant effect I think

3:55 Somebody discovered that developers could solve complex problems, if they just retold the problem, to anybody, even a plant

3:56 spariev: obviously we have too few plants in the office

3:58 bobo_: aint it rubber duck?

3:58 spariev: Lau got it right - http://www.cb1.com/~john/computing/rubber-plant-effect.html

3:59 LauJensen: bobo_: Dont you feel silly for using a rubber duck all this time ?! :)

4:00 bobo_: http://en.wikipedia.org/wiki/Rubber_duck_debugging

4:00 i used wikipedia, i win! :-)

4:02 LauJensen: :(((

4:02 Man you created that page and altered the timestamps fast!

4:02 bobo_: indeed!

4:02 or i planed this al along

4:16 edbond: Hi, how to use java iterators in clojure? .hasNext, .next etc. I want to have clojure sequence from it.

4:18 LauJensen: edbond: iterator-seq and enumerator-seq

4:19 ,(doc iterator-seq)

4:19 clojurebot: "([iter]); Returns a seq on a java.util.Iterator. Note that most collections providing iterators implement Iterable and thus support seq directly."

4:22 edbond: LauJensen: thanks

4:36 LauJensen: How do I run a task with cake in the context of my application? I need access to the entire classpath and all namespaces?

4:38 notsonerdysunny: (ns jrealityTutorial.core

4:38 (:import [[de.jreality.plugin JRViewer]

4:38 [de.jreality.geometry Primitives]

4:38 [de.jreality.reader Readers]

4:38 [de.jreality.ui.viewerapp ViewerApp]

4:38 [de.jreality.scene.data AttributeEntityUtility]]))

4:39 Hi everybody .. can you tell if above is the right way to import multiple classes? (sorry for flooding .. I was hoping it would appear on a single line)

4:39 clojurebot: trampoline is http://groups.google.com/group/clojure/browse_thread/thread/6257cbc4454bcb85/3addf875319c5c10?#3addf875319c5c10

4:40 notsonerdysunny: It is not compiling

4:40 LauJensen: notsonerdysunny: Its not a vector of vectors, its vectors

4:41 hoeck: or lists: (ns ... (:import (de.jreality.plugin JRViewer) ... ))

4:41 notsonerdysunny: LauJensen: thanks

4:42 LauJensen: np

4:44 bartj: hmm, I thought :import were put in lists and :use were put in vectors ?

4:44 based on the convention, I see in the Clojure code I read

4:45 LauJensen: bartj: if we had conventions for use/import/require etc, Clojure would simply be too easy

4:45 bartj: LauJensen, I am afraid, I don't understand

4:46 of course both lists and vectors are sequences, so they are interchangable ?

4:46 LauJensen: bartj: Im just making a joke. The whole import/use/require system has been a bit confusing since the beginning. (use .. is quoted, (:use is not, takes vecs and lists etc, huge overlap between require and use. Personally I use vectors for everything

4:46 ,(seq? '(1 2 3))

4:46 clojurebot: true

4:47 LauJensen: ,(seq? [1 2 3])

4:47 clojurebot: false

4:47 bartj: scratches head

4:48 LauJensen: Maybe this makes more sense

4:48 ,(filter seq? [[1 2] '(1 2) #{1 2} {1 2}])

4:48 clojurebot: ((1 2))

4:48 LauJensen: ,(filter coll? [[1 2] '(1 2) #{1 2} {1 2}])

4:48 clojurebot: ([1 2] (1 2) #{1 2} {1 2})

4:48 LauJensen: Use collections where they make sense, and sequences (lists) where you need their special properties. lists and vectors arent totally interchangeable

4:48 fliebel: morning

4:48 LauJensen: fliebel: morning

4:50 bartj: LauJensen, It would be wonderful, if you could provide an example - as to why, lists and vectors are not interchangeable

4:51 LauJensen: ,(reduce conj [] [1 2 3])

4:51 clojurebot: [1 2 3]

4:51 LauJensen: ,(reduce conj '() [1 2 3])

4:51 clojurebot: (3 2 1)

4:51 LauJensen: Thats one thing, another is they have completely different performance characteristics

4:52 Which tilkov and Chousuke actually put up a blogpost/table about ... wonder where that went

4:52 clojurebot: performance of datatypes?

4:52 clojurebot: http://clojure.org/java_interop#toc46

4:52 fliebel: laujensen: That has always bothered me. Comming from Python with their "one way to do it", it feels wrong to have conj go in the other direction just because.

4:52 LauJensen: fliebel: Its a good thing. You want more datastructures. Everything in Clojure is data right? So we need to express ourselves in different ways

4:52 Like simulating a stack with a vector sucks, but not with a list

4:58 bartj: LauJensen, I think a vector sucks when you want to access data sequentially

4:58 LauJensen: Its the O(1) lookups thats bothering you? :)

4:58 bartj: and a list when you need random access

4:58 that's about it, right ?

4:59 LauJensen: I fail to see how a vector isnt suited for sequential access. Its more performant than a list, so heavy lifting should be done in vectors

4:59 bartj: am sorry, I mean some operations have to be performed sequentially

4:59 like insertion for example

5:00 LauJensen: Im with you so far, that if you need insertion at the front, a list is probably what you want

5:01 bartj: yes, you are right

5:02 LauJensen: Another thing which is important, is that if you do start out with a list, and go through map/filter/remove etc, which are all made to work on collections, your sequence will be cast to collection, thus slowing the process down

5:06 bartj: , (list? (keys {:a 1 :b 2}))

5:06 clojurebot: false

5:07 bartj: well, honestly I thought the keys function would give a list

5:07 , (type (keys {:a 1 :b 2}))

5:07 clojurebot: clojure.lang.APersistentMap$KeySeq

5:08 bartj: because a list is seq-able right ?

5:08 but, it seems to be a collection !

5:10 anars: ,(doc keys)

5:10 clojurebot: "([map]); Returns a sequence of the map's keys."

5:10 anars: there you go.

5:24 Bjering: I have the very first baby steps on my minimal clojure wrapping of NIO.2, would be great to hear some feedback on how it could be made better if anyone wants to look: https://gist.github.com/62014c28ba42f0c03b2b

5:29 LauJensen`: Bjering: No typehints?

5:30 Bjering: not yet, my thinking is any typehints should be motivated by profiling and its not enough in there to profile yet. Or is typehints acceptable "pre-mature" optimization? I do think they make things uglier.

5:31 LauJensen`: no no no

5:31 Never prematurely optimize. A poorly placed typehint can slow your code down

5:31 Bjering: A question, can I get clojure to memoize the reflection? Seems to me that should really be enough in alot of cases.

5:31 LauJensen`: I think your lib looks quite well, though I havent thought about how I would model it so I cant comment on your abstraction level. Stylewise I would prefer to stay away from long names and instead choose short descriptive names with good docstrings.

5:32 Bjering: I guess it could be done for static functions, but normally you wouldn't want that in case something changes somewhere.

5:32 Bjering: its very little abstraction, I want to recognize the java lib below it. Any abstractions will be built on top of this thin clojure-layer

5:32 LauJensen`: Ok

5:33 Bjering: One question, uis such super-thin wrapping really any point or just stupid, should I go with java-interop instead?

5:34 LauJensen`: Well, you seem to have an oppinion about bundling some state and keeping it in atoms, so if that works well I'd say thats enough justification for a wrapper lib in my mind. If people don't like it they'll likely roll their own or just interop

5:36 Bjering: I must say I dont have enough hybris to imagine anyone else to use this lib :) But what is good lib design is good lib design even if I am the only user. Only difference with a "private" lib I dont have to give as many extension-points/parameters. Ie I can be more opinionated and rely on convention-only, ie no configuration options. Which makes it alot easier to test.

5:38 the tests, testing "behavior" such as that callbacks are called, call for state, I think its alittle clumsy, but a full mock seems an overkill atm, but eventually is there a good way to mock in clojure?

5:38 LauJensen`: Try searching for 'mock' on disclojure.org, I think I saw a realease of some lib for that not more than a couple of weeks ago

5:43 Bjering: Is there a streams lib for clojure that can do things like tokenizing based on arbitrary delimiters?

5:44 LauJensen: Not sure

5:44 What are those guys who are running cake called? And where are they !? :)

5:45 bobo_: im going to kill someone for creating php soon, how can anyone like this crap?

5:46 bah wrong channel but anyway

5:51 esj: bobo_: you thought you were in #php ?

5:51 ;)

5:51 bobo_: :-p

5:52 its okay for a language to be dynamic or static. but it can atleast decide

5:55 fliebel: laujensen: Do you mind me asking you some questions about the structure of bestinclass.dk? I mean the how and where of template+text=page

5:56 LauJensen: fliebel: http://github.com/LauJensen/bestinclass.dk/blob/master/src/bestinclass/templates.clj

5:56 Sure, ask away

5:57 fliebel: let me read and think about this for a moment...

5:58 So you have a fixed and flat structure of templates?

5:58 LauJensen: its crazy, that last post I did it still on the frontpage of HN and have taken in over 20k hits in 2 days

5:59 the templates could be

5:59 <body><div id="msg"/></body>

5:59 the template could then do

5:59 [:div#msg] (content "Hi, this is the message")

5:59 or

5:59 [:div#msg] (clone-for [msg messages] (content msg))

5:59 to make multiple div-tags

5:59 fliebel: I see, so where do you store the html files?

6:00 LauJensen: typically in resources/

6:00 I usually make 1 or 2 master html files, which have headers, footers, imports etc, and then smaller ones for specific pages

6:01 fliebel: Becasue you use enlive, are the templates the same files as the result, or do you copy them?

6:02 LauJensen: the return of calling a template is a sequence of strings. You can write that to disk (like I do on bestinclass.dk) or serve them directly via Moustache, or basically whatever you want

6:02 Bestinclass.dk codewise was primarily a way to convert a wordpress blog into a clojure blog, so it scraped the old blog, passed the data through templates, wrote them to disk

6:03 fliebel: In my initial plan, I had a src and a dest folder, where the src folder contained templates and text, and was 'compiled' to the dest folder with the same structure.

6:04 LauJensen: yea thats certainly one way to do it

6:04 fliebel: But with enlive I can imagine they are the same thing, and you only update them.

6:05 So how do you map source files to templates?

6:06 LauJensen: If you look in templates.clj which I linked above, you'll see that deftemplates/defsnippet take first the name of your template/snippet and then the html file to base it on, then the selector, and the args

6:07 fliebel: yup, seen them. But say you have a blog post in a file, how does your app figure out which snippet to use?

6:09 LauJensen: I think the answer to that quetion is too specific to wordpress. Generally you don't pass the html to the snippet, you pass data. Make a template which has the general form of what you want as the result, then pass data in and the selectors will apply them where a match is found

6:10 This is the file I executed to the deploy the site the first time: http://github.com/LauJensen/bestinclass.dk/blob/master/src/bestinclass.clj

6:10 Besides the conversion, it generates the static html pages, like the frontpage on bestinclass.dk etc

6:11 alienscience: Comrades. I am turning a gist into a git project and I don't know what to call it.

6:11 It adds a bit of extra functionality to clojure.contrib.sql.

6:11 Should I call it: extra.contrib.sql?

6:11 fliebel: laujensen: And what do you run when you wrote a new post? Or updated a page?

6:11 LauJensen: alienscience: alien.science.sql might be better

6:12 contrib is not your domain

6:12 zmila: how can I use (memoize) for recursive function (like factorial) ?

6:13 LauJensen: fliebel: admin.html contains a form which has action="/publish", that handler in admin.clj triggers http://github.com/LauJensen/bestinclass.dk/blob/master/src/bestinclass/admin.clj#L98

6:14 zmila: there's a memoized fibonnacci on one of the wikis

6:14 zmila: ok, i'll seorch

6:15 LauJensen: zmila: http://clojure.org/atoms

6:15 Look no further

6:15 fliebel: laujensen: ah, of course… You're running moustache, which directly parses it's stuff, while I'm thinking in terms of markdown files.

6:16 LauJensen: Yea, Moustache is like Enlives speedy cousing, they go well together

6:16 alienscience: LauJensen: There was a big discussion on the clojure group about library names. People didn't seem to like domain names too much.

6:16 zmila: ho, the trick is (def fib (memoize fib)) - redefine the same name

6:17 LauJensen: alienscience: Its not a matter of taste. We (I say we respectfully, I didn't start it) movement where we scrapped domain names, but as it turns out that can give you bad java interop problems down the line - Domain names are there for a reason

6:20 alienscience: I also have the problem that I'm sharing the library with someone. I don't want to tie it to one of my domains in Clojars.

6:21 fliebel: ~seen defn

6:21 clojurebot: defn was last seen in #clojure, 2681 minutes ago saying: http://copperthoughts.com/p/the-golden-ratio-is-evil/

6:23 zmila: sadly, the trick with memoize of recursion function works only for direct calls, recursive calls are not memoized

6:24 alienscience: Ah, forget that - Clojars allows you to add people to groups. Its cool. I'll use a domain name. Thanks for your help.

6:24 LauJensen: zmila: No not unless you memoize the actual multipliction

6:25 lets try that again: multiplication

6:25 zmila: LauJensen, if I do (fib 6) than (fib 6) is returned instantly, but (fib 4) is calculated again

6:26 calling to (fib 6) creates only one memo, not all the 0 till 6

6:26 serp_: really?

6:26 LauJensen: memoize in core is very simple. If you pass the same arg twice you get you a cached result

6:27 serp_: LauJensen: but (fib 6) will call (fib 5) etc... shouldn't they be cached then?

6:29 zmila: serp_ (fib 6) will call old version of (fib), not memoized

6:36 alienscience: zmila: Does this mean this example is wrong http://clojure.org/atoms

6:37 Bjering: a no-op function that always return nil ant takes any number of arguments, do we have this?

6:37 zmila: alienscience - it's not complete, and not fair

6:37 tomoj: Bjering: (constantly nil)

6:37 Bjering: thanks

6:38 tomoj: -> (apply (constantly nil) (range))

6:38 sexpbot: => nil

6:38 tomoj: :)

6:41 joegallo: Good morning. I'm getting a NullPointerException that comes from Var.java line 295. I'm flummoxed.

6:42 Clojure 1.2.0, the line is "Frame f = dvals.get();". It just doesn't seem like dvals could be null, though...

6:43 LauJensen: joegallo: I think you got lost looking for ##java? :)

6:44 (that is, if youre hacking the clojure source)

6:46 joegallo: Heh, nope. I'm trying to run robocode from clojure. It's vanilla clojure-1.2.0.jar.

6:46 LauJensen: oh

6:47 joegallo: I suppose robocode might be doing some magic with classloaders, which might be the issue.

6:51 fbru02: hey guys , how do i do a map in clojure ? i always use reduce or filter but never map

6:51 and i got this problem that didn't give me the output i expectedhttp://pastie.org/1120086

6:52 anyone can help??

6:52 LauJensen: fbru02: map returns the result of applying your function, in this case (nil nil), your function prints, which is a side-effect that has no return

6:52 (doseq [i '(1 2)] (println i)) is what you want for side-effects

6:53 fbru02: LauJensen: cool, so for side effects should i use seqs ?

6:53 LauJensen: seq is an interface, which is particularily well suited for non-side-effectfull computations. Use doseq or dotimes for side-effects

6:54 use map, filter, remove, etc on collections

6:54 fbru02: LauJensen: thank you , understood

6:54 LauJensen: np

7:09 sid3k: whatever I try to do using mvn/ant fails... after switching to debian squeeze, lein started to not work

7:11 zmila: is there a function that does (divisible a b) = (zero? (rem a b)) ?

7:12 LauJensen: sid3k: debian was all the rage in 1969, try Arch

7:12 bobo_: or mint?

7:13 LauJensen: bobo_: dont be vain :)

7:13 bobo_: i havent tried it. but it looks nice?

7:14 LauJensen: I tried it, was okay for a little while, then they got so popular that their servers drowned. Was some nasty package incompatabilities as well. But its not even in the same leageue as Arch though

7:17 sid3k: guess I need to reinstall maven but I don't know where it is

7:20 LauJensen: sid3k: sudo apt-get purge maven && sudo apt-get install maven ?

7:21 or mvn, I forget what its called on debian

7:21 sid3k: LauJensen: tried both

7:22 bobo_: sid3k: rm -rf ~/.m2

7:22 sid3k: maven is not installed but lein still uses anyhow

7:22 bobo_: thats where all the libraries are

7:22 sid3k: bobo_: yeah, this is the one thing I can do about maven :)

7:23 bobo_: :-)

7:29 sid3k: after installing fresh version of lein

7:30 lein new foo & cd foo & lein deps commands gives this output: http://gist.github.com/553205

7:30 any ideas are welcome, google doesn't return any good result for this trouble

7:36 LauJensen: its simply saying that it cant find an artifact, sure you got the name right?

7:39 sid3k: LauJensen: yeah, I've added content of the project.clj file to the gist

7:40 http://gist.github.com/553205

7:40 very mysterious problem

7:41 alienscience: sid3k: whats lein --version say?

7:41 I just tried the same with 1.3.0 on Ubuntu and all is good

7:41 sid3k: Leiningen 1.3.0 on Java 1.6.0_20 Java HotSpot(TM) Client VM

7:41 alienscience: I'm using maven 2.2.1

7:42 LauJensen: I just tried on Arch, works fine as well

7:42 spariev: maybe you have network problems ... I can't reproduce the problem on fedora

7:42 alienscience: sid3k: Oh, it probably worth asking if you're behind a firewall?

7:44 LauJensen: hmm, all distros seem to work except debian.. what could be the problem... hmm :)

7:44 alienscience: Maven needs extra options if you access the internet through a proxy

7:45 sid3k: alienscience: no proxy, no firewall.. very strange

7:47 even if I install and configure clojure without using lein, it will raise same exceptions when I try to use it to get dependencies of another clojure project

7:47 raek: something like this has happened to me before, but I could always solve it by removing the .m2 dir

7:47 sid3k: you're not running lein as root, right?

7:47 sid3k: I removed it for many times

7:48 raek: really strange

7:48 LauJensen: sid3k: Perhaps you could try to install the super-pom dependency manually and retry

7:50 sid3k: BTW, I removed maven2 and ant packages from the system

7:51 but still lein launches maven anyhow

7:51 raek: what does "which mvn" return?

7:51 sid3k: nothing

7:52 alienscience: I thought Leiningen needed Maven to be installed?

7:52 sid3k: and debian offers to install lots of dependencies including openjdk if I try to install maven2 and ant

7:52 alienscience: yeah, and I removed maven2

7:52 but still it can launch mvn

7:53 bobo_: locate mvn tell you anything usefull?

7:54 raek: as for the jvm, you can select which to use with "update-java-alternatives"

7:54 joegallo: Leiningen bundles the maven classes that it needs, they're inside leiningen-standalone.jar.

7:54 It doesn't need the maven executable.

7:54 LauJensen: sid3k: You're on openjdk ?

7:55 sid3k: LauJensen: nope, it's not installed

7:55 LauJensen: ok

7:55 Did you try installing super pom manually ?

7:56 sid3k: not yet, I don't know what it is

7:57 LauJensen: Then read the error dump from lein. It shows that it cannot get 2 dependencies for you, one is clojure and the other is super-pom, then shows you how to install them manually instead

7:58 sid3k: I've updated java alternatives and installed both ant and maven thing

7:58 raek: which program is not doing what it should? I mean, one should not normally have to do these things manually..

7:58 sid3k: no difference about problem

7:59 raek: http://gist.github.com/553205

7:59 raek: yes, but is this a bug in leiningen or in maven?

8:00 sid3k: no idea

8:00 spariev: sid3k: can you download clojure jar from repo manually - wget http://build.clojure.org/releases/org/clojure/clojure/1.2.0/clojure-1.2.0.jar ?

8:01 raek: (this was an open question to everyone in #clojure)

8:01 sid3k: arright :)

8:01 naeu: How do I extract more useful information from a situation that generates an error message like this: java.lang.RuntimeException: java.lang.NullPointerException (NO_SOURCE_FILE:0)

8:02 sid3k: spariev: I'll try to install manually but after installation, lein continues to raise same problems

8:02 raek: naeu: which editor/IDE?

8:02 spariev: hm, very strange

8:02 naeu: raek: emacs

8:02 spariev: no network problems, then

8:02 raek: the original exception is wrapped as the cause of the RuntimeException

8:03 naeu: althought that particular cut and paste was from a lein repl session

8:03 raek: so how do I get to it to take a look?

8:04 raek: naeu: you should be able to type 1 in the exception buffer that pops up

8:04 naeu: ok, but if I'm on the terminal, there's no way to access it?

8:04 raek: or click the line that begins with [CAUSE1] under "Restarts"

8:05 the exception is stored in *e

8:05 naeu: raek: ahh, nice

8:05 raek: I think there is something in contrib for looking at stacktraces

8:05 naeu: raek: great, I'll take a look

8:05 thanks very much for your help

8:06 raek: (.printStackTrace *e) might do what you are looking for

8:06 if you use slime, that will print in the swank terminal

8:07 not in the *slime-repl clojure* buffer

8:07 naeu: perfect. Yep, I normally use slime.

9:03 jcromartie: is there any kind of idiomatic approach to a data type with history?

9:04 for instance, I'm working on a financial system, and I have invoices that I want to track

9:04 and I'd like to deal with them in terms of a sequence of changes

9:04 basically a sequence of maps

9:06 maybe this is where deftype comes in

9:06 raek: do you need a new jvm type for it?

9:06 jcromartie: no

9:06 or a protocol for history

9:06 pdk: do you mean the data type would be persistent or it'd store the differential between pre/post-change versions within itself

9:06 all of clojure's core data structures are immutable and persistent out of the box

9:07 jcromartie: right

9:07 I just mean I want to explicitly keep the history of the object

9:07 maybe this is where protocols and records make sense

9:08 pdk: aside from refs/agents/atoms/vars the functions that work on a clojure data structure return new versions of those objects with the changes applied

9:08 raek: I think that could be done with plain old maps, vectors, lists and refs

9:08 pdk: so you could take the return value of a function that modifies an object and store it in any other structure you want

9:09 so if you wanted to maintain a linear history of the object

9:09 jcromartie: I understand Clojure's persistent data structures

9:09 pdk: you could just append the newest version of it to a list as needed

9:10 jcromartie: yeah

9:10 raek: clojure's persistent data structures will share structure

9:10 jcromartie: yes

9:11 until you serialize and read them back in

9:11 then you just have a big list

9:11 which is another tricky spot

9:11 raek: then you might want to store them as deltas

9:11 jcromartie: right

9:11 raek: and build the maps from them by using assoc, etc

9:11 pdk: thats why hes trying to accomplish :p

9:13 jcromartie: although that might be more useful for serialization than runtime use

9:13 although it would be trivial to create a seq of values from the deltas

9:13 hmm

9:13 pdk: would you be looking for storing the history of objects in terms of "x versions back" or "x amount of time back"

9:14 raek: I think it could be a good idea too separate the internal representation and the serialization representation

9:15 jcromartie: pdk: not really

9:15 alienscience: jcromartie: If you don't minding reading scheme the following Chapter might be of interest to you

9:15 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html

9:15 jcromartie: pdk: I just think it makes more sense to store these objects as the sequence of states

9:15 because we deal with lots of state changes

9:16 alienscience: jcromartie: The section 'A functional-programming view of time' shows a bank account example

9:16 jcromartie: amount changed, approved by Jim, approved by Bob, put on hold by Sue, taken off of hold by Jim

9:16 nice

9:16 I love what I've read of SICP but I never got this far :)

9:16 time to put it on my reader

9:17 pdk: does sicp have any more substantial example uses of closures/macros than you tend to see in introductory books

9:17 like beyond the counter example or quicksort with macros

9:18 alienscience: pdk: No mention of macros. Some very cool use of higher order functions though.

9:18 jcromartie: it is the user's temporal existence that imposes state on the system... deep stuff

9:19 pdk: and that's why the machines want to rise against us

9:20 so they wont have to be coded in c

9:27 jcromartie: https://gist.github.com/f94f54d3801be0d7939a

9:27 b stands for bill :P

9:33 the interesting thing is that the set of functions that will operate on this data will probably need to look at the whole history and not just the current map

9:33 that's kind of messy, I think

9:37 alienscience: jcromartie: why do the functions need to look at the history?

9:38 jcromartie: because certain attributes of an invoice are determined by history

9:38 like, how many days did it spend in a certain state

9:38 or when things happened

9:38 or the set of people that have operated on it

9:38 et.c

9:38 etc.

9:41 fliebel: (offtopic: anyone experience with how long it takes scribd to generate a html version of a document?)

9:43 jcromartie: hmm, destructuring makes this really easy

9:43 (defn do-something [[current & rest :as history]] ...)

9:45 Bahman: Hi all!

9:46 fliebel: hi

9:46 LauJensen: lein question: How do I configure the classpath for custom tasks ?

9:51 alienscience: LauJensen: I don't fully understand your question but I don't think you can change the classpath

9:52 If you need something on the classpath its a dependency (as I understand it)

9:52 LauJensen: But since its already a dependency of the project Im compiling, whats the problem?

10:18 limux1972: what's the realy meaning for the dorun of force side-effect?

10:19 the api doc said that dorun used to force side-effect

10:21 chouser: compare:

10:21 ,(let [a (map prn (range 5))] a :hi)

10:21 clojurebot: :hi

10:21 chouser: ,(let [a (map prn (range 5))] (dorun a) :hi)

10:21 clojurebot: :hi

10:21 0 1 2 3 4

10:22 chouser: dorun forced the side effect of printing the values of a

10:22 limux1972: i see a blog that

10:23 (def x (for [x (range 1 5)] (do (println i) i)))

10:23 (dorun x)

10:23 (dorun x)

10:23 first it will print 1 2 3 4

10:23 second it print nil

10:24 raek: yes, after the lazy sequence has been realized, it won't be recalculated

10:24 limux1972: i see

10:25 i know it won't be recalulated

10:25 raek: and print always return nil

10:25 even in the first case

10:25 limux1972: then the side effect won't be appeared

10:28 originally i understanding dorun and doall, but since i see that "dorun used to force side-effect", i were sightly confused

10:30 raek: hrm, sorry. (dorun x) returns nil because dorun always returns nil

10:30 limux1972: yes

10:31 what i say is the second dorun not print 1 2 3 4

10:31 the first print 1 2 3 4 and nil

10:34 jlf`: can anyone here comment on the maturity/stability of clj-record?

10:34 limux1972: as my understanding of "dorun used to force side-effect", it should also print 1 2 3 4 and nil when it eval second time exactly as the first

10:36 raek: a lazy sequence can only be forced once, that's the way they work

10:37 edbond: how to enable/use clj-stacktrace in slime?

10:37 raek: if you want to delay some code, and be able to make it run multiple times, just use an ordinary function

10:37 limux1972: because x is a lazy seq and it already evaled, so at second time nothing happened except return it's vaule nil in this case

10:38 neotyk: Guys how do I use (c.t/do-template [a] (defn a ..)) to also generate documentation?

10:38 limux1972: thanks, raek

10:38 what's an ordinary function?

10:38 raek: a function :)

10:39 there's nothing special called "ordinary function"

10:40 (defn x [] (doseq [i (range 1 5)] (println i)))

10:40 (x)

10:40 (x)

10:40 jlf`: technomancy|away: `lein new' also omits the final newline in .gitignore , so commands like 'echo newly-ignored-file >>.gitignore' weld two entries together

10:40 raek: or using dorun and map: (defn x [] (dorun (map println (range 1 5))))

10:43 limux1972: what's difference between your x and mine?

10:44 raek: my x is a function, your x is a sequence

10:44 limux1972: lazy sequence

10:44 raek: (defn foo [args] body) is the same as (def foo (fn [args] body))

10:45 edbond: ,(.?. "foo" .toUpperCase (.substring 1))

10:45 clojurebot: java.lang.Exception: Unable to resolve symbol: .toUpperCase in this context

10:46 raek: ,.?.

10:46 clojurebot: java.lang.Exception: Unable to resolve symbol: .?. in this context

10:47 limux1972: a bit of clearness by you explanation

10:56 slyrus: ,(.getRawOffset (java.util.TimeZone/getDefault))

10:56 clojurebot: -28800000

10:57 raek: ,(/ -28800000 3600)

10:57 clojurebot: -8000

10:57 raek: ->(/ (.getRawOffset (java.util.TimeZone/getDefault)) 3600)

10:57 sexpbot: java.lang.SecurityException: Code did not pass sandbox guidelines: ()

10:57 limux1972: bye, raek

11:03 LauJensen: $mail Raynes Whitelist: (/ (.getRawOffset (java.util.TimeZone/getDefault)) 3600)

11:03 sexpbot: Message saved.

11:04 akhudek: it would be nice if clojure.walk supported record types when doing replacements

11:05 I've hacked up a poor mans version of the library to do this

11:06 raek: 17:05 [freenode] [ctcp(sexpbot)] TIME

11:06 17:05 [freenode] CTCP TIME reply from sexpbot: Fri Aug 27 17:14:01 CEST 2010

11:06 => +2000

11:10 fliebel: hey

11:11 akhudek: hi fliebel

11:19 slyrus: why is the http-agent contrib deprecated?

11:22 or, to put it another way, if I'm used to using drakma in CL-land, where should I start in clojure-ville?

11:31 dnolen: slyrus: I use clj-apache-http and like it quite a bit.

11:49 slyrus: I guess I need to get over the clojure-all-the-way down instinct

11:50 is there a reason you use that instead of clj-http?

11:51 ssideris: hello

11:51 I'm trying to make a lazy-seq of prime numbers

11:51 i've come up with this

11:51 http://pastebin.ca/1926919

11:52 but for bit values of top it runs out of stack

11:52 can anyone explain why?

11:54 chouser: yes

11:54 ssideris: bit=big

11:54 pdk: try making it (lazy-seq (cons (first xs) (euler ...

11:54 chouser: but it's a bit tricky to describe

11:55 pdk: instead of (cons (first xs) (lazy-seq (euler ...

11:55 chouser: the problem is that 'remove' is lazy

11:56 the lazy-seq returned by 'remove' is passed into euler again, and another 'remove' wrapped around it, and so on

11:56 so you end up with something logically like (remove f (remove f (remove f ...)))

11:57 ssideris: ah very deeply nested removes

11:57 so what would be a better way to write this?

11:58 chouser: then when you force one of those, each remove has to force the next one down, each calling a function, adding to the stack...

11:58 edbond: how to walk over map and apply func to vals?

12:00 mefesto: edbond: doall

12:00 chouser: ssideris: that algorithm essentially iterates over 2 through n to determine if n is a prime or not

12:01 ssideris: chouser: i wasn't trying to write a test of whether n is a primer or not, I actually wanted the full sequence

12:01 chouser: ssideris: so you could do that more explicitly

12:01 ssideris: I understand, but what you've got there is doing the same work as (filter is-prime? (range 2 top))

12:02 ssideris: agreed...

12:02 chouser: ssideris: so if refactor to that, I doubt you'll have any problem writing 'is-prime?' that doesn't blow the stack.

12:03 however, it's also not very efficient. You can spend a lot of time working out efficient algorithms to produce lazy seqs of primes

12:03 there's even a paper on the topic

12:03 edbond: mefesto: looks like doall doesnt what I need, I meant hash-map

12:03 ssideris: chouser: I could maybe memoize my is-prime?

12:04 chouser: ,(let [m {:a 1, :b 2, :c 3}] (zipmap (keys m) (map inc (vals m)))

12:04 clojurebot: EOF while reading

12:04 chouser: ,(let [m {:a 1, :b 2, :c 3}] (zipmap (keys m) (map inc (vals m))))

12:04 clojurebot: {:c 4, :b 3, :a 2}

12:05 edbond: chouser: cool, thanks

12:05 chouser: ,(into {} (fn [[k v]] [(name k) (* v v)]) {:a 1, :b 2, :c 3})

12:05 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$into

12:05 chouser: sheesh

12:05 ,(into {} (map (fn [[k v]] [(name k) (* v v)]) {:a 1, :b 2, :c 3}))

12:05 clojurebot: {"a" 1, "b" 4, "c" 9}

12:05 chouser: edbond: take your pick. there are other ways too.

12:06 pdk: yknow i never looked into it enough to see what sort of cases -> and into are useful for

12:06 (doc into)

12:06 clojurebot: "([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."

12:06 chouser: into is very important. you need it in your toolbox.

12:06 pdk: you could say...

12:06 chouser: (into toolbox 'into)

12:06 * pdk shades

12:06 pdk: i need to put it

12:06 GOD DAMN IT you stole my thunder

12:07 chouser: :-( sorry

12:07 dnolen: slyrus: I looked at the various options and clj-apache-http seemed the most comprehensive as well as being built upon something solid and well-tested. the other Clojure http libs are more minimal but that also means less malleable.

12:07 pdk: hm

12:07 slyrus: ok, thanks dnolen

12:07 pdk: are there any blog posts or such outlining the cases where you'd want to use -> and into

12:07 dnolen: slyrus: it's also maintained by a Common Lisper :)

12:07 ssideris: dnolen: no pressure, but did you get the chance to push native-deps 1.0.3?

12:08 dnolen: ssideris: I could not push to clojars last night I don't know what's up.

12:08 ssideris: ah ok... your fans are waiting eagerly :-D

12:08 dnolen: ssiderris: just clone the repo and run lein install inside of it.

12:08 ssideris: yeah, I think i'll do that :-)

12:08 dnolen: ssideris: sigh I know, the clojars issue is frustrating, hopefully it will suddenly start working.

12:11 ssideris: erm, I'm feeling a bit stupid for asking this, but where is the repo for native-deps?

12:11 ok found it

12:11 sorry

12:16 dnolen: hm, I get Exception in thread "main" java.lang.IllegalAccessError: make-dependency does not exist (native_deps.clj:1)

12:16 (i'm on windows if that makes any difference)

12:17 dnolen: ssideris: are you on lein 1.3.0 }

12:17 ?

12:19 ssideris: i think i am...

12:20 $ lein.bat version

12:20 Leiningen nil on Java 1.6.0_17 Java HotSpot(TM) Client VM

12:20 haha

12:20 great

12:20 dnolen: ssideris: you might want to run lein upgrade

12:21 ssideris: that's not available on windows...

12:21 but it seems that lein.bat mentions 1.3.0

12:21 and it's pointing to leiningen-1.3.0-standalone.jar

12:21 fliebel: Oh, Im starting to love leiningen for its clarity and reliability.

12:23 ssideris: so I think I have the right thing...

12:25 dnolen: ssideris: hmm ... I tested it so it should work (not on Windows). make-dependency seems to indicate that you're not on the right version of lein.

12:26 ssideris: ok, i'll investigate further....

12:28 dnolen: you're right, it was my fault... sorry!

12:29 dnolen: ssideris: cool, good to hear

12:30 ssideris: woohooo, at last running penumbra/pong :-)

12:31 fliebel: ssideris: what's that?

12:31 dnolen: ssideris: awesome!

12:31 ssideris: penumbra is a wrapper for opengl

12:31 dnolen: and a very good one at that

12:31 ssideris: and it includes a few examples

12:31 Raynes: I need to try that.

12:32 I've never done OpenGL before.

12:32 fliebel: So you could write games and stuff using penumbra?

12:32 ssideris: dnolen, Raynes: my idea is to learn a bit about opengl using the repl... it should make it much easier/fun because of the interactive nature of the process

12:33 Raynes: Indeed.

12:33 dnolen: Asteroids is like > 400 lines of code in Penumbra

12:33 oops < 400

12:33 fliebel: ssideris: Assuming you can modify the thing after you have started it?

12:33 dnolen: ssideris: yeah that's one of the great features about penumbra, be able to change to the running code on the fly.

12:33 fliebel: you can

12:33 ssideris: pong is 130 lines and tha includes some "A.I."

12:34 fliebel: dnolen: Great! Most of the time this kind of things are of the setup-and-run kind.

12:35 dnolen: fliebel: the entire world is actually passed around to the core fns, so it's possible to modify the game state on the fly as well as modifying fns and whatnot.

12:35 ssideris: have you guys heard of the livecoding scene? people doing graphics and/or music by coding live in front of an audience...

12:35 dnolen: ssideris: yes. the other cool Clojure live-coding project is overtone

12:35 a wrapper around SuperCollider

12:35 ssideris: dnolen: yeah I saw that... but I'm more of a visual guy

12:36 although overtone seems to include a graphical repl (which I haven't tried yet)

12:36 dnolen: ssideris: you can work with it entirely from emacs, but they are working on a fairly fancy ui as well.

12:37 emacs or whatever.

12:37 ssideris: fancy in what way

12:38 dnolen: ssideris: envelope manipulation via penumbra view, integrated text editor, integrated repl

12:39 ssideris: sounds like a fantastic way to show off in a livecoding event :-)

12:40 * slyrus longs for the lein swnak plugin

12:41 dnolen: ssideris: I started porting the nehe tutorials a while ago, http://github.com/swannodette/clj-nehe to penumbra

12:42 ssideris: oooh nice!

12:43 although nehe has a slightly dubious reputation

12:43 because of his coding styl

12:43 style

12:43 still, very useful, thanks!

12:43 jcromartie: ssideris: how about this...

12:44 ,(iterate #(.nextProbablePrime %) (bigint 1))

12:44 clojurebot: (iterate #(.nextProbablePrime %) (bigint 1))

12:44 clojurebot: Execution Timed Out

12:44 programming clojure is http://www.pragprog.com/titles/shcloj/programming-clojure

12:44 jcromartie: oops

12:44 ,(take 20 (iterate #(.nextProbablePrime %) (bigint 1)))

12:44 clojurebot: (1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67)

12:44 jcromartie: there you go

12:46 raek: ooh, new version of Joy of Clojure

12:46 ssideris: hehe, nice, didn't know about this, but my question was more about learning clojure and less about using the java standard lib to work around the problem

12:47 dnolen: raek: so who is the secret foreward written by? :)

12:48 jcromartie: :)

12:48 ssideris: sometimes the best way to do something in Clojure is to use the Java method

12:48 but I understand

12:49 for instance there was this blog on doing bit counts (population) of integers

12:49 http://metaljoe.wordpress.com/2010/08/12/bit-counts-in-python-erlang-and-clojure/

12:49 raek: dnolen: the pdf does not contain any foreword

12:49 jcromartie: the best clojure version is (.bitCount (bigint n))

12:49 dnolen: raek: argh!

12:51 fliebel: Huh? what is this? nextProbablePrime Especially the probable part...

12:53 ssideris: jcromartie: yeah, that's probably the "best" in production code, but for educational purposes I need to know how to make lazy seqs without blowing the stack

12:54 jcromartie: yeah :) did you figure it out?

12:54 fliebel: Returns the first integer greater than this BigInteger that is probably prime. The probability that the number returned by this method is composite does not exceed 2-100. This method will never skip over a prime when searching: if it returns p, there is no prime q such that this < q < p.

12:54 that's (Math/pow 2 -100)

12:55 so it's very primey

12:55 :)

12:55 ssideris: jcromartie: nope, got distracted by the fact that I got penumbra working!

12:55 jcromartie: hah awesome, sounds like you're having fun

12:56 lazy-seq is important to understand, but it's also good to be able to use the abstractions like iterate and repeatedly, etc.

12:56 fliebel: Is there any page explaining all the different ways of loading modules? There is a whole bunch of them, and they even work different when used in the ns declaration.

12:56 I mean: load, use, require...

12:56 ssideris: fliebel: afaik you should only use them with ns

12:57 fliebel: s/load/import/

12:57 ssideris: Still, I'm screwing up the syntax for them every time.

12:58 raek: ssideris: this is an example I tend to show pretty much anyone who's learning lazy sequences. I guess you aldready know the basics, so maybe this is totally superflous. but anyway, here it is: http://gist.github.com/480608

12:58 ssideris: how about this: http://en.wikibooks.org/wiki/Clojure_Programming/Tutorials_and_Tips#Using_the_.28ns.29_macro

12:58 raek: fliebel: this covers the basics: http://clojure.org/libs

12:58 fliebel: ssideris: And how about the non-ns veriants for on the repl?

12:59 ssideris: fliebel: i think you can still use ns in the repl with (ns user ...

12:59 raek: also, all those forms except ns are functions and thus requires you to quote their arguments

12:59 mrBliss: fliebel: drop the : and add a quote

12:59 fliebel: (ns .. (:use [..])) -> (use '[..])

12:59 raek: mrBliss sums it up very well... :)

13:00 also, don't use ns to switch namespace, use in-ns for that

13:00 (if you want to play around in a certain namespace with the repl)

13:00 ssideris: raek: oh

13:00 fliebel: mrBliss: (:use clojure.contrib.lazy-seqs)) -> (use clojure.contrib.lazy-seqs) = java.lang.ClassNotFoundException

13:01 mrBliss: you forgot the quote

13:02 fliebel: mrBliss: Nice… a class literal? or what would that be?

13:02 raek: exactly

13:02 jcromartie: I think the confusion comes from the fact that the ns macro uses unquoted symbols

13:02 and uses keywords for functions where they are usually symbols

13:02 fliebel: jcromartie: Yea… not so nice, combined with several different import statements.

13:03 jcromartie: they have different uses

13:03 include loads Java packages

13:03 or classes

13:03 rather

13:03 raek: don't forget the empty prefix list! a very common mistake

13:03 jcromartie: require just loads a clojure lib

13:03 empty prefix list?

13:04 raek: (import '(foo.bar)) imports nothing

13:04 jcromartie: ah yes

13:04 raek: (import '(foo.bar a)) would import a from the foo.bar package

13:04 jcromartie: and 'use' is like require but imports everything in the current namespace

13:04 raek: but the first one imports *nothing* from foo.bar and doesn't signal any errors

13:04 jcromartie: I wish I could do (import '(java.util *))

13:05 fliebel: diner, bye

13:05 jcromartie: but NO! it's like Clojure expects me to use Java classes sparingly and with precision or something!

13:06 mrBliss: jcromartie: it's even discouraged in Java land

13:06 jcromartie: yeah I know

13:06 they expect you to know what you are doing, or something ridiculous like that

13:06 what if I just want to bog down the JVM with unused bytecode?

13:07 maybe that's *exactly* what I want to do

13:07 mrBliss: funny, because a clojure developer is more likely to know what he's doing than an average java developer :-)

13:08 jcromartie: I really want to move our company to clojure, because it basically means you can't hire idiots anymore

13:08 mrBliss: jcromartie: I agree :-)

13:08 jcromartie: as it is, we have some of the worst C# code I've seen

13:10 we added search to our system; if you search for an item, click on it to view it in the standard page that we always use, editing the item fails for some unknown reason

13:10 but if you reach the item's page from certain other pages, you can edit it fine

13:10 global (session) variables abound

13:12 like, how does that even happen? how does a programmer *do that*?

13:19 ssideris: raek: the lazy-seq example with use interaction is very informative, well thought out :-)

13:20 raek: really? neat... :)

13:21 I'm glad you found it useful

13:22 ssideris: it really drives the point of laziness

13:22 "drives home"? is that the phrase?

13:28 raek: it's so lazy, it doesn't even care to make up the values itself... :)

13:28 ssideris: we have truly enslaved ourselves to the machines!!! :-D

13:42 fliebel: How can I make a lazy seq that returns a list of 2 items from 2 other seqs?

13:43 jkkramer: ,(map vector [:a :b :c] [1 2 3])

13:43 clojurebot: ([:a 1] [:b 2] [:c 3])

13:43 jkkramer: like that?

13:43 fliebel: jkkramer: yea :)

13:45 astoddard: Has anyone here used the emacs org-mode, org-babel-clojure?

13:45 ssideris: i've used babel but not for clojure

13:46 astoddard: Ah, I ask because it seems the world of setting up clojure environments has moved on since org-babel-clojure was created.

13:47 I was hoping someone had the mode working and could offer some pointers on configuring it.

13:47 I would like to use it with something like cljr.

13:48 But its easier to modify something starting from where it is working...

13:48 technomancy: anyone else read that as cl junior?

13:52 neotyk: Just submitted checkable promise proposal http://j.mp/at4dsH http://j.mp/9LgTRj WDYT?

13:56 fliebel: Trying to figure out when nextProbablePrime will fail :)

13:58 alekx: very newbie question: a form is whatever is enclosed in paranthesis... is that correct?

13:58 jcromartie: fliebel: well you've got luck on your side...

13:58 alekx: then having a list (values) is '(val1 v2 ... )

13:58 jcromartie: ,(Math/pow 2 -100)

13:58 clojurebot: 7.888609052210118E-31

13:58 jcromartie: that's the probability of a non-prime being generated :)

13:59 alekx: so why is clojure called homoiconic as there's a difference between forms and values?

13:59 fliebel: jcromartie: Hmmm, so it might take a while before walking my lazy seq will stop and return the difference.

14:00 (how do I interrupt a loop without killing the repl?)

14:01 chouser: alekx: quoting comes in during evaluation

14:01 alekx: the compiler consumes nothing but data structures which have a textual representation which is exactly the representation we use when we write clojure code

14:02 alekx: chouser: what I don't understand is that according to my probably wrong definition homoiconic would mean there's no diff between code and data and that is deduced based on the runtime context

14:02 chouser: there is no diff

14:03 (v1 v2 v3) is a list of symbols

14:03 ,(count (read-string "(v1 v2 v3)"))

14:03 clojurebot: 3

14:04 chouser: eval'ing a list doesn't just return a list, it does something else.

14:04 alekx: chouser: how is that different from say a = [1, 2, 3]?

14:04 raek: this could be of interest: http://stackoverflow.com/questions/2877371/definition-of-lisp-form

14:04 chouser: alekx: what data structure is that?

14:04 alekx: there's something subtle I'm missing

14:05 string string list

14:05 raek: to me?

14:06 chouser: alekx: so what's the function like 'read' that consumes that text and returns string string list?

14:06 alekx: probably my confusion comes from the fact that in my brain there's something saying: all list/clojure reads is lists

14:06 first is lisp*

14:06 but then there are different kind of lists

14:07 * alekx is totally confused

14:07 chouser: no lisp reads only lists

14:07 raek: alekx: yes, regarding the odd word "form", but maybe that was already clear

14:07 alekx: raek: I'll read it as I'm not sure it is clear

14:07 chouser: even simple lisps can read at least lists and symbols, and most can also read other literals -- string, numbers, etc.

14:08 alekx: I mean... right now philosophically I do seem to be extremely confused

14:08 chouser: clojure can also read hashmaps, vectors, sets, etc.

14:08 alekx: chouser: very correct

14:08 so what exactly makes it homoiconic?

14:08 raek: in lisps, you are basically writing the AST directly

14:08 chouser: alekx: that the syntax of the language is built out of those things

14:09 alekx: but all syntaxes are build out of this things

14:09 built* these*

14:09 raek: clojure evaluation is not defined in terms of text strings, but in terms of nested data structures

14:09 its like if the java compiler could read code from nested ArrayLists

14:09 alekx: I mean ... java has symbols, numbers, etc... so what's the difference?

14:10 raek: you cannot do macros in java

14:10 alekx: raek: not sure I follow you

14:10 raek: macros take code and return code

14:10 alekx: "java compiler would read code from nested ArrayLists"

14:10 raek: and the code can be processed as ordinary data structures

14:10 mefesto: alekx: if you generate code in java you are creating a string that is parsed and compiled

14:10 alekx: in clojure you create data structures

14:11 alekx: it reads code from nested functions/etc

14:11 fliebel: Muhahahah! My first actual Clojure in months: http://gist.github.com/553870 I want to get started with the real work. Anyone seen defn? That script runs nearly forever by the way.

14:12 alekx: I think I'll have to pull out one of my old lisp books and re-read the intro parts

14:12 seems like my brain got old and tired and is missing subtle things :(

14:13 mefesto: that's true

14:13 mefesto: alekx: in java you don't have direct access to the representation of the code

14:13 alekx: so if I'm writing an AST program that would make it homoiconic

14:13 because I can create "structures" that will be later interpretted?

14:14 mefesto: how do you have it in clojure? are you referring to macros?

14:14 raek: if you make a programming language whose AST is build out of the data structures of the language, then it is homoiconic

14:14 *built

14:15 alekx: hmmm... there might be a little light at the end of the tunnel

14:15 raek: in most non homoiconic languages, the AST is just a compiler internal thing

14:15 mefesto: alekx: yeah in macros you can manipulate the forms as simple data structures that represent expressions

14:15 alekx: so, I have a PL that natively supports some data structures

14:15 raek: in lisps, it's basically what you program in

14:15 alekx: if I write the AST to work only with these data structures then I get homoiconic

14:16 raek: is that what you are saying?

14:16 raek: yes

14:16 alekx: has it been proved that it is impossible to right such a thing for Java for example?

14:16 I mean the current compiler definitely doesn't do that

14:17 but is there proof that it cannot be done? (theoretically)

14:17 raek: I suspect it would be possible to make an alternative "syntax" for java which is build on java collections

14:17 alekx: but why only collections?

14:18 fliebel: Does anyone knows why nextProbablePrime is probable?

14:18 alekx: you said data structures

14:18 mefesto: ,(eval (list 'println "hello"))

14:18 clojurebot: DENIED

14:18 mefesto: :-\

14:18 alekx: a "keyword" can be an atom and so a data structure

14:18 raek: ah, well any data structure written in java would do, I guess

14:18 ah

14:19 you need atoms too, of course...

14:19 sorry for being unclear

14:19 alekx: I see some light... but I'll still go back to my books :D

14:19 or probably just ignore this theoretical part for now ... which might be a bit more productive

14:20 raek: so the surface syntax / textual representation is not important for a homoiconic PL

14:20 alekx: this is the part that tends to make sense to me

14:20 raek: the compiler or evaluator does not care about which format the code was stored in

14:20 somnium: Dylan is an example of a language with syntax and macros

14:20 alekx: it is about how the program is represented by the interpretter/compiler

14:21 raek: yes

14:21 alekx: somnium: not familiar w/ Dylan

14:21 somnium: I think some recent ones too, Boo and Nemerle

14:21 technomancy: factor too, I think

14:21 mefesto: Ioke

14:21 somnium: still not as easy as lisp macros, but pretty expressive

14:21 KirinDave: Lisp macros are not easy.

14:21 The raw defmacro is actually the hardest way to do it.

14:22 Esp if you want real error handling in your syntax generator. Which is sorta necessary when your macros reach a certain level of complexity.

14:22 technomancy: basically every language whose author is well-educated and decides to make a clean break from the algol family.

14:23 KirinDave: I really need to see if I can sit down and copy PLT scheme's MBE.

14:23 I really like that system, mostly because it gives automatic error handling for a lot of common cases.

14:23 somnium: scheme syntax-rules style macros are very easy

14:23 KirinDave: Right.

14:23 Sometimes you need to write LOOP, then Defmacro is what you want.

14:24 But for example, Enlive's macro system would be vastly better if it had more error handling.

14:24 And MBE would make writing enlive's syntax stuff trivial.

14:24 raek: my gf jokingly when I mentioned homoiconic languages: "I think that most programming languages are indeed homosexual... they were made by men for men..."

14:25 KirinDave: dang

14:27 nollidj: i've got a quick question about leiningen: is there a flag i can pass to it which says "don't try to look for updates to stuff online"?

14:30 fliebel: What is the simples way to print the classpath?

14:31 mrBliss: fliebel: if you're using leiningen: $ lein classpath

14:31 fliebel: mrBliss: Not lein this time, just the repl

14:31 mrBliss: fliebel: (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))

14:32 fliebel: wtf, contrib just dissapeard!

14:32 mrBliss: fliebel: (. System (getProperty "java.class.path"))

14:33 fliebel: Just a moment ago, I wrote a script that utilized contrib, and how it freaks out and contrib is off the cp!

14:36 mrBliss: http://gist.github.com/553920

14:37 mrBliss: fliebel: strange

14:37 raek: nollidj: it seems like mvn has a -o option (for offline), but I don't know how to make leiningen use it

14:38 mrBliss: fliebel: and running clj in the previous dir fixes it?

14:38 clojurebot: with java6(jdk1.6) CLASSPATH can contain a "*" so /jar/dir/* will suck in all the jars in the /jar/dir directory, this also works with swank-clojure-extra-classpaths in emacs, alternatively you can use this shell snippet: find .jars/ -type f -name \*.jar -print0|xargs -0|sed "s/ /:/g"

14:38 fliebel: mrBliss: Yea...

14:39 mrBliss: fliebel: what's in your clj script?

14:41 raek: nollidj: I have also seen this: mvn dependency:go-offline

14:41 fliebel: mrBliss: http://gist.github.com/553920 9second file)

14:43 raek: I find it simpler to use cljr for one-off repl sessions (when I don't want to create a project) and leiningen for everything else

14:43 mrBliss: Me too

14:45 fliebel: it would be easier for ;-) and you (especially when you want to update or install some extra dependencies) to use cljr (supports swank)

14:45 fliebel: for got "me" before the smiley

14:46 fliebel: what is cljr?

14:46 mrBliss: fliebel: lein without the projects

14:46 fliebel: ok

14:46 mrBliss: fliebel: with easy dependency management adding

14:46 s/adding/http://github.com/liebke/cljr/

14:46 nollidj: raek: yeah, i knew maven had an argument for it

14:46 thanks

14:46 raek: basically, "get me a repl where I can use all libraries I have installed"

14:47 mrBliss: fliebel: I'll help you if you encounter a problem

14:48 fliebel: okay, I'll have a look

14:50 nollidj: doesn't seem like lein does, though

15:00 technomancy: nollidj: nothing yet, would love to see a patch for it or at least an issue

15:10 nollidj: technomancy: thanks for the answer. i might look into the code, but i'm stuck on 1.2 because of issues with native-deps and penumbra, so any patch would be based off an older branch

15:11 i'll make an issue, though

15:14 i guess it's really two issues: 1) if dependencies are present but lein can't connect to the internet, it doesn't fail gracefully. 2) there's no offline mode which lets you specify not to look online at all

15:14 would you want two different issues in the github tracker?

15:15 technomancy: sure, thanks

15:16 dnolen: man, a lot more people use native-deps than I thought :(

15:17 wouldn't know it from my 8 watchers on github tho

15:17 anybody else having trouble pushing to clojars today? yesterday?

15:31 somnium: anyone with admin access to clojars? Ive been wanting to add people to a group but seem to have forgotten my login info and ato seems to be mia :/

15:32 technomancy: somnium: ato is working on migrating to a new server where he won't be the only admin

15:32 but ... it hasn't happened yet.

15:32 nollidj: dnolen: if it helps, you might want to look at how many people use penumbra. that's what i use native-deps for

15:34 ssideris: yeah, penumbra seems to be the main use case right now :-)

15:44 ninjudd: technomancy: thanks for accepting my cake shebang highlighting patch to clojure-mode

16:04 technomancy: sure; thing

16:04 feels good to have my patch backlog clear again. =)

16:06 ninjudd: technomancy: i noticed that highlighting/indenting doesn't work in clojure-mode for deftype/defprotocol/proxy/etc. is there some option i need to set to enable it?

16:08 or is that not supported yet?

16:09 raek: highlighting should work, I think

16:10 indenting works in the latest commits if you set the clojure-mode-use-backtracking-indent variable to t

16:14 I made and pushed patches for this about a month ago

16:15 oh, you are a contributor of clojure-mode too, I see...

16:15 ninjudd: raek: barely

16:16 raek: that fixed the indenting. thanks!

16:17 raek: I saw your pull request, but I thought it would better if technomancy would decide about it

16:17 ninjudd: hehe, yeah

16:17 hmm... still looks like highlighting is wrong, but i may have a different idea of what is "right"

16:18 raek: all the def* forms should have a special color for the name

16:18 and docstrings should have another color too

16:18 (not protocol method docstrings so far, I think)

16:18 ninjudd: seems like the function names in a deftype should be the same color and with standard (defn ...) calls

16:19 s/and/as/

16:19 raek: hadn't thought about it in that way, but it makes sense

16:20 ninjudd: raek: does backtracking-indent support highlighting too?

16:21 raek: I have no idea :)

16:21 ninjudd: maybe it should be called back-tracking-context...

16:21 raek: it is some experimental code that technomanchy inherited from the previous maintainer

16:22 ninjudd: well, i'll submit a patch if i can figure out how to do it without too much trouble

16:23 raek: for me the name of a def is yellow

16:23 mefesto: didn't the "Contrib Libraries" link on clojure.org used to point to the clojure-contrib docs and not it's github readme?

16:23 ninjudd: yeah, me too

16:24 raek: do you want "method" in (deftype [] Foo (method ...)) to be yellow too?

16:24 ninjudd: yeah. that seems right to me

16:26 * raek looks throughs some code using protocols and defrecord

16:37 technomancy: I haven't actually used defrecord yet

16:37 so I am fully reliant on contributors to get this right. =)

16:43 ninjudd: looks like it is pretty complicated to do multi-line highlighting...

16:44 it would likely mean the entire deftype or defprotocol would have to be rehighlighted when it changes. which may be too slow

18:29 hiredman: ,(=)

18:29 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-EQ-

18:30 hiredman: ,(= 1)

18:30 clojurebot: true

18:34 seangrove: Hey all, wondering how I actually use server-socket

18:34 The link on the library page here: http://clojure.org/libraries#Clojure%20Libraries-Category:%20xml-clojure.contrib.server-socket.clj points to http://github.com/richhickey/clojure-contrib/ ... so I think it's in clojure.contrib

18:34 ... but I don't see it anywhere :P

18:37 Ah, nevermind

18:37 qbg: http://www.reddit.com/r/programming/

18:37 seangrove: Had a typo in my :use statement

18:37 mrBliss: seangrove: http://clojure.github.com/clojure-contrib/server-socket-api.html

18:37 qbg: Err, http://clojure.github.com/clojure-contrib/server-socket-api.htmcl

18:37 seangrove: Heh, thanks mrBliss, and you too qbg

18:39 Is there a generally favored testing lib in clojure?

18:39 hiredman: clojure.test?

18:39 clojurebot: clojure is cheating

18:40 seangrove: Looks good enough to start out with :)

18:45 I'm moving over from the scheme world, and intereste to build up a few throw-away libraries as a way to get used to clojure

18:46 I'd like to implement a quick twitter client from the socket level up - but not sure where I should look for clojure to provide the functionality, and where to rely on java interop

18:49 wwmorgan: seangrove: java.net.Socket provides socket functionality. Is that what you're looking for?

19:14 dnolen: finally native-deps 1.0.3 pushed

19:15 ssideris: woohoo!

19:15 :-)

19:15 thanks

19:15 btw, in your nehe ports, (:use [penumbra opengl geometry] ... doesn't work for me

19:15 it works fine if I leave the geometry part out

19:16 dnolen: ssideris: penumbra changed, I need to make a 0.6.0 tag

19:16 ssideris: ah, ok you know about this

19:16 i guessed it was something like that, thought to let you know

19:17 dnolen: ssideris: oh yeah, I created a 0.6.0 branch

19:18 just: git checkout 0.6.0

19:18 ssideris: ^

19:20 ssideris: thanks

19:21 btw, this is completely off-topic, but it's so cool I have to share: http://devour.com/video/racer/

19:37 darrenaustin: Hey folks, is there a way to read input from the repl's standard in from my own code?

19:45 hiredman: *in*

19:54 darrenaustin: I tried to just use either read or read-line from the REPL, but I just get EOF exceptions or nil.

19:54 I am using swank to talk to the repl. I don't know if that makes any difference.

20:03 ihodes: darrenaustin: text you enter into the REPL is read by the fn read, which parses the strings into Clojure forms, which are then passed to eval. if that gives you a better idea of what's going on.

20:03 hiredman: yeah

20:03 swank is funky about threads

20:03 it can mess with *in*

20:05 danlarkin: make sure to vocally blame technomancy

20:08 ssideris: I was reading that swank has problems with swing too (persumably because of threads)

20:10 slyrus: you sure it isn't swing that has problems with swank?

20:10 like swing stuff wanting to be run off of the initial thread?

20:12 does swank-clojure support fd-handler SWANK:*COMMUNICATION-STYLE*?

20:20 * slyrus falls for the 40% off trick

20:44 ihodes: if you want to run a Swing app from the repl (i've been doing it a lot the past few months for testing…) just make sure you call it with SwingUtilities/invokeLater

20:45 seangrove: (str symbol) returns ":symbol" - how would I get it to return just "symbol" ?

20:45 Well, (str :symbol)

20:46 this works, but probably isn't quite right: ;; Post with clj-apache-http...

20:46 (http/post "http://twitter.com/statuses/update.json"

20:46 :query (merge credentials

20:46 {:status "posting from #clojure with #oauth"})

20:46 haha

20:46 Sorry

20:46 ihodes: ,(name :k)

20:46 clojurebot: "k"

20:46 seangrove: Thanks ihodes

20:46 ihodes: no problem

20:46 seangrove: I had (str-join "" (rest (str :symbol)))

20:47 hiredman: :symbol is not a symbol

20:47 ihodes: it's a keyword seangrove

20:48 which is a glorified string

20:48 seangrove: Ah, sorry

20:48 ihodes: which has some nice attributes

20:48 no need to be sorry!

20:48 seangrove: 'symbol ?

20:48 wwmorgan: 'symbol is a symbol

20:48 seangrove: Heh, got it

20:48 ihodes: well, not quite, right? ' is a symbol

20:49 and so is symbol

20:49 wwmorgan: ,[(class 'symbol) (class symbol)]

20:49 clojurebot: [clojure.lang.Symbol clojure.core$symbol]

20:49 ihodes: yeah true just check in my repl

20:50 fsmunoz: ihodes: I'm doing swing stuff, cold you perhaps explain the invokeLater comment above?

20:50 seangrove: Thanks guys, appreciate it

20:50 fsmunoz: I'm not using the contrib stuff for now, still getting a hold of it first without any macros.

20:51 ihodes: fsmunoz: sure thing. it calls the swing app in its own thread, the EDT (event dispatch thread), which is where swing needs to run to run properly, basically

20:52 ssideris: fsmunoz: you pass a runnable object to invokeLater

20:52 fsmunoz: ihodes: thanks. Wasn't there something called "do-swing" that did something similar?

20:52 ssideris: and it makes sure it's invoked in the EDT

20:53 ihodes: fsmunoz: i'm not sure! if so, that wouldn've been nice. i wrote my own little macro instead to wrap my main swing fn

20:53 fsmunoz: ihodes: yeah,I think I saw that one in the contrib section. Probably something most people end up doing.

20:53 I still haven't though

20:54 ssideris: something like (invokeLater (mytest)), instead of (mytest) - in which mytest returns a JFrame?

20:54 I'll read the docs instead of pestering you though

20:55 ssideris: fsmunoz: hm, not exaclty... in java at least, *any* changes to GUI objects have to be performed in the EDT

20:55 so if you add data to tables

20:55 fsmunoz: ouch

20:55 ssideris: change the strings in textboxes etc

20:55 not sure what facilities clojure has for making this easier

20:56 fsmunoz: ssideris: I see.

20:56 Perhaps this: http://richhickey.github.com/clojure-contrib/swing-utils-api.html#clojure.contrib.swing-utils/do-swing

20:56 I think it is meant to wrap any swing code.

20:57 ssideris: fsmunoz: yes, it sounds like it does exactly what i described

20:57 the equivalent java code is *much* more verbose

20:57 fsmunoz: I can imagine

20:57 ihodes: yeah that's essentially my macro there

20:58 fsmunoz: check out stuartsierra's series on swing in clojure

20:58 http://stuartsierra.com/2010/01/06/heating-up-clojure-swing

20:58 fsmunoz: Oh, right, I've read that

20:58 ihodes: that should help

20:58 fsmunoz: ihodes: it did (and does)

20:58 ssideris: fsmunoz: I also liked this: http://blog.licenser.net/2010/05/11/the-ease-of-guis

20:59 fsmunoz: I'm perhaps spreading a bit to thin, as it were, since I'm learning Clojure, new to functional programming, don't really know Java or Swing.

20:59 ihodes: nah, you should be okay.

20:59 what kind of stuff are you trying to do?

20:59 fsmunoz: Which makes it all an exercise in searching. But in a nice way

21:00 ihodes: oh, hobbyist stuff, experiments, etc. The final goal is theoretically to make a small game I have in mind, purely for personal entertainment

21:00 ihodes: but at least I'm getting results, which is nice and motivating.

21:01 ihodes: i'd recommend trying out the examples stuart has in his posts, and using the macros he supplies. then you can expand, and look into the J-classes, like JTextField, JLabel etc, and add them into your projects. look into refs and add-watch, so you can create a responsive and manageable GUI with sort-of state

21:01 ssideris: ihodes: do you know what the documentation means when it says that add-watch is "subject to change"?

21:01 fsmunoz: Plus, I've found that using the JVM has some hidden beneficts I hadn't thought about, like being able to put my experiments in an applet or via webstart for friends to see. Rather nice.

21:02 dnolen: fsmunoz: what do you language do you normally code in?

21:02 ssideris: write once erm... run anywhere!

21:02 ihodes: you can also make things easier on yourself by wrapping some common things, like (swing-button "The Name" true) and (set-text c) etc

21:02 ssideris: yes? what do you mean?

21:02 fsmunoz: dnolen: Common Lisp, mostly

21:03 dnolen: but never GUI stuff, in any event

21:03 ssideris: ihodes: have you heard what the plan is? will the interface change, or will it be removed as a feature or what

21:03 fsmunoz: Oh, and some Objective-C, that made the Java documentation much easier to swallow

21:03 dnolen: fsmunoz: CL, then not *totally* new to fp :)

21:03 ihodes: ssideris: i have no idea! i hope its not going anywhere, as i've used it extensively in the app i wrote this summer for the lab i was interning at

21:03 fsmunoz: dnolen: no, true.

21:03 ihodes: it was very useful

21:04 ssideris: yeah, i can imagine... it must be very valuable for swing programming too

21:04 fsmunoz: dnolen: I meant it mostly regarding the imutable data structures, while in CL I would make "pure" functions I would still let* variables, including changing them, etc.

21:05 ihodes: it really was. if i'd had the time, i probably could've made the swing program look almost functional. though the EDT would've been a bit difficult to manage, i guess.

21:08 ssideris: fsmunoz: another common pattern in swing is that you'd like to run something in a new thread and then have the gui do something when this background job finishes (like display a message). For this, you can use SwingWorker

21:08 (not sure what the idiomatic clojure is for those cases)

21:09 ihodes: you could treat it like a future

21:11 fsmunoz: ssideris: I still haven't reached that stage, but I will shortly. Thanks for the pointer, will investigate SwingWorker. IIRC in Objective.C I do something involving -detachingNewThreadSelector and notifications. Mayve something similar happens in Swing - or mayve it's completely different.

21:12 slyrus: can one :use multiple packages :as the same name, getting the union of the packages symbols?

21:13 hiredman: I sure hope not

21:13 ihodes: slyrus: you cannot

21:14 though if you really wanted to, you could make that happen with your own macro and the ns family of functions

21:14 i *think*

21:16 slyrus: hiredman: why not? It's equivalent to :use'ing multiple packages, but just putting them behind some sort of alias to the packages

21:17 I'm still struggling with the best way to export my libraries API after refactoring things into multiple files. my core.clj has the protocols and their methods, but it isn't until the implementation defrecords get defined that their "constructors" (e.g. make-foo) get defined. I'd like to "export" those from the core ns, but I'm not quite sure how/if to do that

21:21 tomoj: what do you mean "export"?

21:28 slyrus: I have things in get defined in foo/moose and foo/bar that I would like to be made available to other folks by use'ing foo/core

21:28 s/things in/things that/

21:29 tomoj: I don't think there's any good way to do that

21:29 compojure used to use an immigrate thingy but it turned out to be evil

21:29 ihodes: tomoj: slyrus: haskell makes that easy, but it also makes it easy to pollute your namespace

21:29 slyrus: I guess the first question is "is that a good thing to want to do?"

21:30 right, and CL's package system lets you do this too

21:30 ihodes: slyrus: i don't think so: it's gnerally better to say EXACTLY what you're getting, when you "use" something

21:30 and for the people using your API, it might be surprising to get things from other namespaces when they just want to ue X namespace

21:30 use*

21:30 slyrus: I'd rather say EXACTLY what the provider of foo/core wants me to use and not have to know what that actually is

21:31 tomoj: aren't you the provider of foo.core?

21:31 slyrus: yes

21:31 ihodes: yeah, i'm confused now

21:31 tomoj: so just tell people to use foo.mouse and foo.bar instead of telling them to use foo.core...?

21:31 ihodes: could you describe a situation where this might be problematic? tomoj: that's what i'm thinking

21:32 tomoj: http://groups.google.com/group/compojure/browse_thread/thread/400aac94e536e633

21:32 slyrus: if folks just :use the packages, it's really not a problem. If the require :as ... the packages, it's still not _really_ a problem, it's just a little bit of an inconvience

21:32 tomoj: oh, I see

21:32 slyrus: the specific case is that i used to have make-atom and make-molecule, e.g. in chemiclj/core

21:33 then I refactored the tree, s.t. now one has to do atom/make-atom and molecule/make-atom

21:33 molecule/make-molecule, I mean

21:33 tomoj: right, shucks

21:33 slyrus: I'd rather have both of these available as chem/make-atom and chem/make-molecule

21:34 ihodes: i suppose you could 1) alias the functions you want in core 2) :use xxx :only the things you want 3) implement something like what Vagif suggested at the end of the linked thread

21:34 (would aliasing them work?)

21:34 dnolen: slyrus: I think the thing to do then is the to import the symbols by hand into a namespace you want people to actually use. penumbra does this.

21:35 your project may have many namespaces, many which are not intended for public consumption.

21:35 slyrus: ihodes: I was just thinking about trying to ... turn defalias on its head

21:35 dnolen: ok, thanks, I'll look at how penumbra does it.

21:35 like I was starting to say earlier, there are two questions, 1) is this reasonable and 2) if so, how to do it?

21:35 I'm still on question 1 :)

21:36 ssideris: how about defn-

21:36 ihodes: for your use case, it sounds reasonable, as long as you make sure the user can keep his namespace clean!

21:36 ssideris: ,(doc defn-)

21:36 clojurebot: "([name & decls]); same as defn, yielding non-public def"

21:37 ihodes: ssideris: i think defn- would defeat the purpose here: he's trying to make these functions available, not hide them

21:37 ssideris: sorry, I misread the above

21:37 ihodes: no problem! it's a bit confusing

21:39 * slyrus is a bit confused too :)

21:39 tomoj: aleph might have an example

21:39 ihodes: slyrus: would something like: (use-groups :particles) work, where it would intern the functions from their respective namespaces, depending on the group name. groups could be user-defined, and/or defined in your core.clj. you could also allow qualified uses e.g. (use-groups [:particles :as ps])

21:40 tomoj: aleph.import has a macro that aleph.core uses to pull a bunch of stuff in

21:40 hiredman: eww

21:40 slyrus: ihodes: I'm not sure I follow that.

21:41 (in-ns 'chemiclj.core) (d/defalias make-atom chemiclj.atom/make-atom)

21:41 at the end of atom.clj seems to do what I want

21:41 so maybe I just use defalias to "export" the "foreign" symbols I want from core and everyone's happy

21:41 nobody needs to know that make-atom isn't in chemiclj/core

21:42 dnolen: tomoj: no, it imports one definition, it doesn't pull a bunch of things in.

21:42 tomoj: eh?

21:42 dnolen: tomoj: http://github.com/ztellman/aleph/blob/master/src/aleph/import.clj

21:42 tomoj: yes, and aleph.core calls it 16 times

21:43 25 actually

21:43 dnolen: tomoj: yes, but he's has to write out by hand which fns he's going to bring in, and it carries over the important info.

21:43 hiredman: ugh

21:43 tomoj: indeed

21:43 hiredman: that is nasty

21:44 what is the point of that?

21:44 ihodes: hiredman: he explains above

21:44 tomoj: so that you can (:require [aleph.core :as aleph])

21:44 dnolen: hiredman: so consumers don't have list a bunch of namespaces, while his stuff stays organized.

21:44 hiredman: he's calling eval inside a macro

21:44 dnolen: well he failed

21:44 tomoj: and not (:require [[aleph [core :as acore] [foo :as afoo] [bar :as abar]]]) or whatever

21:44 slyrus: instead of (:require [aleph.foo :as aleph] [aleph.bar :as aleph])

21:44 bah

21:45 :)

21:45 dnolen: hiredman: yeah but eval is at compile time. big deal, I use that all the time.

21:45 hiredman: dnolen: just because you do it, doesn't make it good

21:45 somnium: 'definline calls eval from a macro, and its in (ahem) clojure.core

21:46 dnolen: hiredman: just because you think it's bad, doesn't make it bad ;)

21:46 slyrus: the obvious solution is that multiple :as foo's just accumulate the symbols in the packages their requiring :)

21:46 ihodes: http://gist.github.com/554539 just something like that?

21:46 hiredman: dnolen: yeah, it does

21:46 slyrus: s/their/they're/

21:46 dnolen: haha,

21:46 tomoj: slyrus: then you have to go dig through all those namespaces to find the var

21:46 M-. will probably still work fine though :)

21:46 ihodes: slyrus: i think that's a doable macro.

21:46 hiredman: (:use [aleph.foo :only [what-i-need]] [aleph.bar :only [other-thing-i-need]])

21:47 slyrus: hiredman: please stop presenting reasonable, logical solutions

21:47 ihodes: hiredman: we've done those. this is now bat country.

21:48 dnolen: hiredman: sure but that can get tedious, depending. my ring imports are always crazy. aleph provides a friendly interface, imho.

21:48 slyrus: what dnolen said

21:48 tomoj: maybe new ns will help someday

21:49 slyrus: for the time being, the in-ns core / defalias combo seems to do what I want

21:49 ihodes: slyrus: you can do your "union of all the ns's under the :as name" idea, but the way I'm envisioning it is a hellish nightmare. though, i could be useful for sure.

21:49 hiredman: dnolen: a friendly interface is by no means evidence of correctness, it is only evidence of a friendly interface

21:50 dnolen: hiredman: well what do you consider the problem? what is incorrect?

21:50 tomoj: exactly, and the question is, can we have a correct friendly interface?

21:50 slyrus: friendliness is easier to judge than correctness

21:50 and probably much easier to achieve

21:50 dnolen: a package macro would be nice, something that is official for collecting defns into a namespace for friendly interfacing.

21:51 slyrus: anyway, thanks y'all for helping me think this through

21:51 hiredman: dnolen: that is very possible without any migration of stuff across namespaces

21:52 dnolen: hiredman: I still haven't heard a good reason why migration is bad? I'm ok with taking your side, if you have some case where it causes trouble.

21:53 hiredman: I don't have one at hand because I don't use code that does it, but I could manufacture a few

21:54 dnolen: hiredman: I'd like see something :)

21:54 hiredman: ok

21:54 ihodes: hiredman: me too, i'm rather curious

21:55 tomoj: there's the binding problem in the thread above

21:59 hiredman: actually, I think tomoj is right, that thread explains it pretty well

22:00 clojure's compiler, the binding behaviour of Vars, etc all assume that def'ed vars (and the functions they hold) live where they live

22:02 dnolen: hireman: huh, I suppose that's why the ztellman only doesn't import fn

22:02 rebinding a fn seems wack

22:02 only uses import-fn I mean

22:02 hiredman: ztellman?

22:03 dnolen: aleph author

22:04 hiredman: there are a lot of neet projects that are the authors first (and only) foray into clojure, they are rarely examples of good style

22:05 slyrus: (defmacro export [sym] `(d/defalias ~(symbol (name `~sym)) ~sym))

22:06 dnolen: heh, aleph is not a first foray, ztellman does penumbra, that's one of the larger clojure projects I've seen. his code is usually delightfully idiomatic.

22:06 but sure, migration of defs is something to be used sparingly or not all, I agree.

22:09 somnium: probably the source of clojurebot is one of the few examples of good style in the wild

22:09 ihodes: somnium: could you link to that, please?

22:10 ah, nevermind

22:10 hiredman: somnium: I doubt that

22:14 slyrus: hrm... "Can't create defs outside of current ns"

22:14 that seems a little harsh

22:14 I should be able to create a def wherever I want

22:14 somnium: slyrus: you can always intern

22:16 slyrus: somnium: that seems to work! thanks :)

22:16 dunno why you can intern but not defn then.

22:17 that seems like a rather petty restriction

22:17 hiredman: def is compile time, intern is runtime

22:17 ihodes: clojurebot: def alias

22:17 somnium: I tried to do something like ml-functors, like (mk-red-black-tree :as my-rbt my-comparator), then (my-rbt/empty) (my-rbt/create ...), but it was hard

22:17 ihodes: ,(doc alias)

22:17 clojurebot: "([alias namespace-sym]); Add an alias in the current namespace to another namespace. Arguments are two symbols: the alias to be used, and the symbolic name of the target namespace. Use :as in the ns macro in preference to calling this directly."

22:18 somnium: was able to do (create ns blah) (intern ...), then alias it, but something didn't work right

22:20 slyrus: ok, thanks hiredman

22:23 (defmacro defn* [fn-name body] `(intern 'chemiclj.core '~fn-name ~body))

22:23 * slyrus ducks

22:24 slyrus: oh, wait, I forget to put the (fn ... in the macro.

22:25 (defmacro defn* [fn-name args body] `(intern 'chemiclj.core '~fn-name (fn ~args ~body)))

22:28 * slyrus forgot about multiple arity, etc...

22:28 slyrus: back to the drawing board

22:31 wei_: how can I check where my logs are being written to?

22:34 slyrus: hiredman: still, compile or runtime, I don't see why Compiler.java can't just intern the sym in v.ns instead of currentNS

22:34 that's what intern does, might as well give folks the convenience of defn if you're going to give them the rope of intern

22:35 or am I missing something about how ns'es work?

22:37 somnium: slyrus: you can do variable arity with `fn'

22:38 ihodes: i'm curious if anyone knows the reasoning behind not allowing multiple dispatch with reifty, defrecord etc? i'm assuming for performance reasons, as performance was a motivating factor behind reify?

22:38 slyrus: somnium: oh, right

22:41 tomoj: ihodes: reify makes java stuff, java stuff doesn't do multiple dispatch

22:44 and performance, yeah

22:44 hotspot is good at single dispatch

22:46 slyrus: somnium: but I don't get access to the name of the function I'm defining inside of fn :(

22:47 wei_: hello

22:47 i have a quick question: I'm using the functions in clojure.contrib.logging, but I don't know where the output is going?

22:48 somnium: ,((fn dizzy ([] (dizzy))))

22:48 clojurebot: java.lang.StackOverflowError

22:48 wwmorgan: ,((fn this [x] (if (zero? x) 0 (this (dec x)))) 3) ; <- slyrus

22:48 clojurebot: 0

22:49 slyrus: oh, ok, thanks

22:51 I'll probably burn in hell for this, but this seems to work:

22:52 (defmacro defn* [fn-name & rest] `(intern 'chemiclj.core '~fn-name (fn ~fn-name ~@rest)))

22:53 somnium: I don't think the almighty weighs the irc's opinion of clojure style quite that heavily

22:53 (but you never know ...)

22:54 ihodes: tomoj: java can be made to do multiple-dispatchy stuff…but the performance reasons are a good enough argument for me–i was just wondering if there were other reasons. i could see it being useful

22:55 tomoj: making reified classes do multiple dispatch would be a terrible hack

22:55 rich tries to avoid those :)

22:56 ihodes: it would totally be awful haha

22:56 fair enough.

22:56 if it was totally needed and performance wasn't important, it wouldn't be too bad to implement it in Clojure, i think

22:56 but i could do that myself if necesary

23:09 tomoj: isn't it already, in multimethods? guess you'd have your reify functions call some multimethod on their args?

23:18 ihodes: tomoj: didn't even think of that; that'd work haha

Logging service provided by n01se.net