#clojure log - Nov 07 2009

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

0:20 konr: Is there a way to call a protected method besides using gen-class?

0:20 hiredman: I am glad you asked

0:20 http://gist.github.com/226726 <-- wall-hack-method

0:21 konr: hiredman: haha, I just ran into that piece of code wondering if it was trying to do that

0:31 chouser: hiredman: we could smuggle that into contrib. what do you think?

0:34 hiredman: sure

0:35 I hate java.uti.Date

0:54 somnium: hey, is this obviously broken for any reason -> http://paste.lisp.org/display/89933

0:54 trying to make a when-let for multiple bindings and it seems to work without much code

0:55 hiredman: you're missing a quote

0:55 somnium: where? it runs in my repl

0:55 ah, in the example

0:55 my bad

0:59 I meant the semantics I guess, I saw several people asking about multiple when-let if-let bindings recently and it doesn't *seem* so hard

1:05 chouser: hiredman: I think it has to be a patch via clojure-contrib assembla. Maybe again java-utils?

1:06 hiredman: ok

1:06 chouser: hiredman: go ahead and assign it to me

1:06 * hiredman goes to learn assembla

1:07 hiredman: I remembered my password on the first go round!

1:12 * technomancy just learned today that contrib has a separate set of committers from clojure proper

1:14 chouser: I don't think any one person watches every commit that goes into contrib

1:17 hiredman: I'm not a member of the space

1:18 so I can't do much

1:18 https://www.assembla.com/spaces/clojure-contrib/support/tickets/43-add-wall-hack-method-and-wall-hack-field-to-java_utils-clj

1:19 _ato: ah ha! I fixed Chousuke's problem

1:20 hiredman: !

1:20 _ato: all I did was rearrange his classpath a bit

1:20 hiredman: :|

1:20 _ato: problem was it was compiling itself over itself and getting all confused because gensym makes things change name

1:21 hiredman: interesting

1:21 have you seen my reader?

1:21 _ato: no I hadn't

1:21 there's two competing readers is there? :)

1:22 hiredman: well, competing? I dunno

1:23 _ato: ah so yours is all one function, that probably helps you avoid Chousuke's problem

1:23 hiredman: sort of

1:24 it's one top level function

1:24 with the letfns, but the letfns are locals

1:24 _ato: oh right, but the inner closures and stuff will still come out as multiple class files

1:33 chouser: hiredman: it's done.

1:33 hiredman: huzzah!

1:34 somnium: are you going to keep the cool name?

1:34 hiredman: it's in the tree with the name

1:34 somnium: nice

1:34 chouser: "hack" in the name is very appropriate

1:35 add-classpath should probably have that too

1:40 selector-gadget: ?quit

1:53 chouser: ~tarpit

1:53 clojurebot: Huh?

2:12 konr: Is there a variation of filter that splits the lists into matching and not-matching parts?

2:13 hiredman: reduce

2:13 there is split-with but that only works on a sorted list

2:14 well

2:14 it sort of only works on a sorted list

2:18 somnium: ,(doc separate)

2:18 clojurebot: "clojure.contrib.seq-utils/separate;[[f s]]; Returns a vector: [ (filter f s), (filter (complement f) s) ]"

2:19 konr: somnium: oh :( I was starting to code that!

2:20 somnium: konr: I've found that simply reading contrib is a great way to save time :)

2:20 (and core for that matter...)

2:20 if only there wasn't so much to read

2:25 is contrib.core a place for 'soon to be in clojure'?

2:30 lisppaste8: krumholt pasted "problem with agents" at http://paste.lisp.org/display/89934

2:31 krumholt: can somebody see an obvious error with that code?

2:32 hiredman: #'minus is unusual

2:32 I think old versions of ants.clj had that(maybe it still does?)

2:32 but #' is not needed

2:33 what problem are you having?

2:33 krumholt: ok but that doesn't seem to be the problem

2:33 i get an out of memory error on the agent

2:34 hiredman: possibly you are queing up a ton of agent actions

2:35 krumholt: Exception in thread "Swank Control Thread" java.lang.OutOfMemoryError: Java heap space

2:35 * hiredman blames swank

2:35 hiredman: what happens if you up the sleep times?

2:36 krumholt: i tried i went: Exception in thread "Read Loop Thread" java.lang.OutOfMemoryError: Java heap space

2:37 :)

2:37 not much better

2:37 hiredman: have you tried it outside of slime?

2:38 krumholt: no i will one second

2:38 hiredman: it's humming along here

2:42 (#<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space>)

2:42 there we go

2:42 could just be the number gets too large

2:44 krumholt: hm it's not doing anything if not used from slime

2:44 no error

2:44 maybe if i wait longer

2:44 ah now

2:45 hiredman: I dunno

2:46 krumholt: well thanks anyway

2:46 hiredman: oh duh

2:46 use when

2:46 not while

2:47 ,(doc while)

2:47 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

2:47 krumholt: oh man

2:47 thanks

2:47 hiredman: ,(doc when)

2:47 clojurebot: "([test & body]); Evaluates test. If logical true, evaluates body in an implicit do."

2:47 krumholt: of course i meant when

2:47 hiredman: very easy to overlook

2:48 jamesswift: Hey! I thought I might post here a small program I wrote as a learning exercise http://wiki.github.com/phraemer/Boggle-Solver

2:48 krumholt: hiredman, thanks again could have look hours over that vode without figuring that out

2:48 hiredman: so it was the agent queues overflowing after all :P

2:48 krumholt: yes

2:48 hoeck1: hiredman: good catch : )

2:48 krumholt: vode = code

7:31 javuchi1: what do you thing about CL+FSET versus Clojure?

7:41 Licenser_: what is CL FSET?

7:43 ah google told me

7:44 javuchi1: FSET are inmutable collections for Common Lisp

8:20 Chousuke: yay

8:21 everything builds and all contrib and clojure tests pass!

8:27 gbt: congrats Chousuke :) I was lurking yesterday so I know you were having a few 'minor' troubles ;)

8:27 Chousuke: yeah, _ato solved them for me :P

8:28 apparently it was some classloader thingy and not an actual problem with my code

8:28 gbt: shhhh, you're meant to keep that sort of thing to yourself :D

8:28 thats ok then. So is this reader just for yourself or an addition to clojure proper?

8:30 Chousuke: Well, I started writing it just to see how it'd turn out.

8:31 I think it'll still need some tweaking before I dare suggest it for inclusion though. But at least I have something that works as a base now.

8:32 gbt: I'm a noob, so its beyond anything I can understand. But its great to see so many people actively trying to improve what is already an impressive language :)

8:34 The-Kenny: Chousuke: What's the difference between yours and the "original" reader?

8:34 Chousuke: mine is written in Clojure :)

8:35 The-Kenny: Oh, that's cool :)

8:35 Chousuke: it also uses multimethods, but otherwise it's pretty similar to the java reader.

8:53 thomaslee: compojure question -- any ideas why the :user-id session variable would not be set despite the redirect-to in login-action being executed? http://pastebin.com/d29a8c7ed

8:54 well it's not an *actual* redirect-to, but a redirect all the same. :)

10:03 scode: I'm looking to implement an LRU cache based on immutable data structures. I can't figure out how to do so using Clojure data structurs, due to the problem of keeping track of recenticity.

10:04 Effectively I need an efficient priority queue (the priority in this case being the recenticity) where the priority of individual items can change. It's fine if it's log(n) or better, but n is not acceptable.

10:04 Am I missing something obvious?

10:04 If the clojure vector did logn32() removal at arbitrary indexes I'd be okay.

10:06 The-Kenny: :)

10:06 wrong window, sorry.

10:26 chouser: scode: would a sorted map do it?

10:26 scode: chouser: I thought so at first, but as far as I can tell I can't "grab the first element" out of a sorted map.

10:27 Or rather, I can't produce the "rest" of the sorted map.

10:27 chouser: use 'first' to get the first, and then remove it from the map

10:27 scode: I think. :) It was one or the other.

10:27 Right. I think I found some problem with that. *reconsiders*

10:28 chouser: I've not actually used a sorted map that way, so there may be a use case where it falls down, but it's the most likely of what we've got so far.

10:28 finger trees should be able to do it too, but they're not ready yet.

10:30 scode: Was not aware of those (http://en.wikipedia.org/wiki/Finger_tree) - I'll read up on them. Thanks :)

10:30 As for sorted map, I think you're right. I think I made a mistake when I went down that path before.

10:36 Yeah. I'll need an additional mapping to cross-reference values in that sorted map, but it should work.

10:37 chouser: scode: if your keys are not naturally unique, you can use a vector of [priority uuid] as the key

10:38 where uuid is not necessarily anything industrial-strength, just something to keep your priorities from colliding.

10:38 scode: If you get it working (or find why it doesn't), I'd appreciate knowing about it. The question comes up occasionally.

10:39 scode: chouser: I was planning on keeping an ever increasing counter to keep track of recencitity.

10:39 chouser: ah, so naturally unique. good.

10:39 scode: The keys will be uique, but since the sorted map is sorted on key (which in this case is recenticity), I must keep a separate mapping to find the [recenticity, key] tuple for a given key

10:40 chouser: And yes I'll let you know.

10:40 chouser: I am doing this to make some comparisons on the effects on GC performance/latency as a result of avoiding mutations (making incremental collections less expensive).

10:42 chouser: Clojure's sorted-maps haven't gotten the same optimization effort that its hash-maps and vectors have gotten, I think.

10:42 no transient sorted-map for example.

10:42 scode: Transient, in this context?

10:42 I do not care too much about absolute performance right now, as long as complexity is reasonable.

10:42 It's more about seeing how CMS/G1GC behaves with no writes to older generations.

10:43 (Or very few writes; there won't be zero.)

10:43 And an LRU is a good practically relevant use case. I wasn't able to get good enough behavior on multi-gigabyte heaps mostly containing LRU-cached data.

10:44 chouser: clojurebot: transient?

10:44 clojurebot: Don't bash in place

10:44 chouser: hmph. I'm not finding useful docs on transients.

10:44 scode: chouser: Oh, you're saying the implementation is in fact mutation based?

10:44 chouser: clojurebot's advice is accurate, but a bit incomplete. :-)

10:44 scode: Rather then copy-on-write "all the way down".

10:45 That was my interpretation of 'don't bash in place'. So if it's not transient, I guess it's bashing in place? :)

10:46 chouser: scode: hash-map and vector support a special "mode" where some mutation is allowed for performance.

10:46 scode: chouser: http://clojure.org/transients

10:46 chouser: ah, yes, that's it.

10:46 scode: Ah, I didn't know that. I thought there was never any mutation.

10:46 I'll read that one. A bit later; gotta go away atm.

10:46 chouser: Thanks for your help!

10:46 chouser: scode: sure

10:48 scode: But I did peak right away; sounds like it's transient mutation in the sense of temporary values during creation, rather than any mutation of the actual data structure being operated upon. Which is fine in this case; writing to newly created data is okay for my purposes.

10:50 chouser: scode: you may be being mislead by the introduction. transient can be used later in the life of the collection if its useful, for example for "batch updates"

10:51 If you're doing one-at-a-time inserts and updates to your maps, you're likely to not call anything that uses transient/persistent! internally and using them explicitly yourself may not change very much.

11:38 krumholt: hi, does anyone have java completion in emacs?

11:51 leafw: krumholt: goodle knows.

11:51 gooGle

11:53 krumholt: sry i didn't mean java java completion but clojure java completion. so it can complete i.e (.printSt to (.printStackTrace

11:55 kefka: ,(class (- 12345678901234567890 12345678901234567889))

11:55 clojurebot: java.lang.ExceptionInInitializerError

11:55 kefka: ,(- 12345678901234567890 12345678901234567889)

11:55 clojurebot: java.lang.ExceptionInInitializerError

11:55 kefka: ,(- 6 5)

11:55 clojurebot: 1

11:55 kefka: ,1

11:55 clojurebot: 1

11:55 kefka: ,12345678901234567

11:55 clojurebot: 12345678901234567

11:55 kefka: ,12345678901234567890

11:56 clojurebot: 12345678901234567890

11:56 kefka: ,(- 12345678901234567890 1)

11:56 clojurebot: java.lang.ExceptionInInitializerError

11:56 kefka: ,(- (new java.lang.BigInteger 6) (new java.lang.BigInteger 5))

11:56 clojurebot: java.lang.ClassNotFoundException: java.lang.BigInteger

11:56 kefka: ,(- (new java.math.BigInteger 6) (new java.math.BigInteger 5))

11:56 clojurebot: java.lang.IllegalArgumentException: No matching ctor found for class java.math.BigInteger

11:57 kefka: ,(- (new java.math.BigInteger "6") (new java.math.BigInteger "5"))

11:57 clojurebot: 1

11:57 kefka: ,(- (new java.math.BigInteger "12345678901234567890") (new java.math.BigInteger "1"))

11:57 clojurebot: 12345678901234567889

11:57 kefka: ,(class (- (new java.math.BigInteger "12345678901234567890") (new java.math.BigInteger "12345678901234567889")))

11:57 clojurebot: java.lang.Integer

11:58 kefka: ,(class (- 12345678901234 12345678901233))

11:58 clojurebot: java.lang.ExceptionInInitializerError

11:58 kefka: ,(class (- (long 12345678901234) (long 12345678901233)))

11:58 clojurebot: java.lang.ExceptionInInitializerError

11:58 kefka: weird.

11:58 chouser: those all work fine in my repl

11:58 kefka: they work fine in mine too

11:58 although (- 12345678901234567890 12345678901234567889) is an Integer

11:58 gbt: krumholt: clojure-mode seems to do it. well I just tried (.printSt and it worked

11:58 kefka: while (- 12345678901234 12345678901233) is a Long

11:59 Why does BigInteger get downcast but not Long?

11:59 In my mind, (long 1) is a bit pathological.

11:59 Obviously, (unchecked-subtract 12345678901234 1245678901233) should be a Long.

12:00 (long 1) is pathological because of the nasty map behavior

12:00 ,(get {(long 1) "one"} 1)

12:00 clojurebot: nil

12:00 krumholt: gbt, hm doesn't work for me for some reason

12:01 gbt: krumholt: what version of clojure-mode you got? I'm on 1.5

12:01 onigiri: kefka, chouser what's the problem? all these clojurebot requests made me curious

12:01 gbt: I'm new though, so I don't know if its always worked?

12:02 kefka: The clojurebot exception is not the problem; we don't have that in our Repls.

12:02 Subtle issue with Clojure is that while 1 and (long 1) are semantically equal, hash-maps treat them as different.

12:02 krumholt: gbt, uh i am on 1.0

12:02 gbt, thanks gone update

12:03 kefka: onigiri: So that can be an issue if you're dealing with, say, sparse matrices/vectors

12:03 ,(get {(long 4) "four"} 4)

12:03 clojurebot: nil

12:03 onigiri: kefka: oh I see, thanks

12:03 kefka: Also...

12:03 ,(hash-set 1 (long 1))

12:03 clojurebot: #{1 1}

12:04 kefka: ,(sorted-set 1 (long 1))

12:04 clojurebot: #{1}

12:04 kefka: I think that if you're relying upon numerically equal things comparing equal, better to use sorted maps/sets for now.

12:04 I generally think (long 1) is a pathological value but there are times when it's appropriate (e.g. a function takes only a long).

12:04 A java function that is... obviously, clojure numerical functions don't care.

12:12 chouser: there are several objects that can represent 1 -- if you're using them as keys in a collection it's probably worth making sure you always use the same type.

12:12 using numbers as keys

12:17 Chousuke: hmm

12:17 ,(get {(long 4) "foo"} (long 4))

12:17 clojurebot: "foo"

12:26 kefka: chouser: agreed, but this is hard to guarantee.

12:26 Because (- 12345678901234567890 12345678901234567889) is the Integer 1 but (- 12345678901234 12345678901233) is the Long 1.

12:26 Which is counterintuitive. It'd be better if - were consistent, IMO.

12:26 Either it always downcasts, or it never does.

12:27 * In my example, the first is a subtraction of two BigIntegers and the second is one of two Longs

12:53 cup: howdy, is there a standard recommendation for how to structure a compojure site?

13:12 javucci: hello there

13:48 ericthorsen: Is there a correlate to proxy-super for gen-class(ed) class methods?

13:49 rhickey: ericthorsen: see :exposes-methods in the gen-class doc

13:49 should do the trick

13:49 if slightly differently

13:50 ericthorsen: rhickey: I saw that..just checking to see if there was a magic function. Thanks!

14:10 javi_: rhickey, what do you think about FSET?

14:11 rhickey: javi_: I haven't used it, but it seems like a good idea if you are in CL

14:16 javi_: i see the problem with FSET is the interaction with the remaining Lisp

14:29 scode: chouser: I have a preliminary LRU now at http://github.com/scode/plrutest/

14:30 chouser: But it's definitely preliminary (needs docs, needs some additional features, and can definitely be optimized)

14:41 chouser: scode: great!

14:41 scode: another perfect candidate for deftype/protocols once those are ready.

14:48 djpowell: i've just been added to the contrib page; is it possible to subscribe to clojure-dev without a google account?

15:06 ericthorsen: rhickey: Anything I have to so for overloads on the expose methods for gen-class? Cannot seem to get it to see a no arg version of the function...I'm passing this to both versions

15:06 ...:exposes-methods {read superRead unread superUnread}

15:06 both read and unread have overloads

17:02 scode: chouser: Amusingly when I googled the first hit was what you just said - apparantly Google indexes faster than I catch up on IRC

17:02 chouser: But were you referring to http://www.assembla.com/wiki/show/clojure/Datatypes (deftype/protocols)?

17:04 rhickey: ericthorsen: what you get is another method with the name you specify, to call use (.superRead this)

17:05 chouser: scode: ooh, if so that's new -- google's generally been a couple weeks behind on our irc logs

17:05 scode: but yes, datatypes

17:08 scode: Roger, sounds interesting. I admit to not having kept up with the movements in clojure as well as I would like.

17:21 ben_m: Greetings :)

17:21 Is there a way to load some definitions from a file into the REPL, so I can do interactive development?

17:23 Chousuke: (doc load-file)

17:23 clojurebot: "([name]); Sequentially read and evaluate the set of forms contained in the file."

17:24 Chousuke: (doc load) ; this also

17:24 clojurebot: "([& paths]); Loads Clojure code from resources in classpath. A path is interpreted as classpath-relative if it begins with a slash or relative to the root directory for the current namespace otherwise."

17:24 ben_m: Thanks :)

17:25 Would you generally recommend Clojure to a functional programming fan (I love Haskell, Common Lisp, ...), who likes the JVM, but not Java the language?

17:26 From what I've seen when I last played with Clojure is that you do have to use Java-esque code frequently when interfacing with the JVM.

17:31 _ato: ben_m: yes, idiomatic Clojure is very functional.

17:32 ben_m: This mentality of "embracing the jvm" puts me off a bit

17:32 But we'll see :)

17:34 _ato: well, it's a choice between that and rewrite everything yourself, I guess. In practice I find interfacing with Java code works fine. If the library has a particularly horrible API a couple of wrapper functions and the odd macro can clean it up

17:35 ben_m: Sounds reasonable.

17:46 fradiavalo: Hi, is it possible to write multi-line code on slime (swank clojure)?

17:47 _ato: fradiavalo: in the REPL?

17:48 fradiavalo: _ato: yes

17:48 _ato: yeah... just don't close your parens and it'll continue on the next line

17:48 although I prefer to do multi-line things in a .clj for and evaluate with C-x C-e

17:48 s/.clj for/.clj file/

17:49 javi_: who's using clojure?

17:49 is enterprise ready?

17:49 fradiavalo: ah, I see. I am using paredit mode, so that doesn't let me not enter an closing paren

17:50 _ato: javi_: gosh I hope not. Most thing labeled "enterprise" are terrible. ;-)

17:50 fradiavalo: I can't just put my cursor before the closing paren and hit return

17:50 ben_m: fradiavalo: ^d then press return?

17:50 I don't know about paredit so that's just a guess :)

17:50 javi_: _ato, then i don't understand why to use the jvm, as it is very much enterprise "oriented"

17:51 in other words

17:51 is clojure ready in reability and stability terms?

17:51 fradiavalo: ben_m: thx, but that doesn't work

17:52 javi_: reliability

17:52 ben_m: fradiavalo: What keeps you from writing the code in some buffer and loading that?

17:52 As _ato said

17:52 fradiavalo: ben_m: yeah, I could do that. Its just that I love typing at the REPL :)

17:53 ben_m: heh

17:53 Well, you just type at another buffer and evaluate the last s-expression.

17:53 I think you don't even have to save the buffer or anything.

17:53 I'm a Vim user who uses Emacs only for Common Lisp and Haskell, so these are all just assumptions.

17:53 fradiavalo: You mean just like other lisp expressions in the scratch buffer?

17:53 ben_m: right

17:54 fradiavalo: I will give it a shot

17:54 _ato: javi_: uhh... yes, it doesn't crash randomly? is that what you mean by reliable? ;-)

17:55 fradiavalo: ben_m: That does work if I turn on clojure more on the buffer

17:55 ben_m: yeah

17:55 that's pretty nice :)

17:55 fradiavalo: ben_m: yeah! Thanks

17:55 ben_m: I should tidy up my .emacs file (that's what is keeping me from using Emacs more) and get used to it for clojure

17:55 fradiavalo: Thank _ato for that

17:56 fradiavalo: yeah thanks _ato too

17:56 ben_m: Take a look at emacs starter kit

17:57 _ato: fradiavalo: another handy key combo is C-c C-c which will compile the top-level form you're in the middle of. Which is great for working on functions as you don't have to navigate to the end of it to compile it

17:58 fradiavalo: _ato: Yeah, that is pretty cool. I also like how code navigation just works

17:58 ben_m: code navigation? :)

17:58 fradiavalo: ben_m: Jumping to definations and back

18:00 _ato: ben_m: M-. to go to a definition and M-, to go back

18:00 ben_m: That's nice.

18:02 I hate configuring Emacs :D

18:03 fradiavalo: It is not possilble to change your classpath from the REPL, is it?

18:04 _ato: there's an add-classpath function, I don't know how reliably it works though

18:05 fradiavalo: I will take a look at that. Java's classpath is so rigid, I still haven

18:06 haven't figured out a system to manage my code well

18:06 ben_m: yeah...

18:06 Raynes: fradiavalo: I believe the add-classpath function is rather frowned upon.

18:07 Usually when people recommend it they say something along the lines of "But don't get too used to it."

18:08 fradiavalo: Raynes: :), I will keep that in mind

18:08 Anything that makes classpath managable has to be black magic.

18:08 Raynes: Indeed.

18:08 * Raynes hated the classpath at first as well.

18:10 fradiavalo: What makes Raynes not hate it now?

18:10 Raynes: I got used to it.

18:11 fradiavalo: How you keep from adding every new jar to it?

18:11 How do* you

18:17 _ato: fradiavalo: personally I just have ~/.clojure/* on my classpath an symlink in any jars I need. not great but I haven't bothered to come up with something better. If it's a more complex project (like some existing java monster with a million jars) I'll put the swank.jar in it's classpath, start it from a terminal and use M-x slime-connect in emacs

18:17 I think some of the maven users came up with some emacs magic for automatically switching the classpath depending on the project you're working on, reading the dependencies from pom.xml. I haven't looked into that yet

18:19 yeah, here we go: http://github.com/talios/clojure-maven-plugin

18:19 they have a clojure:swank task

18:19 fradiavalo: _ato: I have something similar to you now. But sometimes when I add symlinks to new jars, it doesn't work. I will take a look at Maven

18:19 thanks!

18:29 st3fan: hmm is there a (find-first collection fn) ?

18:29 i need to find a matching item in a (small) sequence

18:30 sequence of maps

18:31 _ato: ,(use 'clojure.contrib.seq-utils)

18:31 clojurebot: nil

18:31 st3fan: ah seq-utils :-)

18:32 _ato: ,(find-first #(> % 4) [1 2 1 3 6 3 2])

18:32 clojurebot: 6

18:32 _ato: not sure if that's exactly what you meant

18:35 ,(find-first :a [{:b 2} {:c 3} {:d 7, :a 4}])

18:35 clojurebot: {:d 7, :a 4}

18:37 st3fan: yeah it is

18:37 i should really use a map though

18:37 to do a direct lookup

18:40 ben_m: fradiavalo: the emacs starter kit is great, thanks for the recommendation

18:41 fradiavalo: ben_m: you are welcome. Thank the author for it :)

18:44 ben_m and _ato: C-j will do \n and indent at the slime REPL :)

18:45 ben_m: mhh

18:45 M-x slime opens up two buffers with a REPL

18:45 :/

18:46 fradiavalo: ben_m: one is inferior lisp, avoid that one

18:47 ben_m: ok

18:47 Still ugly :D

18:47 _ato: fradiavalo: ah, cool. that's handy. That reminds me I should turn on paredit at the REPL was well (I use it when editing source)

18:49 fradiavalo: yeah paredit is awesome, it feels a little weird at first, but once you are a little used to it, it becomes indispensible

18:49 ben_m: I feel that way about the Emacs in general

18:49 fradiavalo: true

18:49 ben_m: I'm a Vim poweruser though

18:50 I'm not used to editing things in Emacs :/

18:50 _ato: ben_m: I think *inferior-lisp* is the stdin/stdout of the clojure process, and then the other REPL slime connects to via a socket which does all the funky slime stuff

18:50 eg. if you use slime-connect to a remote process you don't get *inferior-lisp*

18:50 ben_m: When you load a file via C-c C-l, both buffers load the file

18:52 digash: lets say I have a vector of integers. How do I find the index of the smallest one?

18:53 _ato: ,(apply min-key second (indexed [90 50 40 70 30]))

18:53 clojurebot: [4 30]

18:53 _ato: ,(first (apply min-key second (indexed [90 50 40 70 30])))

18:53 clojurebot: 4

18:54 _ato: there's probably a simpler way

18:54 djpowell: ,(doc indexed)

18:54 clojurebot: "([s]); Returns a lazy sequence of [index, item] pairs, where items come from 's' and indexes count up from zero. (indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d])"

18:54 djpowell: is that from contrib?

18:54 ,indexed

18:54 clojurebot: #<seq_utils$indexed__697 clojure.contrib.seq_utils$indexed__697@8fc519>

18:54 djpowell: k

18:57 _ato: ,(first (apply min (indexed [90 50 40 70 30])))

18:57 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

18:57 _ato: oh right

18:58 fradiavalo: ,(doc min-key)

18:58 clojurebot: "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is least."

19:02 digash: thanks, for the pointers i will need to adapt it to clojure 1.0 w/o contrib

19:08 st3fan: hmm what is the non-read-macro equivalent of #'foo ?

19:09 isn't that (function foo) in common lisp?

19:09 djpowell: (var foo)

19:09 st3fan: ah :-)

19:10 digash: ,'#'foo

19:10 clojurebot: (var foo)

19:12 st3fan: hmm does not work in my case

19:12 i need to do something like this:

19:12 (find-first #(= "Test" (:webservice-action (meta (var %)))) [test-action hello-action])

19:12 where the actions are functions with :webservice-action meta-data

19:13 ben_m: Has anybody used java-sdl with clojure with success?

19:17 chouser: st3fan: resolve

19:18 ,(meta (resolve "map"))

19:18 clojurebot: java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.Symbol

19:18 _ato: st3fan: it doesn't work because [test-action] resolves to a value so your vector contains two functions, not two symbols/vars

19:18 chouser: ,(meta (resolve 'map))

19:18 clojurebot: {:ns #<Namespace clojure.core>, :name map, :file "clojure/core.clj", :line 1705, :arglists ([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]), :doc "Returns a lazy sequence consisting of the result of applying f to the\n set of first items of each coll, followed by applying f to the set\n of second items in each coll, until any one of the colls is\n exhausted. Any remaining items in other colls are ignored. Function\n

19:19 _ato: ,(map #(meta (resolve %)) '[inc dec])

19:19 clojurebot: ({:ns #<Namespace clojure.core>, :name inc, :file "clojure/core.clj", :line 618, :arglists ([x]), :inline #<core$fn__4427 clojure.core$fn__4427@4e1e4>, :doc "Returns a number one greater than num."} {:ns #<Namespace clojure.core>, :name dec, :file "clojure/core.clj", :line 763, :arglists ([x]), :inline #<core$fn__4516 clojure.core$fn__4516@86b899>, :doc "Returns a number one less than num."})

19:19 _ato: ,(map #(meta (resolve %)) [inc dec])

19:19 clojurebot: java.lang.ClassCastException: clojure.core$inc__4430 cannot be cast to clojure.lang.Symbol

19:30 Raynes: How would I repeat a function call a set number of times? I naively figured that (repeat 6 (rand-int 10)) would work, but I was wrong. :>

19:31 What I'm trying to do is get a sequence of 6 random numbers.

19:31 raek: does the function have side effects?

19:31 ah

19:31 Raynes: The function is rand-int.

19:32 raek: (doc repeatedly)

19:32 clojurebot: "([f]); Takes a function of no args, presumably with side effects, and returns an infinite lazy sequence of calls to it"

19:32 raek: ,(take 6 (repeatedly #(rand-int 10)))

19:32 clojurebot: (9 4 7 9 6 0)

19:32 Raynes: I see.

19:32 I should have thought of that. :)

19:32 Thank you.

19:33 raek: np

19:44 ben_m: groar

19:44 paredit is annoying :D

19:45 _ato: hehe, takes getting used to

19:45 ben_m: I have (((/ n 2)))

19:45 Because I removed some things

19:45 And I can't remove the outer parantheses :P

19:45 _ato: M-s

19:45 st3fan: _ato, i still don't fully understand the function meta-data stff, but i'll read more first

19:46 ben_m: I have to use Esc-s because urxvt grabs M-s, but thanks :)

19:48 _ato: yeah, the whole point of paredit is the hotkeys for manipulating S-expressions, until you intern them it is a bit annoying, but then you can't live without it

19:49 ben_m: guess so

19:50 _ato: st3fan: yeah it's a little counter-intuitive. metadata is associated with vars, not the actual functions the var is bound to. I don't remember why that is, there's no doubt a good reason

19:51 oh wait.. I just remembered why it is :p

19:52 it's to do with importing things from namespaces. for example you can mark a var private and it won't be imported and you want to be able to do that whether the var is bound to a function or something else

20:44 fradiavalo: ben_m: C-q (paren) to insert single parens

20:45 and C-u del to delete single parens

20:46 ben_m: Thanks :)

20:50 fradiavalo: I wonder if there is a functino ot fix missing parens

20:51 ben_m: I know that there's a function to close all open parens at the end, even without paredit

20:51 Don't remember the name or key though

20:52 fradiavalo: I will try to find that

20:55 ben_m: C-c C-q slime-close-parens-at-point

20:56 I read about it in Practical Common Lisp

20:57 There _is_ a slime-close-all-parens-in-sexp

20:57 C-c C-]

20:57 fradiavalo: excellent! Thanks

21:15 Raynes: ben_m: While I'm memorizing the important keys for Paredit, I've set my desktop background to the Paredit cheatsheet. Comes in handy.

21:19 cup: when fetching n items from a vector, is there a performance difference between getting from the front or the back?

21:21 ben_m: Raynes: I use a tiling window manager, so I don't really have a desktop :)

21:22 Raynes: I'll just keep it open in a browser though until I memorize it.

21:22 Night guys :)

22:30 shmay: i'm going line by line through ants.clj to learn clojure. i'm looking at this line: (defn place [[x y]] (-> world (nth x) (nth y))). why does it use the '->' operator, and what exactly does that operator do (i've looked at the online examples, but am still a bit confused)?

22:31 hiredman: it threads an expression

22:32 (nth (nth world x) y)

22:32 or

22:32 (-> world (nth x) (nth y)) ~ (-> (nth world x) (nth y)) ~ (nth (nth world x) y)

22:36 shmay: hiredman: thanks, so it embeds the expression with the previous expression?

22:36 chouser: shmay: -> is never required, it just allows a smoetimes more convenient arrangement of the code

22:36 hiredman: shmay: the next expression

22:36 ,(-> 1 inc inc inc)

22:36 clojurebot: 4

22:37 shmay: hiredman: right, i think i got it, thanks a lot

22:37 hiredman: there is also a new related macro

22:37 ->>

22:38 ,(-> 1 (nth [:a :b]))

22:38 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number

22:38 hiredman: oh

22:38 ,(->> 1 (nth [:a :b]))

22:38 clojurebot: :b

22:39 annealer: i have what's probably a really dumb macro question. does what im trying to do in this trite example code https://gist.github.com/97ffff695c43b28d3f2b make sense? and if so, why doesn't it.... work

22:40 hiredman: :(

22:40 parens should not be on a new line like that

22:41 and it looks like you are trying to call a macro at runtime

22:41 which you should not do

22:42 shmay: so it becomes the 3rd item rather than the 2nd?

22:43 hiredman: shmay: it becomes the last

22:43 shmay: gotcha

22:43 hiredman: ,(-> 10 range (->> (map inc)))

22:43 clojurebot: (1 2 3 4 5 6 7 8 9 10)

22:45 shmay: :)

22:51 annealer: hiredman: well, im not trying to call a macro at runtime so much as i'm trying to define a macro that calls other macros based on its arguments

23:31 _ato: annealer: is this what you're trying to do? http://gist.github.com/229099

23:31 not sure as your gist seems to have dissappeared

23:42 annealer: _ato: pretty much. thanks

Logging service provided by n01se.net