#clojure log - Sep 23 2009

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

0:00 hiredman: I don't see how that would require a useless parameter

0:00 mabes|away: how do I get the length of a list in clojure? (find-doc "length") isn't helpful.. Is length defined in some lib in clojure-contrib?

0:00 hiredman: ,(doc count)

0:00 clojurebot: "([coll]); Returns the number of items in the collection. (count nil) returns 0. Also works on strings, arrays, and Java Collections and Maps"

0:00 killy971: mabes|away: > count

0:01 mabes: ok.. coming from scheme so I expected length. thanks :)

0:01 killy971: hiredman: do you know project euler?

0:01 hiredman: I am aware of it

0:01 killy971: problem 214

0:02 hiredman: I think it would help if you explained what you mean by dynamic programming first

0:02 killy971: it is basically about computing phi, and phi again on the result of primes upto to a certain limit

0:02 so

0:02 I have a function which compute the length of a chain

0:03 hiredman: ~euler

0:03 clojurebot: euler is http://clojure-euler.wikispaces.com/

0:03 mabes: what is the general rule for deciding to use a vector vs. a list in clojure? In my case I'm dealing with integers.. is a vector a better fit for that and why?

0:03 hiredman: it might help you to get a feel for clojure code if you looked over some of the solutions there

0:03 killy971: then, I would like to check if the chain length for a certain number has already been computed

0:04 hiredman: mabes: do you require fast indexed access? if so a vector, if not, a list

0:05 mabes: hiredman: ok, so if I'm just iterating over them then a list is the best fit. Thanks.

0:06 hiredman: killy971: sounds like a job for reduce

0:07 you have a map which is a cache, and you would like to reduce a list of numbers to entries in the cache

0:07 killy971: I see

0:08 I am going to try this

0:08 thanks

0:08 hiredman: conviently enough, reduce used in this fashion will work with or without transients

0:09 clojurebot: transient?

0:09 clojurebot: excusez-moi

0:10 hiredman: clojurebot: transients?

0:10 clojurebot: No entiendo

0:10 hiredman: clojurebot: transients is <reply>http://clojure.org/transients

0:10 clojurebot: Ack. Ack.

0:16 technomancy: killy971: you shouldn't be using transients unless you've already written a non-transient version of the same code, profiled it, and found it to be a bottleneck

0:16 hiredman:

0:16 killy971: well, I was trying it for the first time as it seemed convenient...

0:16 but I know I shouldn't use this

0:17 in the first place

0:33 mabes: when I want to define a helper function in another function is the best way to do so is with let? (this is what I did: http://github.com/bmabey/sicp-study/commit/1306fe6a76968e28bbd36df5e79e0edf56ee7696)

1:10 wooby: hello, i'm new and looking for cool web app clojure stuff... i saw compojure, are there other projects of note?

1:12 mikem: wooby: there's also conjure: http://github.com/macourtney/Conjure

1:12 wooby: mikem: thanks i'll check it out

1:14 oh, i'm in the middle of that guy's book

1:14 err nevermind

1:45 dnolen: is there a way to say that an fn is synchronized for a Java primitive parameter/object as you can for methods in java?

1:51 cgrand: ~locking

1:51 clojurebot: No entiendo

1:51 cgrand: ,(doc locking)

1:51 clojurebot: "([x & body]); Executes exprs in an implicit do, while holding the monitor of x. Will release the monitor of x in all circumstances."

1:51 cgrand: dnolen: that's the closer thiing I can think of

1:53 dnolen: cgrand: interesting! thanks, so that should work pretty much the same way?

1:56 cgrand: that's close enough. only one thread can enter that block of code. I guess synchronized syntax generates something pretty much like that.

2:16 licoresse: good morning europe

2:42 prospero_: ,(= (keyword "a") (keyword 'a))

2:42 clojurebot: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.lang.String

2:42 prospero_: hmm, that's not what I get at my repl

2:43 anyways, the above returns true for me, but (= (keyword "/") (keyword '/)) returns false

2:43 anyone know why?

2:45 hiredman: uh

2:45 keyword takes a string

2:45 prospero_: I dunno, I pulled from github a few days ago

2:46 it seems to not mind symbols

2:46 hiredman: I guess that changed

2:46 anyway '/ is treated somewhat special

2:47 I imagine it would not be allowed as a symbol at all (just as namespace seperator) if it wasn't for / as the division op

2:47 prospero_: right, I'm just trying to set up some rules for a DSL

2:48 and while it refuses to read :/, it will take (keyword '/)

2:48 hiredman: for good reason

2:48 in a keyword is a namespace seperator

2:49 ,:foo/bar

2:49 clojurebot: :foo/bar

2:49 prospero_: oh, ha

2:49 that makes sense

2:49 hiredman: ,(namespace :foo/bar)

2:49 clojurebot: "foo"

2:49 hiredman: is special, so it is best not to use it

2:49 er

2:49 / is special, so it is best not to use it

2:50 (my irc client ate / the first time)

2:50 prospero_: like I said, it's for a DSL, so I don't have much choice, unless I don't allow division

2:50 hiredman: div

2:50 prospero_: every other arithmetic operator is a symbol

2:50 hiredman: :\

2:50 ,:\

2:50 clojurebot: Invalid token: :

2:50 hiredman: anyway, those are the breaks

2:51 prospero_: well, doing (keyword '/) seems to work fine

2:51 is that going to change?

2:51 am I just lucking into some implementation detail?

2:51 hiredman: ~search ticket keyword validation

2:51 clojurebot: No entiendo

2:51 hiredman: ~ticket search keyword validation

2:51 clojurebot: ("#6: GC Issue 1:\t:validator as keyword arg for ref/atom/agent" "#17: GC Issue 13:\tvalidate in (keyword s) and (symbol s)")

2:51 hiredman: ~ticket #17

2:52 clojurebot: {:url http://tinyurl.com/nq6ef7, :summary "GC Issue 13: validate in (keyword s) and (symbol s)", :status :test, :priority :low, :created-on "2009-06-17T18:56:26+00:00"}

2:52 prospero_: so basically if :/ doesn't fly, neither should (keyword '/)

2:53 is that what you're saying?

2:53 hiredman: yep

2:54 prospero_: I'm confused, though. It looks like the fix for this issue was already submitted

2:54 so why is my workaround still working?

2:55 hiredman: there is a patch for testing

2:55 prospero_: which hasn't been merged yet

2:55 ok

2:58 sfuentes: question: as i'm here trying to learn clojure I get the feeling that I'm writing code in clojure but not necessarily functional code. My gut instincts is to remind myself to try to use map and reduce as often as possible. Is there a better approach to trying to learn functional programming?

2:59 hiredman: practice practice practice

2:59 sfuentes: i imagine that there is more to functional programming than just map and reduce

3:00 hiredman: well, use and write functions

3:01 arbscht: there are book, if you're into that sort of thing

3:01 books

3:05 sfuentes: ok so here's my naive plan: code, code, read more about FP, code, code some more, read other ppls code, code, code ... etc

3:06 Raynes: A good way to learn functional programming, if you find it impossible to grasp it otherwise, is to learn Haskell. You'll walk away from Haskell all starry-eyed, and you'll be a new man. Clojure will look like a golden halo floating just inches above the top of a redwood stand waiting for you to pick it up and place it upon thy skull.

3:06 * Raynes stops being overly dramatic.

3:06 Raynes: One ring to rule them all...

3:07 arbscht: morning LauJensen

3:07 Raynes: :D

3:07 * Raynes goes to sleep.

3:08 sfuentes: Well I did consider learning Haskell ... but I questioned how practical it would be.

3:10 arbscht: it's quite practical. however I don't see why you might not just learn clojure. you'll face similar challenges learning functional patterns in both systems

3:10 Fossi: it's a bit like learning lisp, no matter what language you code, it will teach you some

3:10 yason: sfuentes: in Clojure you'll generally find yourself having to do more work if you want to stay out of functional style

3:11 LauJensen: Morning arbscht :)

3:11 (and the (rest #clojure))

3:11 yason: sfuentes: nevertheless, there's no best way to learn functional programming: you'll get it eventually, one way or another, as long as you delve into it

3:12 LauJensen: yason: that statement is probably wrong - we just have worked out the best way yet :)

3:13 yason: LauJensen: there's probably always a best way for one person, but nothing that caters for everyone

3:13 LauJensen: not until humanity turns into a horde of similarly wired clones, anyway :)

3:13 LauJensen: like I said, we're working on it :)

3:14 crios: hello. I think a good way to learn functional programming is to read the source code written by their power users, so that one can also study the "best practices" suited for that language

3:14 LauJensen: True, thats a good way to go

3:15 crios: therefore, I'm in search of a good code base. Do you suggest anything in particular, on "clojure-contrib" perhaps?

3:16 sfuentes: yeah, good examples of functional code would help

3:16 LauJensen: ~def println

3:16 sfuentes: cause i feel like i don't know what i'm doing

3:16 LauJensen: sfuentes: Read that file, it's called core.clj, lots of good stuff :)

3:16 sfuentes: will do

3:17 its like i hear ppl talking about orgasms and not having experienced one

3:17 LauJensen: ...

3:17 yason: crios: I somehow "got it" when writing C... I had been toying with Emacs Lisp for years but finally realized that if I pretty much inline everything instead of using variables, recompute them, and pass them as variables, then my C code actually looks like the code I had been writing in ELisp... :)

3:19 crios_: clojurebot: logs?

3:19 clojurebot: logs is http://clojure-log.n01se.net/

3:20 crios_: [come back from a Firefox crash]

3:21 mmm in the history I don't see the last sentences

3:21 could you re-copy the url?

3:21 Fossi: ~def println

3:22 it's just core.clj

3:22 "just"

3:22 crios_: :)

3:22 pixelman: I'm looking for a good and clean way to replace keys in a string in clojure from a map, like "hello $bar" {:bar "world"}

3:23 crios_: ~def identity

3:24 ~def

3:24 clojurebot: defmulti doc is ugly

3:24 crios_: just trying "~def"

3:27 LauJensen: ,(reduce #(.replace %1 (name (key %2)) (val %2)) "foo $bar baz" {:$bar "baz" :baz "bar"})

3:27 clojurebot: "foo bar bar"

3:31 LauJensen: pixelman: Clean ?

3:32 pixelman: LauJensen: thanks! I it's clean :)

3:33 LauJensen: np

3:36 crios_: anyone here use VI on Linux?

3:37 links on how enable clojure support?

3:38 LauJensen: crios_: Its quite easy "sudo apt-get purge vi* && sudo apt-get install emacs-snapshot && git clone git://technomanchy/clojure-mode"

3:39 crios_: emacs?

3:39 arbscht: crios_: I think this is a usable solution http://kotka.de/projects/chimp.html

3:40 crios_: ok, I'll give it a try , thank you

3:40 hiredman: ~vimclojure

3:40 clojurebot: vimclojure is state-of-the-art

3:40 hiredman: ~google vimclojure

3:40 clojurebot: First, out of 245 results is:

3:41 Kotka : Projects : Clojure : VimClojure

3:41 http://kotka.de/projects/clojure/vimclojure.html

3:41 arbscht: ah that's the one

3:41 hiredman: chimp is superseded

3:41 * arbscht knew it was on kotka.de somewhere

3:41 crios_: ok, let's go with vimclojure :)

3:49 LauJensen: I can't find the *agent* thing documented anywhere, why is that ?

3:56 arbscht: http://clojure.org/api#toc9

3:57 LauJensen: arbscht: thanks

4:22 Does anybody have a really easy-to-follow beginners guide for emacs/slime?

4:23 arbscht: LauJensen: there is a builtin tutorial. hit C-h t

4:24 LauJensen: I meant for setting up slime though :) I wan't something for non-clojurians who read my blog, so they can get setup really quickly

4:26 tomoj: just found this http://acidrayne.net/?p=39

4:26 if you use the emacs-starter-kit it's really easy

4:26 arbscht: LauJensen: oh, I believe it's as simple as M-x clojure-install, once clojure-mode.el is installed

4:26 LauJensen: Great, thanks

4:26 Ok, even better

4:26 tomoj: yeah, clojure-install is easier than the manual thing I linked to

4:27 arbscht: LauJensen: http://technomancy.us/126

4:31 LauJensen: arbscht: great, really clear and easy to follow, thanks

4:47 sfuentes: what does & in an argument vector mean?

4:49 arbscht: sfuentes: the remaining arguments

4:49 ,((fn [a & more] [a more]) 1 2 3 4)

4:49 clojurebot: [1 (2 3 4)]

4:51 sfuentes: i see. thank you.

5:03 simplechat: heyyas

5:05 Chousuke: hi

5:06 simplechat: just as a question, on debian say, what would be the easiest way to set up a useful clojure environment?

5:12 LauJensen: simplechat: http://technomancy.us/126

5:19 crios_: I'm wondering how burden it is installing vimclojure. Recompile clojure-contrib, use ANT to get the vimclojure jar, start a ng-server server, and finally tell VI to use that NailgunClient!

5:19 Just thinking it was a joke :D!

5:20 so I must checkout the "contrib" source

5:20 can I "svn" it?

5:21 Or should I use just git?

5:21 LauJensen: hehe

5:21 You should use Git for any and all SCM purposes, especially however, Git repositories

5:21 djpowell: the new ->> is nice

5:22 crios_: lol. So in order to configure vi I have to install git, too. ehehe. Ah, these programmers! ;)

5:23 LauJensen: (doc ->>)

5:23 clojurebot: I don't understand.

5:23 LauJensen: djpowell: ?

5:23 djpowell: it has just been added in git

5:23 it is like ->, but it threads the last parameter

5:24 so you can do (->> (range 1 7) (filter odd?) (map #(* 2 %)) )

5:24 LauJensen: ah ok

5:35 For those interested in concurrency http://www.dzone.com/links/concurrency_challenge_dining_philosophers.html

5:38 crios_: btw, LauJensen, why do you think I should ALWAYS use git?

5:40 LauJensen: crios_: Where SCMs are concerned I far prefer the distributed approach. Regarding implementations, Git is 1) Much more effecient, which gives a faster workflow, 2) Better integrated into Emacs (Magit/egg) 3) Has a few more tools (maybe not anymore though), like git bisect. 4) Branching is redundant in SVN/CVS but comes to great use in Git

5:40 Chousuke: redundant is not the right word. "pain" is better :P

5:41 LauJensen: hehe, true

5:41 crios_: regarding the fourth point it is difficult to not agree :)

5:41 Chousuke: git makes branching natural

5:42 crios_: It should be the real reason for which I would leave svn

5:45 this is my experience: suppose two branches, feature1 and feature2. I have to freeze a release, so a create a new branch release1, merging both. Then, when I'll have to merge that features in trunk (for example), I cannot merge release1 with trunk: I must restart the merge using feature1 and feature2 branches towards trunk!

5:45 [when using svn]

5:50 jdz: somebody's been using too much syntactic sugar

5:50 LauJensen: who?

5:50 jdz: (map #(agent %) (repeat 5 0)) => (map agent (repeat 5 0))

5:51 LauJensen: oooh :)

5:51 I got caught red handed didn't I ? :)

5:51 sgtarr: LauJensen: you're behind bestinclass?

5:51 * sgtarr landed on your blog accidentally

5:52 LauJensen: Yes

5:52 sgtarr: Basically, you're to blame that I'm now back to looking at Clojure instead of Scala ;)

5:52 LauJensen: Haha :) You read the concurrency post did you? :)

5:52 sgtarr: yep

5:52 LauJensen: Man I'm glad to hear that, welcome to :)

5:55 jdz: LauJensen: does the program work at all?

5:55 LauJensen: jdz: The dining philsophers? Yea it runs flawlessly

5:55 jdz: you use @forks in the code, although forks is just a sequence

5:56 LauJensen: lemme look, might be some cut'n'paste which got mangled

5:56 Good catch, thats version 0.1 code :)

5:57 I started with (ref {:1 true :2 true...} but went with n-refs after cgrand spanked me

5:58 jdz: also, there's something wrong with: I can pull id [id (dec id]

5:58 most probably missing paren before closing ]

6:00 i'd define a function fork-available? and then use that as the first parameter to every? in got-forks?

6:00 LauJensen: thats a weird sentence alltogether

6:00 jdz: You think that would make it more clear?

6:01 I went with this because got-fork? was a fun parody on 'got milk?' :)

6:01 jdz: well, that's good software practice if you later decide to represent forks differently

6:02 and i dislike #() sin-tax [with a little passion]

6:02 LauJensen: Man you get annoyed quickly

6:02 jdz: in general, #(= true (second %@)) in no way tells me what it's supposed to mean

6:03 hence the code is not readable

6:03 LauJensen: %@ is ugly, I've changed to (deref %)

6:03 jdz: and hard to grasp if i have to jump all over the program to look what my-forks returns, and then go looking what is in the forks sequence etc

6:04 changing to deref does not change the point

6:04 the code is not self-documenting

6:04 as opposed if you used the fork-free? predicate

6:04 just try reading the body of the function with my suggestion and your original version

6:05 Chousuke: isn't the (= true ...) a bit redundant? or is it possible to have values that are logically true but should return false with the test?

6:05 LauJensen: You have a point jdz, but I think code-length can itself add a factor of unclearness to the code. Generally ½ line abstractions are to be avoided I think

6:06 Chousuke: It's for new-comers

6:06 (which I think my site has 92% of)

6:06 jdz: LauJensen: see, Chousuke also has a point. and his objection is not related to the got-forks? function, but to fork-available?

6:07 LauJensen: I see that

6:12 Chousuke: I think you could make it a lot cleaner if your fork data structure was a map instead of a vector

6:13 LauJensen: a map of refs ?

6:13 jdz: and why is the fork vector in a ref when it's the second member that's changing?

6:13 i.e., the fork id never changes

6:13 LauJensen: yea thats redundant

6:15 Chousuke: if you had {:fork-id % :free? true}, then the controversial lambda would become #(:free? (deref %))

6:16 LauJensen: yea - I think I might need to release a 2.0 in a couple of days :) I built a model quickly and then added to it. To a degree this hasn't been ideal

6:46 hamza`: hey guys, which notation is prefered i use (new SomaClass) mostly but i see code using (SomeClass.) notation which one is more idiomatic?

6:47 LauJensen: last

6:47 hamza`: kk thx.

6:53 ambient: http://bitumenframework.blogspot.com/2009/09/benefits-of-using-clojure-lisp-in.html

6:54 btw, are rich hickey's jvm summit talks anywhere online?

7:04 y-combinator: Hello. What is the easiest way to convert Clojure hashmap to java.util.HashMap?

7:04 LauJensen: ambient: I wonder why it tarries

7:05 ambient: LauJensen not following you

7:06 LauJensen: ambient: I wonder why it's not up yet

7:06 ambient: yep

7:07 LauJensen: ,(java.util.HashMap. (hash-map :a 5))

7:07 clojurebot: #<HashMap {:a=5}>

7:08 LauJensen: y-combinator: I think that's as easy as it gets

7:10 y-combinator: LauJensen: thank you

7:10 LauJensen: np

7:32 AWizzArd: Anyone here who runs Compojure behind https?

7:32 LauJensen?

7:33 LauJensen: Yea, one of my applications is on https

7:33 AWizzArd: did you configure Jetty for that? Compojure ships its own jetty, and that is just a .jar file. No config files etc.

7:34 Or do you have an Apache on port 80 with ssl support which simply transparently proxies your request on a jetty on localhost?

7:38 LauJensen: Since it was for 2 clients we put an apache in front of it. Only one of 2 clients wanted https

7:38 Next time I'll opt for nginx though

7:38 crios_: does anoyone know what does it mean "clj_want_gorilla" when configuring vimclojure?

7:39 jdz: must be something every vim user knows :/

7:40 simplechat: So compojure is clojure for webapps?

7:40 AWizzArd: LauJensen: nginx for more simplicity in the setup?

7:40 LauJensen: yes, once you know what you're doing it takes 5 minutes to setup, and I have a hunch that it's more effecient

7:41 AWizzArd: simplechat: Compojure is a lib with which you can (easily) write webapps in Clojure.

7:41 LauJensen: simplechat: it's one way to go

7:41 simplechat: very cool :)

7:41 any nice tutorials?

7:41 LauJensen, any other good ones?

7:41 AWizzArd: there already are severals

7:41 simplechat: (that you'd recommend)

7:41 AWizzArd: tutorials

7:41 LauJensen: no :)

7:41 arbscht: beware many of the tutorials are now obsolete

7:41 simplechat: none that are worthy of recommendation?

7:42 LauJensen: simplechat: I looked at technomancys concourse git repo on Github, that's the only 'tutorial' I've had :)

7:43 ambient: does compojure have a remotely stable api yet?

7:44 arbscht: ambient: I think so

7:44 LauJensen: simplechat: They might exist, but Compojure is Rock solid and James Reeves (one of 2 core developers) does some amazing work, so I have no reason to look around

7:44 ambient: I think so, but you might want to ask on the group

7:44 ambient: it would be cool to try it but can't help thinking i'm wasting my time if i have to learn to do it in a completely another way later

7:44 ok

7:44 simplechat: very cool :)

7:44 LauJensen: ambient: I think the main function you'll be using (html [:h1 "My header"] [:p "My paragraph"]) isn't likely to change

7:45 simplechat: can you get a repl on the server?

7:45 arbscht: simplechat: certainly

7:45 LauJensen: Yep

7:45 simplechat: OMFG :)

7:45 arbscht, how?

7:45 arbscht: simplechat: as with CL, you may load swank into the server process

7:45 simplechat: swank?

7:46 arbscht: or you could launch the server in a screen session

7:46 clojurebot: swank-clojure

7:46 clojurebot: clojure is the bestest programming language available.

7:46 jdz: or just use eval to evaluate code from random people that will destroy your server

7:47 arbscht: http://github.com/jochu/swank-clojure

7:50 simplechat: hey arbscht i can imagine that would be absolutely awesome

7:50 so you code on your server, which is then running actual code which is web accessable?

7:51 LauJensen: Just thinking out loud - If you have a repl running on a live server system, it would be possible to through nmap to discover that and break in quite easily.

7:52 simplechat: LauJensen, well you'd secure it

7:52 arbscht: LauJensen: bind it to localhost and connect via an ssh tunnel

7:52 simplechat: you could do that, but preferably not on a production server :)

7:52 simplechat: like i have a VPN to my servers so i'd just only expose it via the vpn

7:52 arbscht, am i the only person who would call this profanity worthy?

7:52 LauJensen: arbscht: Yea something like that - All I'm saying is, don't let the door open

7:53 simplechat: LauJensen, note taken

7:53 LauJensen: simplechat: nothing is ever profanity worthy

7:53 ambient: a simple ssh shell wouldn't suffice?

7:53 simplechat: LauJensen, in the "This is [x]ing cool"

7:53 type of sense

7:53 assuming i can get it working

7:53 ambient: don't bind the repl to anything

7:53 simplechat: and learn emacs

8:05 Fossi: does proxy return a value even if the interface is defined void?

8:10 Chouser: calling any void Java method returns nil, whether it was defined by 'proxy' or not.

8:33 jowag: does anybody know what is the license on the clojure logo? Or is it trademarked?

8:36 Chouser: I don't think it's trademarked. rhickey generally gives permission for any use related to the Clojure language.

8:38 pixelman: hahaha the sound on this page http://java.ociweb.com/mark/clojure/

8:39 ambient: apple quicktime addon? no thanks :/

8:39 can't you just directly link to the midi file?

8:40 Chouser: midi?

8:40 there are links at the bottom of the page to the .mp3s

8:40 ambient: oh, it was some mp3's

8:40 i wonder what the qt stuff is for

8:41 pixelman: it autoplayed in my mac

8:41 ambient: heh, i miss the times when half of the personal web pages had some cheesy midi file playing in the background :p

8:42 Chouser: once I turned on JavaScript it autoplayed here on Ubuntu

8:42 ambient: well it's quicktime, so totem/mplayer/whatever might have it

8:42 but windows vista needs it to be manually installed

8:53 djpowell: Inspired by this: <http://www.rubyinside.com/hijack-get-a-live-irb-prompt-for-any-existing-ruby-process-2232.html>, I put together something similar for clojure. It takes a process id, and uses the Java 1.6 Attach API to start a clojure repl up in that process, and lets you type stuff into that repl. I'll have to remember to publish it somewhere if anyone's interested.

8:54 pixelman: awesome! I've been wanting to do that in clojure

8:54 eevar2: djpowell: how does it compare to swank?

8:54 swank-clojure, that is

9:00 simplechat: djpowell, i'm interested

9:02 pixelman: are closures thread safe?

9:04 Chousuke: pixelman: well, they're supposed to be immutable so... yes? :/

9:04 pixelman: each thread keeps it's own references?

9:05 Chousuke: what do you mean?

9:05 Chouser: djpowell: wow sounds amazing.

9:05 pixelman: I assume they are thread safe, I just try to understand how it is done

9:05 Chouser: a closure can certainly do thread-unsafe things

9:07 Chousuke: pixelman: the closure saves a references to the objects in the outer scope that you use within the closure. if the things are immutable, you can't have threading problems. :)

9:07 of course you can always capture a reference to something mutable

9:07 Chouser: or pass in a mutable thing

9:08 pixelman: ok!

9:08 but for each thread the arguments passed to the closure are the threads own?

9:08 Chouser: closures are independent of threads

9:09 pixelman: uh

9:09 Chouser: the arguments passed to a closure are whatever arguments you pass to it

9:10 crios_: ,(clojure.contrib.repl-utils/source cons)

9:10 clojurebot: java.lang.ClassNotFoundException: clojure.contrib.repl-utils

9:10 crios_: mm

9:10 Chouser: ~def cons

9:11 still not very helpful. cons just calls clojure.lang.RT/cons

9:11 crios_: whati is it "(fn* cons"

9:11 ?

9:11 fn* ?

9:11 Chouser: crios_: that's clojure code before most of clojure has been defined yet. :-)

9:11 simplechat: hey, i know this is probably stupid, but how do you implement a counter as a clojure?

9:12 Chouser: crios_: fn* is currently just like fn but without support for destructuring, :pre/:post, etc.

9:12 crios_: but that's an implementation detail. note that at that point in core.clj, not even 'defn' is defined yet.

9:13 crios_: thaks Chouser. Yes, I'm trying to "study" / read core.clj source code

9:13 maybe some more simple code base should be appropriate^

9:13 Chouser: simplechat: you want the closure to change some state each time it's called?

9:13 Chousuke: simplechat: depends on what you need to count

9:13 simplechat: a ref is good, or an atom

9:13 Chouser: crios_: reading core.clj can be quite instructive, just keep in mind that much of what it does early on can be done more easily later.

9:14 simplechat: Chouser, yep

9:14 Chousuke: simplechat: or in some cases, just a regular function parameter

9:14 simplechat: Chouser, just a number

9:14 Chousuke: simplechat: sure, but for what use? :)

9:14 crios_: ok Chouser

9:14 simplechat: Chouser, more information?

9:14 Chousuke: hm

9:15 simplechat: uh, Chousuke

9:15 Chouser: simplechat: if you want some mutable state, you need a reference object to hold that state. Like Chousuke said, an atom or ref would be a good choice.

9:15 Chousuke: simplechat: do you need a global counter for something or just count something within a loop?

9:16 pixelman: my question re closures is if something like this would be thread unsafe: (defn unsafe? [x] (fn [y] (let [z (+ 2 x)] (+ z y)))) i.e. having a let in a closure.

9:16 simplechat: Chouser, global counter

9:16 Chousuke: pixelman: no

9:17 pixelman: Chousuke: tnx

9:18 Chousuke: pixelman: unless x is mutable at least. which it won't be if it's a number

9:18 pixelman: but then I would have to wrap it in a transaction?

9:18 Chousuke: hm

9:19 I don't really know

9:19 something like (defn foo [a] (fn [x] (aset a 0 x))) would be unsafe

9:19 because a is mutable

9:19 but that's not really a closure problem

9:20 that's a problem with a being mutable :)

9:20 pixelman: :)

9:31 manic12: this could be a java question, or it might also have to do with clojure under slime, but how does one debug threads running other than the repl?

9:32 how does one even get a list of running threads for that matter?

9:34 crios: help on thi expression: (. clojure.lang.RT (cons x seq))

9:35 the second member (cons ...) should not be a method in clojure.lang.RT ?

9:35 Chouser: crios: same as (clojure.lang.RT/cons x seq)

9:36 crios: ah, ok, it is a static method

9:38 Chouser: yes

9:38 Chousuke: that's "old style" code though. don't imitate :)

9:39 crios: ok boss :)

9:42 manic12: anybody know of some good docs to look at for basic threading stuff?

9:45 crios: manic12, mabye on Sun's site

9:45 http://java.sun.com/docs/books/tutorial/essential/concurrency/

9:46 manic12: thanks

9:47 crios: when one should use the ":arglists" metadata when defining a new function?

9:48 Chousuke: it's a documentation thing

9:48 (doc defn)

9:48 clojurebot: "([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata"

9:48 Chousuke: you can make it look like that if you want

9:48 Fossi: confusing?

9:50 crios: that documentation hint is used by automatic doc-gen tools? Why should be not enough to parse the content of [ ] ?

9:52 Chousuke: well, :arglists defaults to the argument vectors :P

9:52 but you can override it if you want to be more specific

9:53 jdz: crios: if you look at the definition of defn you'll see none of the arglists mentioned in documentation

9:53 crios: that is if I just want rename a paramter?

9:53 yes jdz

9:54 jdz: in case of defn it does a bit of argument processing (restructuring if you will)

9:54 so it has only one named (positional) parameter

9:54 the rest are picked out automagically

9:56 crios: so defn add :arglists metadata automatically, picking that information from the input parameters. If I want, I can override that behaviour with my own names

9:57 jdz: no, it does not add anything automatically.

9:58 :arglists is provided by the author of the definiton

9:58 definition even

9:58 crios: mmm so why Chousuke say ":arglists defaults to the argument vectors" ?

10:00 jdz: because that's true :)

10:00 i was a bit confused about your question. your conclusion was right in this sense.

10:02 it's not "overriding behaviours", but just providing data manually...

10:02 crios: do all function have an arglists metadata?

10:03 jdz: it would be a nice exercise for you to write a function that finds that out

10:05 crios: mmm a function which get a function name as parameter, then search for that metadata?

10:06 tmountain: you can walk through a namespace to determine what functions are available

10:06 jdz: you can get all vars in the namespace, you can determine if the value of a var is a function, you can get the metadata, etc

10:06 you have all the tools

10:10 crios: wait. I know that not all functions are declared with :arglists. But when they are evaluated/compiled at runtime, that metadata is not added automatically?

10:11 btw, the private function 'sigs' have no arglists declared

10:15 RomanRoe: why does (.getClassLoader java.util.Map) returns nil? Any other chance to get the classloader?

10:18 crios: maybe you should wrapp that with class

10:18 RomanRoe: (.getClassLoader (class java.util.Map)) => nil as well

10:32 hiredman: the javadoc for Class says some implementations may use null to represent the bootstrap classloader

10:41 RomanRoe: ah, thanks for pointing that out! I switched to (ClassLoader/getSystemClassLoader) which is correct for java.util.Map

10:53 tmountain: is the download link on clojure.org supposed to still point to code.google.com rather than github?

10:54 weissj: tmountain: i don't think github has builds on it, just source to build yourself. i could be wrong about that, but i think the current release really is on google code

10:55 tmountain: weissj: ok, just checking. for some reason I thought the whole project was moved to github.

10:55 weissj: tmountain: i know the discussion is still in google groups

10:56 arbscht: and issues are on assembla

10:56 tmountain: ok, I see what you guys are saying

10:56 hiredman: ~github

10:56 clojurebot: http://github.com/richhickey/clojure/tree/master

10:59 tmountain: I'm looking at core.clj right now. It's amazing how accessible it is in contrast to other language source I've perused.

11:18 Chouser: what's the name of that java lib that lets you create html/dom widgets in the browser?

11:20 cgrand: Chouser: the one that uses webkit?

11:20 Chouser: no, it runs in a web server and generates javascript and stuff

11:20 it had some generic-sounding name

11:21 cgrand: Chouser: ah sorry, I read your question too quickly

11:22 jwt?

11:23 http://www.webtoolkit.eu/jwt

11:23 Chouser: yes! perfect, thanks.

11:36 manic12: in java, to get a list of threads, you have to enumerate the root thread group recursively, passing it an array allocated with enough space for all the threads, however between the time you ask how many threads there are and call enumerate the number of threads could change, is there something wrong with this picture?

11:37 is there a without-interrupts in clojure, or better yet a function already written to list the threads?

11:37 Chouser: whoa

11:38 ,(keys (Thread/getAllStackTraces))

11:38 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission getStackTrace)

11:38 Chouser: bah. Anyway, that should produce something like what you want.

11:39 manic12: what happens if you type ,(System/exit 0) to clojurebot ?

11:40 stuartsierra: ,(System/exit 0)

11:40 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)

11:41 manic12: thanks guys

11:45 crios: ,(fn? #'read-line)

11:45 clojurebot: false

11:45 manic12: what I'd really like is if an exception were thrown in one of my window callback threads it would open and interactive clojure repl on that thread (with the ability to continue from that error of course)

11:45 crios: (fn? read-line)

11:45 ,(fn? read-line)

11:45 clojurebot: true

11:46 Chouser: ,(ifn? #'read-line)

11:46 clojurebot: true

11:46 crios: wow

11:46 Chouser: manic12: you must be a lisper

11:46 manic12: how else am I supposed to debug?

11:47 Chouser: manic12: It might not be impossible, but I think would require essentially writing a java debugger in clojure. could be fun!

11:47 manic12: poke at the black box until it spits something out

11:47 Chouser: manic12: many (most?) java debuggers work on clojure, like jswat.

11:48 manic12: so I should google jswat

11:48 Chouser: sure. or jdb which comes with the jvm

11:50 manic12: do you start clojure in the debugger or something?

11:51 Chouser: manic12: hm, I hardly ever use it. I think you can attach the debugger afterwards.

11:53 rhickey: manic12: if you start Clojure with the right flags you can attach a standard Java debugger at any point

11:53 http://clojure.org/getting_started

11:55 manic12: it is definitely a different experience vs Lisps which monitor their own evaluation

11:56 lisppaste8: crios pasted "untitled" at http://paste.lisp.org/display/87561

11:57 crios: well I tryied to write a function which parse all clojure.core vars

11:57 and get only the functions that don't have :arglists

11:57 could you give it a look?

11:57 Chouser: I guess java debuggers run in their own jvm and process, not in the same jvm process as the code they're debugging?

11:58 crios: 'ifn?' is true for every var

11:59 crios: btw, debuggers can attach to another process, but live into their own process

11:59 Chouser: crios: you'd need to deref the var and use 'fn?' or 'ifn?' on the result

12:00 crios: I was suspecting that. In fact, it was return *in* too

12:00 so deref..

12:00 do you mean (deref ?

12:01 Chouser: yup

12:02 crios: ,(fn? (deref #'read-line))

12:02 clojurebot: true

12:02 crios: ok

12:02 going to rewrite..

12:03 (meta does not need deref?

12:03 Chouser: nope, not even close. :-)

12:03 crios: mmm this is the trouble :)

12:06 lisppaste8: crios annotated #87561 "with deref" at http://paste.lisp.org/display/87561#1

12:06 crios: new version, but don't work: "java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IDeref"

12:06 Chouser: also note that the values of ns-map are not symbols but vars

12:07 oh

12:08 hm

12:08 crios: so do you mean that I cannot deref it?

12:08 Chouser: no, that's not what I mean. I just mean my-symb is misnamed. my-var would be more accurate

12:10 crios: ok. but with this version I get an Exception: java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IDeref

12:10 just trying to understand it

12:10 Chouser: hm, actually ns-map also has values that are not vars: imported classes are included

12:10 maybe try ns-publics instead of ns-map

12:11 crios: with ns-publics: java.lang.IllegalStateException: Var clojure.core/unquote-splicing is unbound.

12:12 Chouser: yeah, not all vars have values. :-)

12:13 so ... once all the bugs are fixed, I'm getting an empty seq.

12:15 crios: what vars have no value?

12:15 Chouser: (def foo)

12:15 ones like that

12:15 crios: sure

12:15 mm

12:16 hiredman: this is why using for can get messy

12:16 Chouser: ,(filter #(and (.isBound %) (fn? @%) (not (:arglists (meta %)))) (vals (ns-publics 'clojure.core)))

12:16 clojurebot: ()

12:16 hiredman: instead of chains of maps and filters and takes

12:16 crios: so a "best practice" would be avoiding (for ?

12:17 Chouser: I don't see how 'for' is any worse in this case.

12:17 a little wordier, perhaps, since this is really just a single filter.

12:18 hiredman: Chouser: if you write something like (-> x ((partial map fn)) ((partial filter fn1)) ...) it is much easier to swap stages in and out

12:20 Chouser: hmmm

12:22 crios: in my example using the for, how could I use isBound?

12:22 is it an instance method of Var?

12:22 Chouser: just add :when (.isBound my-var)

12:22 yes

12:23 crios: thanks

12:23 going to rewrite

12:26 lisppaste8: crios annotated #87561 ""bound" check" at http://paste.lisp.org/display/87561#2

12:26 crios: ok now works

12:27 querying ns-interns returns just a function

12:31 Chouser: ah, 'sigs'? that appears to be a private var

12:39 crios: yes, sigs

12:40 so all the functions have arglists.

12:40 still I cannot understand why :D

12:46 hiredman: eh?

12:46 fn objects don't have arglist metadata

12:47 ~ticket search Fn metadata

12:47 clojurebot: ("#140: Single :tag for type hints conflates value's type with type of return value from an invoke" "#12: GC Issue 8:\t:default as keyword arg to defmulti")

12:47 hiredman: bah

12:47 ~ticket search fn metadata

12:47 clojurebot: well?

12:47 clojurebot: ("#140: Single :tag for type hints conflates value's type with type of return value from an invoke" "#12: GC Issue 8:\t:default as keyword arg to defmulti")

12:47 No entiendo

12:47 hiredman: ~ticket search metadata on fns

12:47 clojurebot: ("#94: GC Issue 90: \t Support metadata on fns")

12:48 hiredman: ~ticket #94

12:48 clojurebot: {:url http://tinyurl.com/mgjunh, :summary "GC Issue 90: Support metadata on fns", :status :new, :priority :normal, :created-on "2009-06-17T20:43:34+00:00"}

12:48 hiredman: any arg list metadata comes from the vars that hold the functions

12:51 crios: I understand your point: you say that the metadata is owned by a Var, not by a IFn

12:55 hiredman: owned?

12:55 I guess

12:55 lisppaste8: crios annotated #87561 "the metadata is in the Var, not in the function" at http://paste.lisp.org/display/87561#3

13:01 crios: so this was the reason of why the Var needed a defer in order to pass its value (a function) to (fn? ); whereas the (meta does not need a defer, because it was applying on the Var itself

13:02 hiredman: yes

13:03 crios: wow. this is the most important day of my life!

13:03 eheh

13:18 * Raynes marvels at the obvious increase in the number of people in this channel.

13:18 savanni: When did the increase happen? I contributed myself to it last night.

13:19 Chouser: ~max

13:19 clojurebot: max people is 176

13:19 Chouser: that's holding steady, isn't it?

13:19 Raynes: I don't know. I just happened to notice that there is like 40 more people than usual in here.

13:19 I've not looked the channel number in quite a while, but it's not been that long.

13:19 Chouser: AWizzArd's been saying we should expect it as schools start up again

13:20 Raynes: Good point.

13:37 slyrus_: perhaps other #lispers came over after seeing rhickey's boston video

13:38 Chouser: was there a recent boston video?

13:38 I thought the most recent was JVM language summit. I assumed that was in California.

13:39 savanni: "Functional Programming with Clojure"?

13:39 Oh, nm, that's by someone else.

13:42 hiredman: did the video from the semantic web thing ever get put up?

13:49 slyrus_: Chouser: http://clojure.blip.tv/file/1313398/

13:50 technomancy: savanni: that was me. =)

13:50 savanni: Cool!

13:51 Chouser: slyrus_: ah, that one. I think that's from late last year.

13:51 But on the internet, content lives forever!

13:52 savanni: Thanks for the link.

14:06 mccraig: liebke: i'm getting a missing dependency on jung on incanter/master

14:09 liebke: jung?!

14:09 wow

14:10 I removed that dependency a long long time ago, let me see if I can figure out the problem

14:10 mccraig: yeah, graphs.clj imports a load of jung classes as far as i can see

14:10 hmm

14:10 liebke: ah, I thought I removed graphs.clj...

14:11 mccraig: ah, hold on... i should be using charts.clj

14:11 liebke: nope, it's still there... I'll remove it from the distribution

14:11 mccraig: doh :)

14:11 liebke: :)

14:11 I still need to remove graphs.clj, thanks for pointing that out :)

14:12 mccraig: yr welcome

14:13 have you considered splitting core, so that it doesn't initialise swing ? would perhaps make it a bit friendlier for backend use

14:15 liebke: yes, I think that's due to a single reference I have to a Processing class. I would like to fix that.

14:18 mccraig: cool. am playing around with incanter while i find my away around some bayesian inference stuff. was very happy to find it. thanks !

14:18 liebke: you're welcome, I hope you find it useful

14:55 wwmorgan: (= (float 0.5) (double 0.5)) returns true, but (= (float 0.55) (double 0.55)) returns false

14:57 Licenser_: wwmorgan: I am pretty sure that this is related with the way float and double rounds

14:58 hiredman: ,(float 0.5)

14:58 clojurebot: 0.5

14:58 hiredman: ,(float 0.55)

14:58 clojurebot: 0.55

14:58 hiredman: ,(double 0.55)

14:58 clojurebot: 0.55

15:00 Chouser: ,(== (float 0.55) (double 0.55))

15:00 clojurebot: false

15:00 Chouser: ,(== (Float 0.55) (Double 0.55))

15:01 clojurebot: java.lang.RuntimeException: java.lang.Exception: Expecting var, but Float is mapped to class java.lang.Float

15:01 Chouser: ,(== (Float. 0.55) (Double. 0.55))

15:01 clojurebot: false

15:01 Chouser: that seems rather unfortunate

15:02 durka42: ,(.floatToIntBits (float 0.55))

15:02 clojurebot: java.lang.IllegalArgumentException: No matching field found: floatToIntBits for class java.lang.Float

15:02 stuartsierra: ,(= (Float. 0.55) (Double. 0.55))

15:02 clojurebot: false

15:02 durka42: ,(.floatToIntBits (Float 0.55))

15:02 clojurebot: java.lang.RuntimeException: java.lang.Exception: Expecting var, but Float is mapped to class java.lang.Float

15:02 durka42: bah

15:02 ,(.floatToIntBits (Float. 0.55))

15:02 clojurebot: java.lang.IllegalArgumentException: No matching field found: floatToIntBits for class java.lang.Float

15:03 hiredman: every day for about an hour #scala turns into ".equals sucks, what can be done to fix it, omg the cure is worse then the disease"

15:03 durka42: but, but

15:03 it's right here http://www.j2ee.me/j2se/1.4.2/docs/api/java/lang/Float.html#floatToIntBits(float)

15:03 Chouser: ,(Float/floatToIntBits 0.55)

15:03 clojurebot: 1057803469

15:03 durka42: oh, duh

15:03 ,(Double/doubleToLongBits 0.55)

15:03 clojurebot: 4603129179135383962

15:03 wwmorgan: ,(.doubleValue (float 0.55))

15:03 clojurebot: 0.550000011920929

15:03 stuartsierra: there's your answer

15:04 wwmorgan: any suggestions?

15:04 durka42: use an epsilon to compare floating point numbers

15:04 Chouser: stuartsierra: ah, of course. don't attempt to use equality with floating point

15:04 ,(== 5 5M)

15:04 clojurebot: true

15:05 stuartsierra: ,(< (Math/abs (- (float 0.55) (double 0.55))) 0.001)

15:05 clojurebot: true

15:05 wwmorgan: that's OK, but I'm actually trying to compare two nested structures

15:05 I may be able to work around it in the way that I construct them, however

15:06 by explicitly specifying number type

15:06 stuartsierra: If you care about equality, you should probably use BigDecimal

15:06 durka42: you still can't rely on equality between to Floats

15:06 two*

15:06 (== 0.2 (+ 0.1 0.1))

15:06 ,(== 0.2 (+ 0.1 0.1))

15:06 clojurebot: true

15:06 wwmorgan: ah. Good points

15:08 durka42: ,(apply + (take 10 (repeat 0.1)))

15:08 clojurebot: 0.9999999999999999

15:30 hiredman: http://twitter.com/nicksieger/status/4064269448 seems like an interesting idea

15:30 turn events into a lazy sequence

15:40 Chouser: lazy-xml does essentially that -- turns SAX parse event callbacks into a lazy seq of event objects

15:43 with plenty of painful thread management inside. :-/

15:44 hiredman: orly

15:44 tomoj: is DnD not what I think it is?

15:44 hiredman: drag and drop

15:44 tomoj: aah, heh

15:50 manic12: with jswat, I can set a breakpoint, but once I get there I can't do anything at all except stop the debugger. after stopping the debugger, it refuses to reconnect to process

15:50 Chouser: oh, in fact I split that out. seq-utils/fill-queue packages up the ugliness and can act as a general facility for turning async events into a lazy seq

15:50 manic12: you can't look at the stack trace or anything?

15:50 (before stopping the debugger)

15:51 manic12: yes, I can look at the stack trace, but it wont let me resume from the breakpoint or even step forward

16:01 LauJensen: Rich uses this phrase in his essay on state and identify " It causes a bifurcation of the program protocols" - What does it mean ?

16:04 Chouser: when you want to represent an action, should you do so using a message or a function?

16:05 With clojure agents, the action is always a function -- there is no "message".

16:10 technomancy: tomoj: you were thinking dungeons 'n' dragons too? =)

16:10 hiredman: 2d6+11

16:10 clojurebot: 14

16:10 savanni: wow

16:10 hiredman: what a crummy roll

16:30 technomancy: (try (eval '(throw (InterruptedException.))) (catch InterruptedException _ nil))

16:30 ^ this doesn't catch the exception

16:30 any idea what's going on there?

16:30 works fine w/o the eval

16:31 Chousuke: technomancy: maybe eval wraps it in a RuntimeException?

16:32 technomancy: I get: No message. [Thrown class java.lang.InterruptedException]

16:32 tomoj: technomancy: yup

16:32 technomancy: not a nested exception

16:34 ordnungswidrig1: hi

16:34 compojure-test> (contains? ::a ::a)

16:34 false

16:34 compojure-test> (contains? [::a] ::a)

16:34 false

16:34 That confused me

16:35 Chousuke: contains? is a key test actually

16:35 (contains? [::a] 0)

16:35 ,(contains? [::a] 0)

16:35 clojurebot: true

16:35 Chousuke: ,(contains? [::a] 1)

16:35 clojurebot: false

16:36 Chousuke: I think it's rather badly named :P

16:36 ordnungswidrig1: Chousuke: uhm, very baldy.

16:36 I thought it was a "sequence containmend test"

16:37 Chousuke: I suppose most people think that. but it's not :)

16:37 ordnungswidrig1: So, which functions tests for containment?

16:38 stuartsierra: in a sequence, they don't

16:38 you generally use sets

16:39 ,(some #{1} [:a :b :c])

16:39 clojurebot: nil

16:39 ordnungswidrig1: stuartsierra: yes, ok. I read to use some. Sth. like (some #{:a} [:a :b :c])

16:39 ,(some #{:a} [:a :b :c])

16:39 clojurebot: :a

16:39 ordnungswidrig1: ah!

16:40 stuartsierra: c.c.seq-utils/includes? does the same thing

16:40 ordnungswidrig1: contrib?

16:40 stuartsierra: yes, clojure.contrib.seq-utils

16:45 LauJensen: Rich uses this phrase in his essay on state and identify " It causes a bifurcation of the program protocols" - What does it mean ?

16:48 hiredman: LauJensen: scrollback, start reading after the first time you asked

16:48 LauJensen: You mean Chousers comment?

16:49 hiredman: yes

16:49 LauJensen: Ah, I wasn't sure it was for me, thanks

16:49 hiredman: it's also a good idea to include some more context in questions

16:50 that line was specifically about actor style message passing as a concurrency construct

16:50 ordnungswidrig1: LauJensen: you mean the term "bifurcation" or the complete phrase makes no sense?

16:50 LauJensen: Its 'bifurcation' that's tripping me up

16:50 manic12: bifurcation means to split

16:50 LauJensen: Oh ok

16:50 ordnungswidrig1: LauJensen: It's a term used in chaos theory

16:51 manic12: to split a path or stream or something like that

16:51 ordnungswidrig1: LauJensen: Think "diversion"

16:52 LauJensen: Ok, so he's basically saying that you have to work around the programs own protocols ?

16:53 ordnungswidrig1: LauJensen: http://en.wikipedia.org/wiki/Bifurcation_theory The second image is a popular example of a function that -- for certain values begins to switch between multiple values -- it bifurcates.

16:53 manic12: maybe he's saying that there shouldn't be two or more ways of doing exactly the same thing

16:53 ordnungswidrig1: LauJensen: Can you give me a pointer to the essay. I did not bookmark it

16:53 LauJensen: sure, http://clojure.org/state

16:54 manic12: of course i am reading your question with almost zero context

16:55 hiredman: you could just ask him when he is around

16:55 ordnungswidrig1: LauJensen: he says the program protocol is split into parts: some part of the protocol is the functions and some part is the value passed

16:56 LauJensen: do you know actor based concurrency?

16:56 LauJensen: ah ok

16:56 Yea I have the general idea

16:57 ordnungswidrig1: LauJensen: To make concurrency work with actors you must get the messages right that are passed and you must get the functions right that work on the messages. I think this is what he means by bifurcation.

16:57 LauJensen: message+functions

16:58 LauJensen: Seems plausible, thanks for helping me decrypt it

16:58 manic12: in other words the logic of the program is divided into two areas, eh?

17:00 i figured out my stupidity with this damn swat, it was stopping all threads instead of just the one I wanted it to stop

17:02 ordnungswidrig1: manic12: yes, two areas, if you like

17:03 anybody using compojure?

17:07 manic12: it's both good and bad that rich has taken a pragmatic approach towards choosing a platform for his language design

17:08 it's good that the jvm is popular, and that clojure integrates well with java

17:12 Makoryu: manic12: Hmm, what happened to the projects to get Clojure running on other VMs?

17:13 Chousuke: nothing. :)

17:13 manic12: i know very little about that and choose to stick my head in the sand on that matter

17:13 Chousuke: ClojureCLR still exists.

17:13 Makoryu: How's it doing?

17:13 Chousuke: that I don't know

17:13 manic12: does it use the DLR?

17:14 technomancy: some people have reported that it's "4 weeks behind regular Clojure", but I don't know where that comes from.

17:14 Chousuke: http://github.com/richhickey/clojure-clr

17:14 technomancy: I haven't seen any commits for it in contrib in ages.

17:14 oh, did they spin it off into its own project?

17:14 why is rich hosting it?

17:14 Chousuke: It's semi-official I think

17:14 manic12: how about a clojure on a lisp runtime?

17:15 Makoryu: manic12: Define "a lisp runtine." I'm curious :p

17:15 You mean compiling Clojure to portable Common Lisp?

17:15 ffailla: is there a way to define a function literal without an an argument

17:15 technomancy: manic12: you mean Common Lisp? would be easier to write once clojure-in-clojure is finished

17:15 Chousuke: ffailla: #(foo bar)?

17:15 manic12: (I'm just joking because it would probably work as well as scheme does on a symbolics machine)

17:16 technomancy: minor pet peeve: people calling Common Lisp "lisp"

17:17 Makoryu: technomancy: Yeah. Clojure and Scheme are every bit as worthy of the name

17:17 manic12: 'splain

17:17 Makoryu: Hell, so's Arc

17:17 manic12: clojure is not lisp

17:17 stuartsierra: Clojure is *a* lisp.

17:17 Makoryu: manic12: Common Lisp is not the original Lisp.

17:17 ffailla: Chousuke: yes, why wouldn't this work (let [f #(+ 1)] (f 1234))

17:17 manic12: clojure is a clojure and has left lisp to the history books

17:17 Makoryu: manic12: Okay, now you've veered off into tinfoil hat territory

17:18 manic12: how so?

17:18 Chousuke: ffailla: because you're calling f with an argument and it doesn't take any :/

17:18 manic12: I've been programming Lisp (CL) for years and clojure is nothing like CL or even scheme really

17:19 ffailla: Chousuke: duh... thank you :)

17:19 Makoryu: ffailla: You want (fn [& r] (do stuff that ignores r))

17:19 Chousuke: or possibly

17:19 ,((partial + 5) 10)

17:19 clojurebot: 15

17:19 Makoryu: manic12: Once more, CL is not the original Lisp.

17:19 manic12: It's not even older than Scheme.

17:20 manic12: i didn't say it was

17:20 Makoryu: manic12: Calling CL "Lisp" is a giant misnomer. Clojure is every bit as much a Lisp as CL is.

17:20 manic12: what i am saying is that clojure is a departure from lisp

17:20 clojurebot: clojure is far closer to perfection then python

17:20 Makoryu: manic12: It really isn't

17:20 Chousuke: clojurebot: than :(

17:20 clojurebot: I don't understand.

17:21 lpetit: is clojurebot's source code available ?

17:21 Chousuke: yes

17:21 clojurebot: source

17:21 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

17:22 Makoryu: manic12: If you disagree, please explain, because I don't see how adding a bit of syntax for literals (something you can do within CL as well) suddenly disqualifies it as a Lisp when all its other attributes are very much in the tradition of Lisp.

17:22 lpetit: omniscient clojurebot, soon it will automatically change it's own source code in git, recompile himself, maybe also create sibling bots to have conversations with when everybody's sleeping :)

17:22 Makoryu: manic12: By the way, Clojure is far from the first Lisp to be implemented on the JVM

17:22 manic12: i think that clojure is it's own new thing

17:23 LauJensen: lpetit: Yea I was wondering about that (ns com.skynet.clojurebot) in the source

17:23 manic12: it focuses on sequences abstractly and not cons cells

17:23 Makoryu: manic12: And CL has a huge pile of generic functions that do exactly the same thing.

17:24 manic12: CL was pushing the limit of what it means to be a lisp too

17:24 Makoryu: So why do you insist on calling CL "Lisp" (not "a Lisp")?

17:24 Chousuke: this argument is silly

17:25 Chouser: Chousuke: +1

17:25 lpetit: I was searching a way to go to sleep, please continue this very interesting existential conversation a little more, it'll get me to sleep quicker than I had expected :-p

17:25 would have

17:25 manic12: what I am saying is that at some point you have to make a break in calling a language a Lisp when it draws from so many other influences

17:25 tomoj: what counts as a lisp, really? anything with code as data?

17:25 are sexp's important?

17:26 or is it a genealogical thing?

17:26 LauJensen: Let me settle this for your boys, I asked google "define: lisp", and this is the truth: a speech defect that involves pronouncing `s' like voiceless `th' and `z' like voiced `th'

17:27 Or from Wikipedia/Lisp: "There are also a few new dialects of Lisp. Notably: Newlisp (a scripting language), Arc (developed by Paul Graham) and recently Clojure (developed by Rich Hickey) and Nu for programming with Apple's Cocoa."

17:27 manic12: clojure is not a lisp

17:27 Makoryu: manic12: Then neither is CL or Scheme ;)

17:27 Chouser: ,(cons 1 (list 2 3))

17:27 clojurebot: (1 2 3)

17:28 lpetit: from the creator of Qi in ( http://www.lambdassociates.org/blog/nextlisp(1).htm ) :

17:28 manic12: clojure has things in common with languages that are modern versions of lisp 1.5, but at some point there is a difference

17:28 lpetit: If we ask ourselves, ‘What is the genotype of Lisp?’, what is its DNA, its genetic legacy, I'd suggest that it is composed of the following five ideas. 1. Recursion as the primary mean of expressing procedure calling. 2. Heterogenous lists as the way of composing and dissecting complex data. 3. Programming by defining functions. 4. Garbage collection. 5. Programs as data.

17:28 interesting distinction between the genotype and the phenotype of lisps.

17:29 Chouser: Clojure easily fits all those except perhaps 2

17:29 Chousuke: lists are only replaced with the more generic "sequences" :P

17:30 lpetit: yes

17:30 manic12: so only #5 seperates it from .net or anything else

17:30 Chouser: or seqs, vectors, and maps.

17:30 lpetit: and Qi will be ported to clojure to be hosted on the JVM. So Clojure has been seen as having the same DNA as Qi :)

17:30 Chouser: I rarely "compose complex data" with seqs, though I frequently use them for dissecting

17:31 Makoryu: I'd add something to the list above: Every Lisp should support a usable superset of its feature influences.

17:31 And Clojure does that pretty well, I'd say

17:32 Chouser: I find it handy to refer to clojure as a lisp, because it seems to be meaningful in an accurate way to a lot of people.

17:32 lpetit: But really guys, isn't that just the difference between the stages of a same program, made easy in lisp, maybe not so easy in other languages ?

17:32 Chouser: though ultimately I don't care much if it actually is a lisp

17:32 manic12: ok, so it's "handy"

17:32 neither do i

17:32 Chouser: hooray!

17:32 lpetit: I mean : iterative programming, start with simple data structures, and maybe enhance them

17:33 Even in common lisp they do so I guess. CLOS is certainly used in practice !

17:34 Makoryu: manic12: You seem to care a lot, what with the number of times you've insisted in the past few minutes that Clojure is not a Lisp...

17:34 lpetit: bye guys, cu

17:35 LauJensen: night night

17:35 Chouser: lpetit: ciao

17:35 lpetit: What time is it in Denmark ?

17:35 :)

17:36 * Chouser guesses: time to compare Clojure to another popular language.

17:37 Makoryu: Chouser: SURE! How about SCALA?!?

17:37 :D :D :D

17:37 Chouser: heh

17:37 LauJensen: Chouser: haha :) I've run out of languages

17:38 Chouser: really? no C++?

17:38 you could go kick the groovy guys around a bit

17:38 LauJensen: (filter #(must-not-be-cruel-comparison %) available-languages)

17:38 Makoryu: Didn't they actually surrender to the Scala folks, or something?

17:39 Chousuke: LauJensen: redundant use of #()

17:39 manic12: Lisp originally stood for List processing, clojure is to lisp processing as jet engines are to propellors

17:39 LauJensen: I think if I was to write up another Vs piece, it had to bring something to the table which was not obvious... I can't think of anything atm

17:40 manic12: list processing

17:40 Chousuke: manic12: the word lisp has since changed its meaning.

17:41 LauJensen: Chousuke: yes, Lisp actually means Clojure nowadays

17:41 Chousuke: :)

17:41 LauJensen: little known fact...

17:41 Chouser: manic12: would you buy "like a lisp"?

17:42 manic12: what about "looks like a lisp"?

17:42 manic12: i'm just stating my opinion

17:42 crios: ,(filter #(= "remove" %) (keys (ns-publics 'clojure.core)))

17:43 clojurebot: ()

17:43 Chouser: manic12: I'm asking for your opinion

17:43 crios: how can I extract the function with name "remove"?

17:43 manic12: oh

17:43 Chouser: ,(filter #(= 'remove %) (keys (ns-publics 'clojure.core)))

17:43 clojurebot: (remove)

17:43 manic12: it "looks like a lisp"

17:44 Chouser: manic12: but isn't "like a lisp"?

17:44 manic12: because the parens come before the function, and it is like a lisp in that code is data

17:44 crios: thank you Chouser (forgetting the symbol!)

17:44 manic12: but the v22 takes off like a helicopter and flys like a turboprop

17:44 Chouser: ,(filter '#{remove} (keys (ns-publics 'clojure.core)))

17:44 clojurebot: (remove)

17:44 Chousuke: I think any language that has a homoiconic representation based on lists or list-like things could be called a lisp

17:46 Chouser: ,('remove (-> 'clojure.core ns-publics keys set))

17:46 clojurebot: remove

17:46 Chouser: ha!

17:46 ,(-> 'clojure.core ns-publics keys set 'remove)

17:46 clojurebot: (clojure.core/-> (clojure.core/-> (clojure.core/-> (quote clojure.core) ns-publics) keys) set)

17:47 Makoryu: ,(doc ->)

17:47 clojurebot: "([x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."

17:47 Chousuke: .. something funky happened with -> there

17:48 Chouser: Chousuke: yeah, the ' at the end was expanded at read time, before -> got a chance

17:48 so then the whole thing got stuck inside a (quote ...)

17:48 Chousuke: heh

17:48 Chouser: ,,(quote lots-of-stuff remove)

17:48 clojurebot: lots-of-stuff

17:49 crios: mm I prefere (filter '#{remove} (keys (ns-publics 'clojure.core)))

17:49 prefer

17:49 Chouser: crios: that's probably an appropriate preference. :-)

17:50 crios: well, much more readable, just IMHO of course

17:51 hamza: hey guys, is it possible to create an interface from clojure? (not implement)

17:51 Chouser: hamza: yes, but it must be AOT-compiled

17:51 hamza: (doc gen-interface)

17:52 * Chouser tries out hiredman-style

17:52 Chouser: ,(-> 'clojure.core ns-publics keys ((partial filter '#{remove})))

17:52 clojurebot: (remove)

17:54 hamza: Chouser: does that kill the ability to test code using repl since i have to compile all the time?

17:54 doc says it does nothing when not compiling..

17:54 Chouser: hamza: only compile the interface when the interface changes

17:55 so get it right. :-) creating new implementations with proxy can be done at runtime.

17:55 hamza: it is a restriction, but one that comes from the JVM.

17:56 dinner time. later, folks.

17:56 crios: Chouser here '#{remove} are you "escaping" a set?

17:56 hamza: kk now i get it :) as long as i keep the .class file on the class path i can play with the interface..

17:57 Chouser: crios: yes

17:57 no.

17:57 crios: quoting, not escaping

17:58 crios: ok

18:00 so that quoted set is the predicate of filter. It applies that predicate to all elements inside the (keys. When matching, the return value is true

18:00 correct?

18:02 I mean when using this expression: (filter '#{remove} (keys (ns-publics 'clojure.core)))

18:03 hamza: ,(+ 1 2)

18:03 clojurebot: 3

18:08 ambient: groovy surrendered to scala? (reading the backlog ~1hr)

18:09 i've read through at least 10 different emacs tutorials and i know all those commands very well, but still feel like im just scratching the surface

18:10 i wish there were different what-i-use-for-my-stuff reports from people who have used emacs for lisp programming for a long time

18:10 technomancy: ambient: not to toot my own horn, but the PeepCode screencast on Emacs does that.

18:10 as does the Starter Kit: http://github.com/technomancy/emacs-starter-kit

18:10 ambient: cool, i shall check that out

18:10 technomancy: have you seen http://technomancy.us/126 ? for clojure-specific functionality.

18:11 ambient: nothing compares to pairing with a pro though.

18:11 ambient: i tried using the started kit but didn't enjoy some of its defaults and didn't really see the point in using it, because clojure-install already does all that i need (that I'm aware of..)

18:12 technomancy: there's http://planet.emacsen.org too

18:12 ambient: bookmarked :)

18:14 i wonder if there's any kind of an integration for firefox and emacs, like vimperator does

18:14 but then again, vimperator is so nice that perhaps it's not necessary

18:14 technomancy: ambient: heh. vimperator was inspired by conkeror, which is exactly that.

18:14 ambient: only thing i hate about vimperator is that i can't live without it anymore :(

18:15 seems that conkeror is not a firefox addon

18:16 technomancy: it's a separate app

19:00 hiredman: I think an IAgent needs to be lifted out of Agent

19:02 the interface for interacting with the EDT via invokeLater is almost exactly what you get from an agent, so I'd like to be able to implemented an IAgent interface on top of it

19:12 clojure.lang.Agent$Action being protected is kind of a drag

19:14 it would be nice if there was an IAction interface that was public at least

20:10 Kjellski: hi there =)

20:10 rhickey: Kjellski: hey

20:10 Kjellski: can someone give me a hint about the make-array function?

20:11 dnolen: ,(make-array Float/TYPE 10)

20:11 clojurebot: #<float[] [F@215bee>

20:11 dnolen: Kjellski: ^

20:12 hiredman: http://gist.github.com/192389 <-- actually, I needed Agent$Action to be lifted out into AAction (and IAction) and then replace the "new Action(..." in Agent with a new method called getAction

20:12 Kjellski: Actually I´m in some sort of newbe trouble I think. So what I´m trying to do is to make an array over an array of "things" and I´ve tried this:

20:12 hiredman: faux-agent should interact with the STM the same way agents do

20:13 Kjellski: (def test (seq (make-array Integer 2 2))) which should give me a 2by2 "matrix" of ints right?

20:13 Makoryu: Kjellski: Interesting smart-quotes... ಠ_ಠ

20:13 hiredman: (prn :foo) could be replaced with a call to invokeLater or invokeAndWait

20:14 Kjellski: erm

20:14 is there a reason you are using arrays?

20:15 first, java doesn't have multidiemensional arrays, it has arrays of arrays, and that is what (make-array Interger 2 2) will make

20:15 Kjellski: What I wanted to do is some sort of minesweeper ... and I thought this would fit the problem ^^ please tell me thr right choise though

20:15 hiredman: second, Integer and int are different types

20:15 dnolen: Kjellski: might be better to just use vectors.

20:15 hiredman: ints are primitives and Integers are ints wrapped in an Object

20:16 Kjellski: @hiredman: I know both of these hints, but that doesn´t solve my problem... ^^

20:16 hiredman: third, call seq on the output of make-array is silly

20:16 dnolen: ,[[1 0] [0 1]]

20:16 clojurebot: [[1 0] [0 1]]

20:16 technomancy: Kjellski: arrays are for java interop.

20:16 hiredman: seq returns a sequence

20:16 has anyone heard anything about an electronic version of the contrib agreement?

20:17 Kjellski: Okay, sorry... maybe a bit closer to my real example, I want to stuff JButtons in there... ^^

20:17 technomancy: hiredman: there's a company here in Seattle that was talking about implementing that for a different OSS project

20:17 had their lawyers look it over; said it would hold water

20:17 hiredman: Kjellski: definitely don't use arrays

20:17 Kjellski: But however, this will give me a nil seq...

20:19 dnolen: ,(get-in [[(Object.) (Object.)] [(Object.) (Object.)]] [1 1])

20:19 clojurebot: #<Object java.lang.Object@18b1699>

20:20 Kjellski: hiredman: what is the better choice?

20:21 hiredman: well nuts, I don't have any envelopes

20:21 Kjellski: a vector

20:21 woa

20:23 ,(let [board [[nil nil nil] [nil nil nil] [nil nil nil]] move [1 1]] (update-in board move (constantly 'x)))

20:23 clojurebot: [[nil nil nil] [nil x nil] [nil nil nil]]

20:23 hiredman: :D

20:28 enderoute: (defstruct foo :x :y :z) (def bar '(3 4 5)); how can I struct a foo with bar? its got to be something simple

20:28 hiredman: (apply struct foo bar)

20:29 enderoute: thanks

20:47 khora: could you give me a clojure example to compile?

20:53 hiredman: I think wrapping SwingUtilities/invokeLater in the Agent abstraction might be the coolest thing since sliced bread

20:53 ~compile

20:53 clojurebot: the unit of compilation in clojure is the namespace. namespaces are compiled (not files). to compile a namspace the namespace needs to be on the classpath and so does ./classes/ (and the directory needs to exist) because clojure writes the class files to that directory. http://clojure.org/compilation

20:54 hiredman: there is an example there

21:53 dysinger: Are queues worked in yet?

21:53 We are coding some message pub/sub in 1.1

21:54 rhickey: dysinger: you want to use JMS?

21:56 dysinger: We are trying to abstract. We are using activemq & rabbitmq

21:56 To start

21:57 (pub / sub / broadcast )

21:57 rhickey: the problem with abstracting is that key features get left out

21:57 dysinger: Y

21:58 It's ok - was just curious

21:58 rhickey: I started to design something to wrap both j.u.c. queues and jms and found too many differences to make it worthwhile

21:58 dysinger: I hear you

21:59 rhickey: now I'm hoping HornetQ or ActiveMQ in local mode are fast enough to provide an in-memory-through-distributed API

21:59 but AMQP is a whole other thing

21:59 dysinger: We can abstract over a couple I think

21:59 For our needs

22:00 (basic)

22:01 rhickey: I've decided not to put it on my plate for 1.1, so maybe you could run with it and contrib something

22:01 the ideas I've been fiddling with are: tying queue transactions to dosync

22:02 queue versions of map and filter

22:02 dysinger: rhickey: Thanks again btw :) our clojure team would be doing something else less cool without your hard work :)

22:03 rhickey: you're welcome

22:03 dysinger: We are now pairing over screen/emacs/voip :)

22:03 So fun.....

22:04 rhickey: gotta run

22:04 dysinger: L8r

22:55 hiredman: lisppaste8: url?

22:55 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

22:56 hiredman pasted "hydra (producer/consumers)" at http://paste.lisp.org/display/87611

23:07 hiredman annotated #87611 "better docstring? returns lazy-seq instead of LBQ" at http://paste.lisp.org/display/87611#1

23:19 duck11231: would it be worth it to have some sort of manifest file that could be placed inside jar files to describe what clojure namespaces are contained within?

23:38 mabes: how do I look up a function if I have the name in string form?

23:38 hiredman: ,(-> "+" symbol resolve)

23:38 clojurebot: #'clojure.core/+

23:38 hiredman: ,(-> "+" symbol resolve deref)

23:38 clojurebot: #<core$_PLUS___4094 clojure.core$_PLUS___4094@4e0456>

23:38 hiredman: the first one gets you the var, the second the function inside the var

23:39 mabes: ,(apply (-> "+" symbol resolve) '(1 2 3))

23:39 clojurebot: 6

23:39 mabes: thanks hiredman and clojurebot!

Logging service provided by n01se.net