#clojure log - Apr 12 2009

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

2:35 cp2: lib names inside prefix lists must not contain periods

2:35 whats this about?

2:35 from

2:35 (read-classfile-header (DataInputStream. (FileInputStream. "../t.class")))

2:36 hiredman: ,(doc read-classfile-header)

2:36 cp2: thats my own function

2:36 but, shouldnt matter

2:36 because it worked before

2:36 hiredman: oh no

2:36 clojurebot

2:36 cp2: :(

2:37 i see

2:37 load-lib is throwing it

2:37 (throw-if (and prefix (pos? (.indexOf (name lib) (int \.))))

2:37 "lib names inside prefix lists must not contain periods")

2:37 the hell

2:37 oh

2:37 oops

2:38 mucked up a vector in (ns .... (:use [.....

2:39 hiredman: erp

2:40 ~botsnack

2:40 clojurebot: thanks; that was delicious. (nom nom nom)

3:43 durka42: is my answer to http://code.google.com/p/clojure/issues/detail?id=104 nonsense?

3:53 hiredman: it convinced me

4:36 Lau_of_DK: Top of the morning gents

7:04 Anybody suffered from this? "org.lwjgl.opengl.OpenGLException: Cannot use Buffers when Pixel Unpack Buffer Object is enabled (NO_SOURCE_FILE:0)"

7:05 Its thrown when I try to use createWindow - Its worked flawlessly for ages, but after a reinstall of my OS, it now borks

7:13 hiredman: http://lwjgl.org/forum/index.php?topic=2537.0%3Bwap2

7:15 http://www.jmonkeyengine.com/jmeforum/index.php?action=printpage%3Btopic=6047.0

7:16 the second link looks helpful

7:25 Lau_of_DK: Thanks hiredman

7:25 I think it might be related to the latest nvidia driver, it doesnt give permissions to the video group, do access /dev/nvidiactl

7:27 haha, same conclusion they reached

7:27 Thanks hiredman, you hit it spot on

7:27 hiredman: glad it worked

7:28 Lau_of_DK: Its not working yet, but Im in the right zone now

7:29 gotta restart x, brb

7:33 Ok - something worth noting about LinuxMint - for some reason it doesnt add your primary user to 'video' when creating it - and for some reason, it gets compiz going even w/o....

7:34 (working now)

7:37 hey rhickey , long time no see

7:37 rhickey: good morning

7:46 Lau_of_DK: So rhickey , have you got Gerald J hacking away in Clojure yet?

7:46 rhickey: not yet

7:47 Lau_of_DK: k

9:53 leafw: someone's at work

9:56 hiredman: :D

9:56 *read-eval*

10:58 cconstantine: is there a way to do named optional arguments?

11:02 singhv: yes.. you do it by giving your function multiple bodies. see the code sample here: http://clojure.org/special_forms

11:10 cconstantine: so, it looks like to do optional named arugments the caller needs to pass a map...

11:11 am I reading that right?

11:17 Cark: constantine : that's right

11:18 cconstantine: thats.... slightly awkward

11:20 Cark: would you rather have this be done behind the scene ?

11:20 and pay for the cost of it on every function ?

11:20 lisppaste8: cconstantine pasted "testing optional arguments" at http://paste.lisp.org/display/78450

11:21 cconstantine: I believe in CL it's done as a macro, so the cost is paid at compile-time

11:21 my paste doesn't work for some reason

11:21 singhv: the map way is one way to do it. but by multiple bodies i meant something else:

11:21 dliebke: Most of the functions I write have optional named arguments without the caller supplying a map. I make the map myself using (apply assoc {} options), where the function signature is something like [x y & options]. so the caller can just call (foo x y :opt1 1 :opt2 2)

11:21 lisppaste8: cconstantine annotated #78450 "untitled" at http://paste.lisp.org/display/78450#1

11:22 cark annotated #78450 "untitled" at http://paste.lisp.org/display/78450#2

11:22 cconstantine: oh right

11:22 singhv: it's when you give your function multiple implementations each with different argument lists, and have some of them call other versions

11:22 Cark: constantine : how does CL know on the call site ?

11:23 cconstantine: Cark: not sure, I might be wrong now that I think about it

11:23 singhv: sorry, you said *named* optional arguments - ignore me.

11:23 lisppaste8: cark annotated #78450 "untitled" at http://paste.lisp.org/display/78450#3

11:24 cconstantine: dliebke: that sounds like exactly what I need... could you show me?

11:26 singhv: hehe, yeah I can get optional arguments just fine... I have 3 arguments. 1 is required, the other two are optional

11:26 To be able to specify 0, 1 or 2 of the optional arguments I need to name them

11:28 Cark: you could go like this : (fn [required & optionals] ... then check that every odd argument is the correct name in your function

11:28 but it isn't as good for editors as the map solution

11:28 lisppaste8: dliebke annotated #78450 "optional named arguments" at http://paste.lisp.org/display/78450#4

11:30 cconstantine: dliebke: ok, so you convert the &optional to a map, then pull out keys

11:30 dliebke: yes

11:32 Cark: but slime won't show you the argument list that way

11:34 dliebke: true. So, I write elaborate documentation strings for my functions showing the available options and their default values (but I need to do that anyway)

11:35 Cark: this is only to avoid the braces in your call site ?

11:37 dliebke: yes, I writing a R-like statistical library, and I want my function calls to be as close to the original R syntax as possible.

11:38 cconstantine: http://groups.google.com/group/clojure/msg/51bb53ca077154f8

11:46 It seems like the arguments passed from the caller could be resolved at compile-time, making named optional arguments just as fast as a normal call

11:51 How do I do destructuring in an optional argument?

11:51 nm

11:55 Lau_of_DK: user> (defn foo [a & options]

11:55 (let [[b c d] options]

11:55 (map println [a b c d])))

11:55 You mean like that?

11:55 cconstantine: that kidna works, but that doesn't give me reording

11:55 Lau_of_DK: You asked about destructuring?

11:56 cconstantine: I was thinking an arg-list more like: [req {a :a b :b c :c :or {a 1 b 2 c 3}}]

11:56 and the map can be optional through another arg-list without it

11:57 so a call would look like: (some-func a {:a 1})

11:58 Lau_of_DK: I'd say it depends on the actual case - its not really a matter of destructuring

11:58 cconstantine: that is a destructuring

11:59 it works, but has some { }s in the call

13:17 Cark: " <cconstantine> It seems like the arguments passed from the caller could be resolved at compile-time" what if you change the definition of the called function after the call site is compiled ?

13:30 cconstantine: uh, don't do that?

13:31 what happens if you change the definition of the called function to add an argument?

13:31 or remove an argument

13:33 Cark: that's lisp we're doing here ... very dynamic

13:33 and one of the reasons of named optional arguments is just that, so that you can add argument

13:33 s

13:35 now if your call site is compiled so that it "magically" knows the named arguments, you'de better make sure the algorithm takes into account the possibility that some arguments might be added, or the order of arguments might change

13:35 so in the end you keep the runtime cost

13:36 you still need to look the name up at runtime

13:38 cconstantine: so what happens if you add an argument to a function and the call sites aren't recompiled?

13:38 I'm not saying it isn't a problem, but I'm not seeing why it isn't a problem for regular arguments

13:39 Cark: it's a problmem for regular arguments

13:39 not so for optional arguments

13:39 cconstantine: but it isn't a problem for optional arguments through a &rest because that's passed as a list

13:39 Cark: right

13:43 cconstantine: so why not just have it be a runtime failure when the arguments change same as with regular non-optional arguments?

13:44 Cark: one of the purposes of named optional arguments is precisely to let you add them or change their position without causing any problem

13:44 that's in my opinion anyways

13:46 cconstantine: ah, I just want to be able to have a a set of arguments that aren't required

13:47 if they aren't named you have to have preceding arguments in the argument list

13:47 Cark: there is a construct in the language to do what you want, and it's stricly more powerfull than what you need

13:47 so what's the trouble ?

13:48 cconstantine: I guess the trouble is I don't know it :)

13:48 Cark: well we showed that to you earlier

13:49 Lau_of_DK: clojurebot, seen technomancy?

13:49 cconstantine: optionally passing in a map?

13:49 Lau_of_DK: ~seen technomancy?

13:49 clojurebot: no, I have not seen technomancy

13:49 Cark: constantine : that's a way to do it yes

13:50 cconstantine: Cark: that (and the other options) is close enough, but not exactly what I want

13:50 Cark: you want CL style named parameters

13:51 right ?

13:51 cconstantine: basically yeah.

13:52 Cark: you could make your own defn macro if that's absolutely what you want

13:52 but it seems a lot of work for something that's already there

13:52 i would argue that the clojure way is best

13:52 you have two orthogonal concepts

13:52 cconstantine: eh. We can disagree because the clojure way works :)

13:53 Cark: on concept is destructuring

13:53 and the other one is function call

13:53 they're kept separate

13:53 cconstantine: right

13:54 Cark: in CL, you have destructuring (destructuring-bind) and destructuring arg lists

13:54 that's mudying the waters !

13:55 cconstantine: if I didn't want muddy waters I'd be in scheme... but I want to get stuff done

13:56 Cark: right, so why not use the existing facilities ?

13:57 cconstantine: it forces me to either redefine how to define functions, or rewrite a pattern every time I want to use it

13:58 Cark: by pattern ? you mean the curly braces

13:58 ?

13:58 cconstantine: right now, I'm just using the pattern, and forcing callers to pass in a { ... } for optional arguments

13:58 there is a call-side pattern (the curly braces) and a caller side pattern (accepting no options and passing in a {}

13:59 s/caller/callee

14:00 Cark: in order to avoid the problem with calers not needing any argument you can define you function like this : (denf bleh ([required] (bleh required {})) ([required {:keys [a b c]}] ....))

14:00 clojurebot: this is not a bug

14:01 cconstantine: right, that's a pattern

14:01 it works, but it's something that could be standardized and abtracted away with a standard macro

14:01 Cark: well then make a macro and be done with it =P

14:04 cconstantine: might, but it would be nice to have to macro extend to the call-site and do it there.

14:04 I'll have to think it through a bit more, and try to get it into clojure.contrib

14:05 Cark: first you would need to change the way function calls work

14:05 that cannot be done with a library i think

14:05 second i don't think that's a good idea

14:06 cconstantine: if the macro (defn-with-optional-named-arguments some-func [ ...]) made a macro named some-func that called a gensymed func

14:06 it could even wrapp the macro in a (var ...) to make it passable

14:07 Cark: then you can't map it anymore

14:07 cconstantine: all the call-site macro would do is convert a (some-funct a) to a (some-funct a {})

14:07 can't map it?

14:07 oh, like (map ...)

14:08 Cark: yes

14:08 cconstantine: I believe there is a way to do that (to be able to pass 'or' and 'and')

14:09 Cark: #(or %1 bleh)

14:09 this goes to show there are troubles anyways

14:10 cconstantine: no, I mean a simpler way

14:12 yeah, it's (var macro)

14:14 eh, the more I think about it the more this has problems with functions used as higher order funcs

14:15 'this' being a macro that makes a macro

14:36 Lau_of_DK: cconstantine, Im sorry I didnt see your question before now http://failblog.files.wordpress.com/2009/02/fail-owned-ownership-fail.jpg?w=500&h=112 ... Did you get this resolved?

14:36 cconstantine: mostly yeah

14:37 Lau_of_DK: Good

15:17 durka42: ,(var or)

15:18 yason: When moving data around like in tuples or small lists, is it more idiomatic to use vectors or lists?

15:18 durka42: ,(var or)

15:18 clojurebot: #'clojure.core/or

15:21 durka42: i might use a vector

15:21 depends on what you're doing with it though

15:22 yason: durka42: vectors seem more natural since there's better syntax for creating them

15:23 durka42: mostly they'll just end up in some other place, probably deconstructed into variables

15:24 lists and dotted pairs are just more traditional in lisps -- might not hold in clojure though :)

15:25 when would it be more sensible to use lists?

15:25 durka42: well, vectors are faster for random access

15:26 lists are better for appending and prepending

15:26 yason: so new copies of vectors are made when something is added in them?

15:27 durka42: well, yes and no

15:27 data structures are immutable

15:27 so you always get a "new" one

15:27 but it will be mostly copy-on-write

15:27 yason: (as opposed to lists consed together from new heads and old tails)

15:28 Chouser: vectors are faster for appending, lists faster for prepending

15:28 durka42: http://clojure.org/data_structures

15:28 Chouser: yason: for your general question, I think vectors are most often slightly more idiomatic

15:29 yason: Chouser: that makes sense, you can extend vectors easily and you can (cons head old-list) more naturally. So is there any other essential differences besides random access and prepending/appending?

15:30 Chouser: Ok, I guess I'll go with vectors then. Just wanted to check I'm not abusing them somehow. I'm just used to Lisps where vectors are maybe less generic than lists.

15:33 Anyway, I think Clojure is pretty damn great and programming with it is great fun. I've also realised that JVM is actually rather nice as soon as you stick a real language onto it, which I would probably have missed without Clojure. :)

16:09 cconstantine: I've got a weird problem... pasting

16:10 lisppaste8: cconstantine pasted "cconstantine" at http://paste.lisp.org/display/78466

16:29 digash: how does one destructures Map into key values?

16:29 ,(let [[key val] {:a "a" :b "b"}] [key val])

16:29 clojurebot: java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap

16:30 digash: oops, ignore my stupidity.

16:31 i've obviously wanted a doseq or first.

16:31 ,(let [[key val] (first {:a "a" :b "b"})] [key val])

16:31 clojurebot: [:a "a"]

16:33 * digash needs to take a break from coding for too many hours.

18:03 cconstantine: Who do I talk to for a code-review and possible inclusion in clojure-contrib?

18:20 danlarkin: the mailing list

18:54 Raynes: Has anyone noticed how massively boring Scala is? :|

18:55 danlarkin: if you don't have anything good to say...

18:56 hiredman: you know #scala had a vote and decided not to log the channel

18:56 bizzare

18:57 digash: My coworker bought the Scala book and the firs mention of concurrency is somewhere after p700.

19:04 gnuvince_: I find that most statically typed languages are much more complex than dynamic ones.

19:04 Compare Clojure, Python, Smalltalk and Factor to Scala, C++, Java and Haskell and tell me the first four are not much simpler than the latter 4.

19:07 digash: "Our main goal is to ensure race safety with a type system that's simple and expressive enough to be deployed in production systems by normal users."

19:07 -- http://lamp.epfl.ch/~phaller/uniquerefs/

19:07 I feel that I am not "normal user".

19:08 Raynes: danlarkin: Oh, it's good enough to make me hate Java even more, but it's still boring.

19:09 gnuvince_: Raynes: I agree that Scala doesn't seem to have the "oomph" effect of Clojure or Haskell.

19:15 cp2: 18:04 < gnuvince_> Compare Clojure, Python, Smalltalk and Factor to Scala, C++, Java and Haskell and tell me the first four are not much simpler than the latter 4.

19:16 oh yeah

19:16 definitely

19:16 i find it funny, all of my friends who are using c++, java, tell me 'oh clojure is so complex because of all the parentheses' etc

19:17 gnuvince_: There's something about knowing all the quirks and exceptions of C++ that people find so appealing.

19:17 cp2: heh

19:17 gnuvince_: "Wow, you must really be a good programmer if you know what a private virtual static friend function is!"

19:20 Raynes: Anyone who says Clojure is complex or bad because of the parentheses needs to be killed. :|

19:20 hiredman: thats kind of harsh

19:20 danlarkin: yeah I don't really get where your anger comes from Raynes

19:20 hiredman: maybe shipped off to a re-education camp

19:22 Raynes: Well, not literally...

19:26 * Raynes watches a fight emerging in #Haskell. This channel is truly a safe haven of like minded people. I've never seen anything worse than an intelligent debate take place in here.

19:29 StartsWithK: anyone used Cloak to automate tasks from clojure?

20:09 Raynes: I want to learn Forth.

20:10 pstickne: so learn it :)

21:27 Chouser: rhickey: spent any more time on self-hosted clojure?

21:34 rhickey: Chouser: only in thinking about namespaces and modularity. I'm trying to get all known issues on the table in looking at self-hosting. A big one is the mismatch between namespaces and the way Java and especially Java module systems (OSGi etc) look at things

21:34 Chouser: ok

21:34 rhickey: there's a fundamental conflict between all-ns and modularity

21:35 Chouser: for better modularity you'd need some namespaces to be visible to less that the whole clojure world?

21:35 rhickey: yes, and to track class visibility in general

21:36 it dovetails with classloader issues, which are still a pain

21:36 Chouser: indeed

21:37 rhickey: the fundamental problem is you can't do classForName on behalf of someone else, i.e. in library code

21:38 Chouser: where "someone else" is a different modules of the OSGi variety? Or where "someone else" is any other lib?

21:40 rhickey: It comes into play with regular classloaders - i.e. if a child classloader can see something Clojure's classloader can't, it can't successfully import it, because it is library code in Clojure that calls classforname

21:41 Chouser: ok, and the jvm is paying attention to the class that owns the method doing the actual classForName call?

21:42 rhickey: You can use context classloaders, but then you need to know that is happening, and most of the module systems don't. They are presuming the immediate consumer calls Class.forName, which does a stack walk to find the classloader of the caller (which could be a bundle classloader) and all works fine - try to proxy the forName call and it fails

21:42 The bottom line is namespaces need to be found the same way classes are found

21:43 So, my thinking is a connection between com.my.ns and com.my.ns$Namespace.value, where the latter is a clojure.lang.Namespace

21:44 get rid of the master namespaces collection

21:44 in a modular system, namespaces should be no more fully enumerable than classes - i.e. not at all

21:45 Chouser: interesting

21:45 if I've got the a namespace object, getting to the package where all its classes are defined is easy

21:46 rhickey: this will provide many benefits, including the ability to load most of Clojure just once and share it with many ephemeral loading contexts, be that web apps, or NetKernel stuff, or OSGi...

21:47 Chouser: and for any given namespace name, finding the namespace object is also simple -- computed both ways then, right, no further connection needed?

21:47 rhickey: making namespaces align with classloader and module visibility is key

21:48 Chouser: right, namespace-name leads to class leads to namespace object, not sure about the need to go the other way

21:50 this obviously impacts the compiler - it can't presume a single global namespace world, and will need to generate code that will leverage the visibility it will have when loaded (i.e. it may be able to see things clojure.lang can't)

21:50 clojurebot: this is not a bug

21:51 Raynes: I wish they made bags of nothing but buttered popcorn jelly beans. :\

21:53 Chouser: Raynes: http://www.jellybelly.com/Shop/ProductDetail.aspx?ProductID=40137&ProductGroup=Buttered_Popcorn

21:53 Raynes: O.O

21:53 Chouser: that's a case of 24 bags, 3.5 oz per bag. Should hold you for a while.

21:53 Raynes: Chouser: You're my hero. hiredman: You're off the hook.

21:58 Chouser: rhickey: does that mean that any runtime reflection would have to be done differently?

21:59 as in, not in a library that may not be allowed to look at the class being reflected upon?

21:59 or could it examine an instance of Class that's specifically passed in?

22:07 lepassive: Hi anyone using Enclojure with NetBeans 6.7 ?

22:08 rhickey: Chouser: I don't think there will be issues there

22:09 Raynes: I don't think Enclojure supports NetBeans 6.7, but I might be incorrect.

22:09 lepassive: Raynes, that's right I can't get it working with 6.7 :(

22:10 Raynes: lepassive: I believe there is a thread about it on the Enclojure group.

22:12 lepassive: Raynes, thanks alot i found the thread

22:13 Raynes: lepassive: No problem. Good luck.

22:46 Mec: how does java reference string regex captures?

22:47 hiredman: $1

22:48 ,(.replaceAll "22nd" "(\\d+)nd" "$1ND")

22:48 clojurebot: "22ND"

22:48 Mec: thanks, tried \1 and got some bizarre results :D

22:49 hiredman: yeah

Logging service provided by n01se.net