#clojure log - Nov 21 2008

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

1:58 Pupeno: Good morning.

2:00 Is there any docs on writing macros? I would have expected the macros section in the reference was about it.

2:07 H4ns: Pupeno: pcl has a section on macros, and on lisp covers them in depth.

2:07 Pupeno: a reference is not meant to be used to learn

2:07 Pupeno: (in the sense that a tutorial or user manual is)

2:18 dang!

2:18 Pupeno: apologies, i was in the wrong channel context :)

2:19 Pupeno: i'd still say that my recommendations are kind of helpful, but certainly to a lesser extent

2:24 Pupeno: H4ns: ok, thanks.

4:05 leafw: away txu txu

5:58 Pupeno-G: Hello.

5:59 I have a Java method with the signature: blah(String�a, String�e, long�i, boolean�o); am I calling it wrong by calling it like (.blah ClassName "a" "e" (* 1000 (.currentTimeMillis System)) false)?

6:01 tWip: you left out part of the signature

6:01 is it public and static or something else?

6:02 Pupeno-G: tWip: public, non-static.

6:03 tWip: then you can't call it on the class

6:03 Pupeno-G: void.

6:03 tWip: you need an instance

6:03 Pupeno-G: Sorry, just wrote it wrong here, I am using an instance.

6:03 tWip: then I believe that should be correct usage

6:03 hiredman: hmm

6:03 maybe wrap the time in (long ...)

6:04 tWip: and static calls I'd prefer (System/currentTimeMillis)

6:04 Pupeno-G: hiredman: that was it, thanks!

6:04 tWip: thanks.

6:04 hiredman: working code first, pretty code after

6:43 Pupeno-G: How do I use generics from Clojure, in the sense of how do I do this: new HashSet<String>(), from Clojure? (new HashSet ???)?

6:44 Chousuke: I'm not aware of any way to do that.

6:45 just use a non-specialised HashSet?

6:45 it's just a compile-time thing anyway

6:45 Pupeno-G: Chousuke: I'm not really working with HashSet, that was just an example. Anyway, thanks.

7:21 askentask: how about lisp and static typing? how hard is it to implement static typing on a lisp? and i mean haskell-like static typing, not java-esque

7:25 philscotted: Pupeno-G: Dynamically typed languages have no real need for generics (parametric polymorphism).

7:26 askentask: I suspect some would say that if you have static typing, you no longer have a lisp.

7:47 askentask: hehe, but i dont build it into the language, i just have a clojure-rpogram that typechecks. and anyway there optional static typing for common lisp.

7:47 also i dont really get the advantage of dynamic typing except for less typing. what are the non-superficial advantages of dynamic typing?

7:48 tWip: Many lisp compilers do type analysis for efficiency

7:55 philscotted: askentask: There are some things you just can't do without dynamic typing. A human being can make type-correctness guarantees that a static type checker cannot.

7:55 askentask: but i want to do it for saftey

7:56 philscotted: tWip: Yes, but I wouldn't call that static typing.

7:59 askentask: Also, you can have statically typed languages where you don't have to write all your types out by hand, so dynamic typing is not about less (keyboard) typing in that sense.

7:59 askentask: phil: yes in haskell but in other langs, java c++ its a lot about it

8:00 but ok i sees the point about humans being able to typecheck where a static typechecker cannot

8:01 philscotted: askentask: Right, but I consider those to be pretty impoverished languages, and not really worth comparing to.

8:01 tWip: static typing requires the whole program to some extent

8:01 and is not compatible with the lispy repl coding approach

8:01 askentask: but as programsize grows id like help on that verification by a program. mostly it is the simple stuff i need to get fixed. like if forget to change something somewher eand it says "1" + 4, those are the things a static system would fo better than me

8:02 tWip: i find the ghci haskell repl to be quite good(ebven if it doesnt allow the whole ghc)

8:02 tWip: never really developed anything in ghci repl

8:02 but I develop in a lisp repl all the time

8:03 philscotted: tWip: Right. Redefining functions on the fly, for instance. You can't do that with ghci.

8:05 tWip: especially good with server software that has a long startup

8:15 philscotted: askentask: In practice, I haven't found those sort of type errors to dominate, and I certainly haven't found them to be a big deal. Besides, with a decent Lisp allow interactive testing and allow you to rebind functions at the toplevel and have the effects propagate properly (unlike Python, say),

8:15 Whoops, pressed return too soon.

8:16 In practice, I haven't found those sort of type errors to dominate, and I certainly haven't found them to be a big deal. Besides, with a decent lisp you can interactively test your functions to iron out those sorts of errors, and when you can rebind functions at the toplevel and have the effects propagate properly (unlike Python, say) you can get rid of those errors pretty quickly.

8:17 In the end, I find the advantages of a dynamic language to be far greater. And in something like Common Lisp, the combination of a debugger and condition system may allow you to correct any missed errors on the fly and continue running the program as if nothing had ever happened.

8:18 Pupeno-G: It seems I can import a.b.C.D in Clojure where C is a class and D is a subclass (public static), while in Java I can; can anybody confirm?

8:18 rhickey: the name of that nested class is a.b.C$D

8:19 you can (import '(a.b C$D))

8:22 Pupeno-G: I meant "can't", but I think my question was clear anyway.

8:22 rhickey: I see, but then everytime I mention the class I have to do C$D; would it be possible to mimic Java's behavior here?

8:23 rhickey: Pupeno-G: No, dots have too many meanings already

8:23 askentask: philscotted: how do you mean propagate properly? or i know what you mean by that but when doesnt it in python?

8:23 Pupeno-G: rhickey: ok then.

8:24 philscotted: In Python, when I redefine a class at the toplevel, existing instances of that class are unaffected. This is really annoying for interactive testing and debugging.

8:25 askentask: i like also like in haskell i can do: :type f and it tells me specifially what it does rather than jus the variable name. if i do in clojure: (defn update [coll index newlist]...) i want to do :type update and get: [[a]] -> Int -> [a] -> [[a]]

8:26 i see about servers yes, so instead of restarting the program you can change things at runtime, that wouldbe a great advantage yes

8:26 philscotted: askentask: Not sure how Clojure behaves on this one. But CLOS will call change-class on all instances when you redefine classes.

8:26 rhickey: askentask: except collections can be heterogeneous

8:26 askentask: phil: ah ok

8:26 duck1123: is it possible to alias a nested class?

8:26 philscotted: askentask: Yes, static typing can be really nice for automatic documentation.

8:27 rhickey: philscotted: it comes at a cost in expressivity

8:27 Pupeno-G: I have just realized I hate Haskell.

8:28 philscotted: rhickey: Yes, of course. But I've already mentioned some of the disadvantages of static typing.

8:28 blackdog: not to mention the code explosion, I just find it easier to deal with less code

8:29 rhickey: duck1123: there's no class aliases at this time

8:29 Pupeno-G: Now I am always afraid a collection will come with one item of an unexpected type and I can't do anything about it. I didn't use to be afraid. I'll take it to my psychoanalyst.

8:31 duck1123: I used to argue for static typing all the time. Now I feel the opposite.

8:32 askentask: lol

8:32 what have i done?

8:32 bringing this up

8:32 when i write in static langs i msiss dynamic typing, when i write in dynamic langs i misss static typing

8:32 Pupeno-G: duck1123: I change polarization about 6 or 7 times a year :S

8:35 gnuvince: askentask: welcome to the club

8:36 duck1123: PHP4 soured me on dynamic typing for quite a while, Ruby brought me back

8:36 Pupeno-G: I'd like clojure-mode to change between different possible tab levels when tab is pressed again, like the python mode (for semantic purposes) or that cool javascript mode (for extra coolness and because Javascript is a mess).

8:37 duck1123: I hate that about js2-mode

8:38 it would be okay if I had to modify the tab to change it, but I tend to hit tab randomly on lines to make sure they're indented properly

8:38 gnuvince: You just need to remember not to try and code like you have a dynamically typed language when you're using a statically typed language and vice-versa

8:39 philscotted: Ocaml's static duck typing is another matter though. Here, an object is automatically typed by an implicit interface which includes precisely those functions which are actually *required*. It allows for a lot more flexibility, heterogenous collections (without the headache of defining variant types). However, it's part of the OO extensions (which I tend to avoid anyway), is restricted to single-dispatch. Oh, and it's Ocaml.

8:39 H4ns: Pupeno-G: with lisp, there usually is one (1) correct indentation for every line.

8:39 Pupeno-G: duck1123: the first tab should leave it where it is if it's a valid tab.

8:39 H4ns: maybe I have weird indenting habits.

8:39 lisppaste8: url

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

8:39 H4ns: Pupeno-G: yes. change them.

8:40 duck1123: you guys should see the formatting of some of my old XQuery

8:42 lisppaste8: Pupeno pasted "Which indentation do you prefer, the first or the second?" at http://paste.lisp.org/display/70818

8:42 Pupeno-G: H4ns: can you answer that paste?

8:42 * hoeck prefers the first

8:43 H4ns: Pupeno-G: certainly - i would prefer the first, but i always stick to what the editor does for me. that is the only way to get consistent indentation. reasonable editors provide you with hooks to control your indentation.

8:43 Pupeno-G: H4ns: but clojure-mode gives you the second, and it doesn't have any way to know you want the first.

8:43 duck1123: I tend to fiddle with my code to get it to look the way I want

8:44 Pupeno-G: duck1123: but then your random tabs break it, where tab-switches-indentation-unless-it-is-in-a-correct-spot doesn't do it.

8:44 H4ns: Pupeno-G: you can certainly customize clojure-mode so that it indents correctly.

8:45 Pupeno-G: H4ns: if you mean modifing it for each library out there, then, no thanks.

8:45 lisppaste8: duck1123 annotated #70818 with "another way to indent" at http://paste.lisp.org/display/70818#1

8:46 Pupeno-G: duck1123: I sometimes do that, but I end wasting too much vertical screen.

8:46 duck1123: while not adding clarity.

8:46 H4ns: Pupeno-G: usually, you can customize lisp mode with a simple regular expression - for example, one that makes a 2 space indent for forms containing with- or without-

8:46 Pupeno-G: it could even be in place, but be defeated by your namespace prefix.

8:47 Pupeno-G: H4ns: true, but that's going to fail sometime, while the tab-cycling doesn't.

8:47 duck1123: I do whatever it takes to make it look as close to what I want to see as possible without changing the default

8:47 H4ns: *shrug*

8:54 askentask: can parameters be caleld anyhting without clashing with builtin names?

8:56 tWip: (defn foo [defn] (+ defn 1))

8:56 seems to work

8:56 rhickey: askentask: other than for special ops

8:57 philscotted: See http://clojure.org/evaluation

8:57 Pupeno-G: It would be nice if the "No matching method found"-error would list the argument types used in the call, not only the name of the method.

8:57 philscotted: rhickey: And if the symbol is bound to a class, according to your docs.

8:57 rhickey: philscotted: right

8:58 askentask: hmmim rewriting my clojure-oo-system. used refs from the start but yesterday someone said just pass along the updates without refs might be better. I want it o to fit in with clojure-style programming. and i want something a bit more elaborate than defstruct.

9:04 hmm im wondering should i have refs in the class or refs or soemthinc classes get assigned to later. i must separate the definition of a class from the creation.

9:05 rhickey: askentask: If you really want to do an object system for Clojure, you need to totally understand this: http://clojure.org/state

9:10 philscotted: rhickey: Actually, just testing out that evaluation order stuff. If I do (import '(java.io PrintStream)) and then "(defn foo [PrintStream] PrintStream)" shouldn't foo return the java class rather than its argument?

9:12 rhickey: philscotted: no, argument will hide it when used as a value like that

9:13 but (new PrintStream ...) would still work

9:16 Chousuke: askentask: if you find yourself using a lot of refs in your object system, you're probably doing it wrong.

9:18 lisppaste8: cemerick pasted "rhickey: no tagging on auto" at http://paste.lisp.org/display/70821

9:18 cemerick: hrm, that title didn't come out right...

9:20 Chouser: cemerick: you could re-def vector-color to something of a different type.

9:20 cemerick: Chouser: ...at which point the :tag could be updated, no?

9:20 Chouser: later, I mean, and cause an auto-hinted vector-stroke-color to do something other than what you meant.

9:21 cemerick: I guess that makes binding more complicated.

9:22 Chouser: the :tag would be used when compiling vector-stroke-color -- I'm not sure you'd want a change to :tag later to go through and recompile all code that referd to that var.

9:23 Lau_of_DK: Afternoon gents

9:23 rhickey: cemerick: you can hint vector-color itself

9:23 cemerick: Chouser: ah, right

9:24 rhickey: yeah, I know. I just hadn't yet thought through the ramifications of auto-tagging vars

9:24 rhickey: auto-tagging is the enemy of heterogeneity

9:25 now, if I add defconstant...

9:27 cemerick: ...and all the shades in between. I often know that some var will always be bound to an object of a particular type, but I do need to rebind it as necessary. defconstanttype :-P

9:27 rhickey: cemerick: just tag it then, there are all kinds of issues about what type to assign - most-derived, least-derived, which of n interfaces etc

9:28 cemerick: Yeah, I wasn't actually suggesting a new def-form.

9:30 rhickey: cemerick: have you tried AOT gen-class yet?

9:31 cemerick: rhickey: No, not yet. I'm buried from a number of directions. I think wwmorgan may have, but I'm not sure.

9:31 I may get to take a look at it over the holiday. I've been watching the developments, though, everything looks to be falling into place.

9:40 Pupeno-G: do you same examples or samples when refering to programs provided as examples?

9:40 or samples.

9:44 Chouser: Pupeno-G: that's a question about English? "examples" usually.

9:44 Pupeno-G: Chouser: yes, english; I never cease to be puzzled by that language.

9:45 sorry for the off-topic, but we were quiet anyway.

9:45 Chouser: np

9:46 askentask: i have this confusion. so i need to define general methods for a class that can then be called by each instance. so i need some from of "self". so should each instance carry a dict with {:my-personall-attributes some-values :general-class-spec spec} where personal-attributes correspond to something n general-class-epc

9:48 meh i need some better teaches, did high school suck for you guys too? we do so much pointless stuff but i have noone to discuss or go to for programming. seriously i have to memorize 80 different fookin birds for a biology class but when i want to learn programming i cant get any help

9:51 Pupeno-G: askentask: if you want to really learn programming, go through SICP, at least, the lectures.

9:51 Chouser: askentask: I sympathize. But at least in my experience, one is generally encouraged if not forced to specialize as you get older. It may be hard to think of it this way, but right now you have an opportunity to learn about birds, history, etc. that may be hard to come by later.

9:53 We had no programming courses at my high-school, or anyone around that could help in that area. Books were it. (No internet then either, at least for me.)

9:53 duck1123: can the path to slurp be relative to the classpath, or must it be absolute?

9:53 Chouser: duck1123: slurp doesn't honor classpath

9:54 askentask: poor you, wikipedia is at least a great help on grasping basic concepts

9:54 Pupeno-G: I had C, Basic and Assembler in high school, but by the time I've got there, I got mostly recruited as teacher helper; so they didn't help me much, but I've got a chance to help others.

9:55 rzezeski: +1 on SICP, still going thru them, very informative. I already have a CS degree and it is teaching me a lot

9:55 Pupeno-G: rzezeski: indeed! if it wasn't for SICP, I wouldn't have my current job.

9:56 duck1123: so, what would be the best way to find a file in my project if I don't know where the code will be sitting?

9:57 rzezeski: I taught myself VB in high school, then I learned C++ senior year of HS and throughout College, then started using Java late College and now in my career.

9:57 duck1123: I started with Atari Basic in 3rd grade

9:57 rzezeski: We studied FP briefly in our AI and Programming Languages class, but about a year ago I finally came back to it by checking out Haskell again

9:58 Chouser: duck1123: I've used: (.getResourceAsStream (clojure.lang.RT/baseLoader) file)

9:58 Chousuke: askentask: your instances could contain a reference to the class object, a map of attributes, and maybe some metadata. the class object then could contain a map of functions defined for that class.

9:58 rzezeski: SICP is teaching me loads though, awesome that you can get such a great resource for free!

9:59 Chousuke: However, I don't see a reason to make anything that complicated. Though it might be good practice if you want to try and understand the concepts.

10:00 askentask: which is?

10:01 Chousuke: If I needed something OO with clojure I'd probably just use maps of attributes and values and call them objects :P

10:02 or I could use java I guess :/

10:03 philscotted: rzezeski: SICP really makes me embarrassed about the quality of teaching at my university. Not sure if that is just a rare jewel of MIT, or whether they have consistently good teaching material.

10:04 rzezeski: I think it's MIT

10:04 Pupeno-G: philscotted: do you know that they ditched Scheme for Python to teach that class? I think it might have been a rare jewel (possible much more rare outside MIT).

10:04 rzezeski: personally though, if I had the choice (and the grades) I'd prefer CMU

10:05 philscotted: Pupeno-G: Ugh. At least they didn't ditch Scheme for Java. The uni where I did my undergrad had an amazing course on OO, taught using Smalltalk. They've now ditched it for Java.

10:14 Speaking of Scheme and Java, does anyone know what Guy Steele was talking about when he suggested Java brings C++ programmers half-way to Lisp?

10:15 Chouser: philscotted: I know very little, but a couple things come to mind: reflection, heterogeneous collections, garbage collection

10:17 philscotted: Chouser: Right. I suspect, then, I would very much disagree with his metric. I'm not even sure Java is halfway to Smalltalk.

10:20 askentask: hmm i cant by the problem that i have a hard time doing this without defs. i could if letting the class-specification being a ref that all instances refer to. instance being a map to :spec and :instance-attributes

10:24 philscotted: If we get indexed HTML documentation for Clojure functions, it might be cool to have a :see-also tag on function and macro symbols, pointing to the web page (or general URI resource).

10:25 Users could then add their own see-also tags which can be used by developer tools.

10:25 rhickey: By the way, I really like the documentation strings and metadata system.

10:31 duck1123: I would like to see people using markdown or something similar in documentation strings

10:31 cemerick: oh noes, not markdown! :-P

10:31 * cemerick feels a bike shed discussion coming

10:34 duck1123: I'm curious, why not? I don't really have strong feelings for it, but I know some other languages use it or similar in their documentation.

10:37 philscotted: Only just looked at it, but my first worry would be that the syntax for emphasis in markdown conflicts with the Lisp convention of surrounding special variables with *.

10:38 I think if we want structured, semantic-rich documentation, we should use an s-expression format.

10:38 askentask: if you need a graph datastructure, how would you create one? here is where Clojure clashes with my brain. in Python I could make a class for Node, Edge etc and specify their behaviour. but what would you use n Clojure?

10:39 cemerick: duck1123: the syntax requires rote memorization. For the small amount of formatting that docs generally require, it's a whole lot easier to just use html

10:40 philscotted: Given that clojure is jvm-centric, I think conforming to the javadoc conventions and then somehow injecting docstrings into the javadoc tool would be ideal, especially given AOT compilation being a good vehicle to provide public APIs.

10:40 Chouser: askentask: you need a graph not just a tree?

10:41 philscotted: askentask: A pure functional way to do a graph would be to have a set of vertices and a map from this set to the set of edges.

10:42 Chouser: {:a #{:b :c} :b #{c} :c #{}}

10:43 duck1123: cemerick: I would love to see clojure code produce actual javadoc documentation.

10:43 I hate the format of javadocs, but there are plenty of tools to make it better

10:43 cemerick: duck1123: I think it'll happen, but we'll probably have to generate java source containing the docstrings in order to run javadoc over them.

10:43 philscotted: cemerick: But it would be good to use sexpr to represent the javadoc documentation, and then have clojure manipulate it for consumption by the javadoc tools.

10:44 cemerick: philscotted: how would you represent javadoc docs using sexprs? It's fundamentally HTML, with type/method/field references here and there.

10:46 Chouser: clojure docs are already represented in clojure data structures (namespaces of vars with map metadata), so consuming that and spewing whatever javadoc needs seems like it should be straightforward.

10:46 philscotted: cemerick: There are loads of ways you could do it. Are there not standard tools to convert javadoc comments to XML? There are standard tools to convert from and between XML and sexpr. So we probably wouldn't need to do anything.

10:46 cemerick: Yeah, it's just a matter of wiring things up. Generating source code kinda sucks, though. :-/

10:47 philscotted: Chouser: At the moment though, the docs are just strings. There is no explicit documentation for individual function arguments, for instance.

10:47 cemerick: philscotted: javadoc comments are strings that are interpreted by the javadoc tool to produce HTML. I'm sure there's tools out there to emit XML instead (and pdf's, etc), but they all work with Java source files.

10:48 philscotted: That's what the standard javadoc annotations are for (@param, etc)

10:48 Chouser: but we don't want @param in .clj files though

10:49 cemerick: Chouser: something like them needs to go somewhere.

10:49 especially if we want actual javadoc output

10:50 philscotted: Chouser: No, but the metadata could contain :arg-doc which maps to another map between the argument symbols and documentation for each one.

10:50 duck1123: on the subject of javadoc, is the javadoc for clojure posted anywhere?

10:51 philscotted: Chouser: Not that any of this is particularly important. But if semantically rich documentation gets added to Clojure, I hope it is in the form of Clojure data structures.

10:51 cemerick: I don't think we'd want to start scattering documentation fragments in multiple places.

10:52 philscotted: I'm still wondering what that "richness" gets you

10:52 philscotted: cemerick: Ah right. javadoc won't consume anything other than java source?

10:52 cemerick: philscotted: exactly

10:52 it's hardwired into the compiler

10:52 gnuvince: Is "taxonomy" a synonym of "hierarchy"?

10:52 cemerick: I looked into it in some detail about a year ago to see if I could generate unified javadoc from java and scala sources.

10:53 duck1123: gnuvince: more a taxonomy is a hierarchy i think

10:53 philscotted: cemerick: For instance, when writing a form, Slime could spit out the documentation for each function argument as I type it, by inspecting the metadata.

10:55 cemerick: Generally, I want the possibility of doing such things.

10:55 cemerick: philscotted: Yes, that might be cool, but getting there with sexprs makes all of the common use-cases more complicated. To start, every fn would need two forms of docs -- a docstring, as well as a metadata map with an :arg-doc entry

10:56 Just grepping the docstring for pairs of @param annotations seems a lot better on all fronts.

10:56 Chouser: I'm with philscotted on this one

10:57 * cemerick shrugs

10:57 philscotted: cemerick: Docstrings are already optional. I think using plain text and preprocessors which have to do the parsing is failing to take advantage of lisp.

10:57 Chouser: imagine (defn foo "does foo things to a and b" :a "tastes like apple" :b "looks like a bee" [a b] (+ a b))

10:57 hm, messed that up, didn't I

10:57 oh, no, that's right.

10:58 cemerick: Chouser: and :a and :b get slotted into foo's metadata's :arg-doc map?

10:58 Chouser: or maybe 'a or just a instead of :a

10:58 cemerick: right

10:58 just like a plain string gets put in :doc

10:59 defn's looking for a vector or a list that begins with a vector for the function args and body. So anything else can have new meaning -- plain string is :doc, plain symbol followed by string could be an :arg-doc

11:00 I think I like the plain symbols, because then keywords could be used for other things. perhaps :returns "the result of doing foo things"

11:00 cemerick: well, it's syntactically it looks fine. Certainly makes the java source generation for javadoc more complicated, but that's a one-time job I suppose.

11:02 duck1123: you would also be able to read them with meta, and perhaps eventually doc

11:02 Chouser: but if we wanted to generate anything other than javadoc, not having to parse out the @params would make the job much easier.

11:03 askentask: My neighbours daughters friend is getting married to a friend of Bill Gates, she is 28, he is 63.

11:03 cemerick: there is only one doc format, and its name is javadoc ;-)

11:03 askentask: My neighbours daughters friend is getting married to a friend of Bill Gates, she is 28, he is 63. in gothenburg, sweden

11:03 haha

11:03 lol in it for the money?

11:03 Chouser: it's interesting that for pure functions the main doc string might go away. once you've described the arguments and the :return value, what else is there?

11:03 Chousuke: doc could be made a bit more general I think. currently it seems to assume the things documented are functions or macros :/

11:04 duck1123: :side-effects true

11:05 askentask: (defn def-method [for-class f]

11:05 (let [spec (get for-class :spec)]

11:05 (dosync (alter spec assoc :methods f)))

11:05 Chouser: duck1123: does 'do' have side-effects?

11:05 askentask: java.lang.Exception: Unable to resolve symbol: for-class in this context

11:05 clojure

11:06 how?

11:06 Chousuke: askentask: you can only have one method per class?

11:06 duck1123: :side-effects 'arguments ?

11:06 Chouser: duck1123: :-)

11:06 askentask: works for me

11:07 philscotted: Would a :side-effects tag be useful for sanity checking transactional code at compile time?

11:07 Chouser: how would you mark java methods?

11:08 Chousuke: maybe a :pure-function tag instead

11:08 to tag functions that have no side-effects. Might help the compiler too :)

11:09 philscotted: Chousuke: Maybe. It's worth remembering though that anything which consumes a function cannot guarantee absence of side-effects.

11:09 Chousuke: hmm, true.

11:10 tribool logic: yes, no, and maybe :P

11:15 albino: why can't the function passed be marked for side-effect freeness too?

11:15 D does this with their pure keyword

11:16 Chouser: again: what about java methods?

11:16 would you assume they're all impure except for those listed in some sort of global pureness set?

11:18 philscotted: Chouser: Everything could be assumed impure unless stated otherwise, I guess. I'm not sure this system could ever be used for static guarantees in things like transactional code, but it could be used to emit warnings.

11:20 albino: What would that allow us?

11:20 duck1123: what about :lazy false

11:21 philscotted: albino: D is statically typed, remember.

11:21 Chouser: duck1123: that's interesting. In a lot of cases boolean is probably sufficient.

11:22 wabash: Quick question: does Clojure have unicode strings baked in?

11:22 Chouser: wabash: yes

11:23 wabash: Clojure strings are Java Strings

11:23 wabash: Oh, yeah. I should have realized that. D'oh!

11:23 gnuvince: Wow, there are songs about Rich on reddit

11:23 wabash: I will write a song about Rich someday, too.

11:24 gnuvince Where did you see them? On the programming subreddit?

11:24 gnuvince: http://www.reddit.com/r/programming/comments/7epv2/rich_hickeys_clojure_talk_at_the_jvm_language/

11:24 wabash: Oh, they are not original songs, only remakes with new lyrics...

11:25 albino: philscotted: I figured the same concept would apply. Marking a function side-effect free means it could be passed to any other function which was also marked side-effect free

11:25 wabash: Once I have a strong enough mastery of clojure to appreciate it, I'll write an original song about clojure or something.

11:29 philscotted: albino: Yeah, but suppose you want to pass a side-effecting function to list. List is side-effect free, and has no intention of invoking its arguments, so we would still want this to work.

11:32 duck1123: philscotted: are you saying evaluate the function and pass it to list, or pass the functions symbol to list

11:33 if it's the first, then list is no longer side-effect free because the false bubbles up

11:33 philscotted: duck: I'm saying to pass the function to list. Suppose the function is foo and it is side-effecting. (list foo) has no side-effects.

11:33 duck1123: if it's the latter, then it's not really a function, it's data

11:36 philscotted: duck1123: More concretely: (defn foo [bar] (bar)) defines a function which takes a function and will have side effects iff bar has side effects. But (defn foo [bar] (list bar)) is pure whatever.

11:36 askentask: can i let inside a reduce?

11:36 Chouser: askentask: you can 'let' anywhere that expects an expression.

11:36 askentask: ah yes

11:37 duck1123: you need 3 states

11:37 foo1 is maybe, foo2 is false

11:40 danlarkin: haha this thread is a goof, http://www.reddit.com/r/programming/comments/7epv2/rich_hickeys_clojure_talk_at_the_jvm_language/c06gob8

11:40 duck1123: (defn foo1 :side-effects (some (map #(:side-effects (meta %)) '(bar))) [bar] (bar))

11:41 I'm sure I screwed that up, but you get the idea

11:42 philscotted: duck1123: Right. So rather than having a simple boolean, we could capture the conditional in some actual code. I'm not sure how much benefit any of this will actually give. It might just end up being overhead.

11:44 hiredman: ugh

11:45 duck1123: presumably, it would be much easier to identify the arguments that can change the side-effect status :side-effects (maybe [bar])

11:49 philscotted: duck1123: I suspect it would be easy to get carried away. My intuition is that you could pick an arbitrary predicate of the arguments, and find *some* function for which that predicate expresses the dependence between the pureness of the arguments and the pureness of the main function, meaning that no simple system would be sufficient.

11:55 duck1123: philscotted: I agree some functions might be difficult to pin down, but a lot of functions (those that don't take IFn's as an arg) would be relatively simple to say true or false. (defn + :side-effects false ...)

11:55 philscotted: duck1123: Agreed.

11:57 Is Rich looking for any volunteers to proof read his documentation?

11:57 askentask: can i bind to vars defined in the same let? like (let [[x & xs] coll test (something-with x)]...

11:57 Chouser: askentask: yes, let bindings happen in order

11:57 philscotted: There are quite a lot of typos.

11:58 Chouser: philscotted: he'd probably be happy to get a list of corrections to be made

11:58 philscotted: in .clj files or just on the web site?

11:59 philscotted: Chouser: The website. I'm happy to go through the documentation there again looking for them.

11:59 Chouser: I can't speak for him of course, but generally when people have noted mistakes he's responded positively.

12:00 drewr: He'd probably love to have corrections for stuff like that.

12:01 I haven't ever seen him respond unfavorably to genuine efforts to improve the project.

12:01 philscotted: Well for my purposes, I want Clojure to look as awesome as possible, and it would be great if the website was completely free of typos for that.

12:01 drewr: He's even kind to the cargo-cult lispers that come in complaining about stuff.

12:03 duck1123: Chouser: in response to your earlier question, doall would be considered side-effect free. That status can be tainted by the sub-forms it contains, but it itself doesn't produce any side-effects, nor does it accept any unevaluated IFn's that could change that.

12:03 doseq, being a macro, would have to be a maybe

12:06 Lau_of_DK: Evenings gents

12:07 duck1123: evening Lau_of_DK

12:18 brill: Yeah, hej Lau_of_DK

12:19 Now english is my second language - and I know what a cargo-cult is. But what is a cargo-cult lisper? I just had to ask...

12:19 duck1123: http://en.wikipedia.org/wiki/Cargo_cult_programming

12:20 Hun: the stuff why we still call a cdr a cdr and so on

12:20 Lau_of_DK: duck1123: based on that description, would you say cargo code is solely for python programmers?

12:23 brill: duck1123: Ah. I get it now.

12:24 Chousuke: Lau_of_DK: nothing about that is specific to any D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[D[C[D[Dlanguage :/

12:24 oops.

12:26 Lau_of_DK: hehe

12:26 Chousuke: it was just another crack at the Python crowd )

12:26 :)

12:28 gnuvince: Anybody here is a French speaker?

12:40 duck1123: is there an easy way to convert a inputStream into a string in Clojure

12:40 all of the java methods are way too complicated

12:41 I just need to read this file, and I need it as a string

12:42 Chouser: (apply str (line-seq (java.io.BufferedReader. (java.io.InputStreamReader. stream))))

12:42 java's io api is so ugly

12:43 shoot, that loses newlines.

12:44 danlarkin: isn't there slurp or something?

12:44 technomancy: duck1123: that drove me crazy in JRuby

12:44 Lau_of_DK: clojure/slurp

12:44 ([f])

12:44 Reads the file named by f into a string and returns it.


12:44 Chouser: slurp works on filenames

12:44 not streams

12:44 Lau_of_DK: Mr. Duck said 'read this file'

12:45 danlarkin: ah :-/

12:45 hiredman: Chouser: you interleave \newline

12:45 then str

12:46 which, uh, may get you an extra newline at the end

12:46 Chouser: (apply str (map char (take-while pos? (repeatedly #(.read stream)))))

12:46 duck1123: I technically don't even need newlines

12:46 in this case at least

12:48 technomancy: it looks like the sourceforge bug tracker is not being used. where do bugs get filed?

12:48 Chouser: technomancy: post to the google group

12:48 technomancy: ah, ok.

12:49 I noticed the zip file expands in-place instead of creating a new subdirectory. This can't be intentional, can it?

12:50 Chouser: technomancy: which zip file?

12:50 oh, the release .zip file?

12:50 technomancy: Chouser: the "download clojure" zip file

12:51 yeah

12:51 Chouser: hm, that's more common with .zip than it is with .tar, but you could still mention it on the google group.

12:51 mmcgrana: orthogonal to your point about the zip file, I'd suggest you use Clojure head from svn

12:52 technomancy: mmcgrana: was about to ask that. =)

12:52 Chouser: at this stage of the game, many (most) people use SVN directly. But that may be changing in the next few months, so it may be good to start refining how the .zip files are built.

12:52 technomancy: Chouser: I'll mention it then.

12:54 dudleyf: JDK 7 should have better IO APIs

12:54 Chouser: if you ask me, JDK 5 should have better IO APIs.

12:55 :-D

12:55 mmcgrana: lol

12:55 dudleyf: ;-)

12:55 I think there's a patch for 1.6 VMs

12:56 technomancy: has there been talk of getting a "real" bug tracker, or does the google group work pretty well?

12:57 dudleyf: technomancy: So far, Rich has like a 6 hour turnaround on bugs posted to the group

12:57 Chouser: technomancy: so far it's hard to keep a bug alive long enough for a tracker to be useful. They tend to be fixed within a day or two, if not hours or minutes.

12:57 technomancy: that's awesome.

12:57 Chouser: I think once 1.0 is out, bugs may have to be tracked against multiple releases and a bug-tracker would become worth its overhead.

12:58 technomancy: sure; things get a little more complicated. also once the book is out the volume may increase.

12:59 abrooks: Chouser: Yes, but only a bug-tracker written in Clojure...

12:59 technomancy: definitely. =)

12:59 danlarkin: it'll be time for two lists

13:00 Chouser: very little of the clojure development system is written in clojure so far: no editor, no web forum, no chat system or IRC bot, no bug tracker...

13:00 The closest we have is a netbeans plugin for clojure that includes some clojure code along with the java.

13:01 danlarkin: no need to reinvent the wheel for a lot of that stuff IMO

13:01 * Chouser nods

13:01 technomancy: yeah, slime is awesome. and it's written in lisp, which is close enough. =)

13:02 Hun: now we hava a is-a vs has-a vs might-be-close with lisp, elisp, common lisp and clojure again

13:02 whatmeworry? :)

13:03 * technomancy digs elisp, but is curious to see what lisp without historical baggage is like

13:03 Hun: elisp is pretty crappy.... it's okay for smaller scripting tasks, but you really don't want to know how it works

13:03 * Hun shudders at the thought of dynamical variables without namespaces

13:04 hiredman: Chouser: I have a xmpp repl bot, which could get on irc using an xmpp to irc gateway

13:04 dunno if it still works

13:04 technomancy: Hun: they're working on that; the lexbind branch is slated for merging after the next release

13:04 duck1123: we really need something like fsbot in here

13:04 hiredman: fsbot?

13:04 duck1123: the bot of #emacs

13:04 technomancy: fsbot is awesome

13:04 tWip: written in elisp, I presume

13:05 duck1123: yeah, erbot

13:05 Hun: technomancy: the last release took 7 years...

13:05 duck1123: I tried setting up one yesterday, but couldn't get it to work

13:05 technomancy: Hun: the next one is planned for January; been in feature freeze since July

13:05 Hun: I think they learned from their mistakes, just like Debian. =)

13:07 brb

13:09 hiredman: so a lisp info bot

13:10 duck1123: basically, we need one for clojure though

13:10 Chouser: what would it do?

13:10 hiredman: doc function

13:10 of course

13:10 duck1123: we should be able to say (doc foo) and have it spit out the doc

13:11 Chouser: oh. I can already do that at the repl without bothering everyone else on the channel.

13:11 hiredman: but what if you want to bother someone on the channel?

13:11 Chouser: oh! good point.

13:11 hiredman: you could teach it answers to faqs

13:11 duck1123: it comes in handy in #emacs

13:11 Hun: like slapping freshly joined people with standard documentation

13:11 also in #lisp

13:11 Chouser: bot: (bother 'hiredman)

13:12 duck1123: clojurebot: no you can't see the version number from the repl

13:13 hiredman: clojurebot: the lastest verion is x, the recomended version is y

13:14 Chouser: clojurebot: try (.getMethod (identity MyClass) ...) instead of (.getMethod MyClass ...)

13:14 hiredman: so we are all talking to something that isn't here

13:15 duck1123: one of the nice things about fsbot is it learns, you can give it new information as they come up in chat

13:15 abrooks: heh

13:15 tWip: well isn't this channel logged publicly? when the clojurebot is done, it can read the logs for learning material :)

13:15 Chouser: hiredman: he'll be able to read the logs to get up to speed.

13:15 once he's written.

13:15 tWip: exactly.

13:16 tWip: though one could say that people can read the logs as well

13:16 danlarkin: wow clojurebot has a lot of features for not yet existing

13:16 technomancy: sounds like a good learning project

13:16 tWip: imaginary software often is the best kind of software

13:17 Chouser: how do you retreive a stored question from the bot?

13:17 technomancy: tWip: yeah, windows Longhorn was soooo much better than Vista. =)

13:17 Pupeno: #<core$keys__494 clojure.core$keys__494@1829c6b>

13:17 Does macroexpand-1 always return things like that?

13:17 technomancy: Chouser: in #emacs, you can do ,term to look up a term, and ,df function-name to look up docs for functions

13:18 Chouser: Pupeno: no, it should return an s-expression of code.

13:19 Chousuke: Pupeno: are you sure your macro isn't accidentally returning some value instead of a code form?

13:24 hiredman: can you override constructors with proxy?

13:25 Pupeno: I was just forgetting to quote the expression to macroexpand, agh, I haven't written macros in ages.

13:25 How do you get a form evaluated inside a back-quoted expression?

13:27 phil: rhickey: I'm still trying to grok your "On State and Identity" article. Am I right in thinking the "state/identity" distinction is the same as the "reference/meaning" "extensional/intensional" distinction?

13:28 Chouser: hiredman: essentially, yes. You don't get to provide your own constructor, but you can pass the super's constructors whatever values you want.

13:28 Pupeno: ~ or ~@

13:29 rhickey: phil: it's really more basic than that, urging separation of identity/reference from value/representation

13:29 hiredman: hmmm

13:29 well that did nae work

13:30 rhickey: hiredman: proxy has same ctor as superclass, is flow-through to super

13:31 Pupeno: Chouser: that was I was trying... I didn't realize I had another ~ inside and that was causing the error.

13:31 Chouser: Pupeno: ah, ok

13:32 phil: rhickey: Okay, yes. I perhaps need to rephrase. I'm wondering if the points you are making can be nicely explained in those terms. For instance, something I might do in a program is say (the list of) Jill's friends is the (list of) Jack's friends. The problem in most imperative languages is that lists are mutable, so if Jack drops one of her friends, it will affect Jill. What's happened here is we've stated that "Jack's frie

13:32 nds" is intensionally the same as "Jill's friends", so any change to one affects the other.

13:33 hiredman: hmm

13:33 phil: What we wanted to say was that Jack's friends and Jill's friends happen to refer to the same list, which *never* changes. At some point in the future, Jack may acquire a *different* list of friends, but this cannot affect Jill.

13:35 Chouser: hiredman: frequently when using proxy I end up with a fn that acts a bit like a constructor and may provide instance data. It then calls proxy (with appropriate constructor args) and my methods close over the instance data.

13:36 hiredman: oh

13:36 neat

13:37 Chouser: oh, good, I was afraid that didn't make any sense.

13:38 Pupeno: Any better/shorter way to write (symbol (format "%s-bleh" 'blah))?

13:38 rhickey: phil: yes, but also that Jill may retain a persisting reference to Jack, names aside, and ask for his current list of friends at any time, so there's the list itself and the association of the list with an identity

13:39 Hun: (defn foo-postfix [name] (symbol (format "%s-bleh" name))) (foo-postfix "blah")

13:39 Chousuke: I think the "today" example in the article is a really good one.

13:40 wwmorgan: Pupeno: (symbol (str 'blah "-bleh"))

13:42 hiredman: ahem

13:42 phil: Chousuke: I didn't quite get that. I consider "today" to be

13:42 Chousuke: even if tomorrow "today" will be 22-11-2008 that doesn't mean 21-11-2008 has changed. it just lost its association with the identity "today".

13:43 21-11-2008 is itself an identity though. but a much more stable one than "today"

13:43 phil: I consider "today" to be merely an indexical, like "me" or "you", its meaning determined by context. Perhaps my understanding has been coloured by other subjects, which is why I was after an explanation in terms I was more familiar with.

13:44 Hun: i think of them as chomsky-0. context-sensitive identifiers

13:44 argh

13:44 Chousuke: phil: How about this: when you do @ref, you determine the value of the ref in a given context, and work with that.

13:44 Hun: chomsky-1

13:45 Chousuke: phil: in other contexts, @ref may be different, but that will not affect you

13:46 or: someone knocks you out for days, and when you wake up, you still might think "today" is 21-11-2008 and do decisions based on that.

13:47 no external entity has access to your brain to overwrite the association "today == 21-11-2008"

13:47 phil: Chousuke: I'll think on it a bit more. I'm hoping for something quite formal to capture the idea.

14:09 technomancy: I'm curious as to the motivation behind leaving out an implicit progn in if

14:09 sorry, implicit do.

14:09 is it just so that the true and false branches are parallel?

14:10 oh, or to discourage side-effects... that would make sense

14:10 kotarak: technomancy: How do you decide, when the if branch is finished?

14:11 technomancy: kotarak: when it runs out of arguments? I don't understand the question.

14:12 kotarak: technomancy: If I understand you correctly, you ask why in (if (...) (do (a) (b))) the do is necessary?

14:13 technomancy: kotarak: well in other lisps the third argument to "if" is considered a "rest" arg, and it's wrapped in an implicit do.

14:13 tWip: really?

14:13 kotarak: technomancy: ok. So in (if (..) (a) (b)) is b in the else branch or not?

14:13 tWip: I don't think that's true for CL at least

14:14 or elisp or scheme

14:14 technomancy: so (if cond true-form false-form1 false-form2) becomes (if cond true-form (do false-form1 false-form2))

14:14 kotarak: the do only wraps the last arg

14:14 tWip: (if nil 2 3 4 5) ;; <= returns 5

14:14 tWip: ok. I stand corrected then.

14:15 Hun: tWip: it is in cl

14:15 tWip: Didn't know that. I've always just progn

14:15 technomancy: tWip: the best part about IRCing from emacs is that you can check these things as you type them. =)

14:15 tWip: +used

14:15 technomancy: but since clojure explicitly discourages side-effects, it makes sense to require an explicit do

14:17 kotarak: And from a stylistic point of view: Why should the else branch be treated differently?

14:17 tWip: ok scheme doesn't allow that

14:18 hiredman: (meta ...) works on symbols, yes?

14:18 ah

14:19 find-var is what I need

14:20 technomancy: kotarak: because you can only have one rest argument. but that's an implementation excuse.

14:23 maybe this is obvious to people who've used Java before, but what do you do with a fresh checkout of the closure source?

14:23 tWip: ant

14:23 or mvn install

14:23 technomancy: cool, thanks.

14:23 tWip: both build systems are supported (build.xml is for ant, pom.xml is for maven)

14:23 technomancy: that *definitely* belongs in the readme

14:23 tWip: agreed

14:24 hiredman: technomancy: in clojurebot

14:25 technomancy: hiredman: or clojurebot could just say, "read the readme"

14:25 =)

14:25 are you guys pretty happy with SVN, or are there plans to move to a distributed system?

14:26 not being able to fix the readme myself feels very strange after using git for so long. =)

14:26 tWip: you could send a patch to the group

14:26 duck1123: technomancy: there is a git mirror on github

14:27 Pupeno: technomancy: git-svn is your friend ;)

14:27 technomancy: and... what duck1123 said.

14:28 technomancy: duck1123: will check that out.

14:28 duck1123: https://github.com/kevinoneill/clojure/tree

14:28 technomancy: tWip: yeah, it's just more manual than I'm used to. not a big deal though.

14:28 * technomancy is spoiled, for sure

14:28 * Pupeno would also like clojure main development to move to git. But that's up to Rick.

14:30 technomancy: folks would certainly be more likely to submit patches for smaller things if the barrier to contribution were lower.

14:30 craigmcd: Hey guys...anyone have any examples of how you would do what used to be gen-and-save-class?

14:32 i.e, using the new AOT class generation.

14:33 Chouser: AOT/gen-class syntax: http://paste.lisp.org/display/70665

14:33 the "announcement" starts here: http://clojure-log.n01se.net/date/2008-11-18.html#14:19

14:34 craigmcd: thanks

14:36 lisppaste8: asken pasted "OO-system, comments?" at http://paste.lisp.org/display/70846

14:37 askentask: http://paste.lisp.org/display/70846

14:37 ^^ askentaskens -not-so-cute- OO-system for clojure

14:37 lol bold claim, it sucks :(

14:37 but comments would be appreciated

14:38 tWip: why is the code in add-method quoted?

14:38 askentask: because i ti is evaled when called, didnt know how else to store it

14:39 i will add the obvious possibility of passing aguments to methods and more stuff

14:39 uh the example is a bit messy , ill annottate

14:39 tWip: I may be missing something, but why not just use defmulti?

14:41 askentask: because im trying to learn more about programming languages rathet than do something directly useful

14:41 lisppaste8: asken annotated #70846 with "OO-example" at http://paste.lisp.org/display/70846#1

14:42 tWip: are keywords replaced with accessors in method code?

14:44 askentask: yes

14:44 tWip: so you can't use keywords for other things

14:45 askentask: each instance has a spec-map and a attribute-map. when doing (call instance method-name) the method in spec will be fetched and the keywords replaced by the corresponding values

14:45 other?

14:45 i guess it will be a problem if you had a method that ocntained another method-call

14:45 no wait

14:45 it should work

14:45 tWip: I mean that you can't use keywords for their normal use then

14:46 askentask: it only replaces for keywords that arw attributes

14:46 if there is a name-clash there could be a problem

14:46 but otherwise should work

14:49 Chousuke: hmmh

14:49 hiredman: (doc str)

14:50 Chousuke: askentask: #(add-method with (first %) (second %)) methods) in spec-class is suspect

14:50 askentask: you're not dereferencing the ref

14:51 which means you're not passing add-method the instance, but a ref.

14:52 so (get instance :spec) tries to get :spec from the ref, not its value.

14:53 and it returns nil, thus an NPE is thrown

14:54 hiredman: (doc str)

14:54 askentask: Chousuke: uh yes that is not finished

14:54 spec-clas

14:55 hiredman: ok

14:55 Chousuke: redef'ing things is ugly too :)

14:55 hiredman: third time is the charm

14:55 (doc str)

14:55 clojurebot: With no args, returns the empty string. With one arg x, returns x.toString(). (str nil) returns the empty string. With more than one arg, returns the concatenation of the str values of the args.

14:55 technomancy: hiredman: that was quick.

14:56 Chouser: hiredman: that's via xmpp?

14:56 hiredman: no

14:56 I grabbed pircbot

14:56 Chouser: excellent

14:56 hiredman: it just does doc lookup for stuff in the clojure namespace right now

14:57 not clojure.core :(

14:57 technomancy: hiredman: is it easy to make it store and lookup definitions?

14:57 clojurebot: clojure

14:57 hiredman: oh, that doesn't work

14:58 right now it just looks for (doc x)

14:58 lisppaste8: Chousuke annotated #70846 with "using -> (untested)" at http://paste.lisp.org/display/70846#2

14:58 Chousuke: whoops

14:58 forgot some extra stuff in the annotation

14:58 but with -> it looks almost nice

14:58 hiredman: makes a symbol out of x, resolves it to a var in the clojure ns, grabs the metadata and returns the :doc bit

14:59 technomancy: cool.

14:59 definitions should be easy to add.

14:59 at least, until you start to think about persistence

14:59 tWip: (doc this-should-not-exist)

14:59 lisppaste8: hiredman pasted "clojurebot" at http://paste.lisp.org/display/70849

15:00 drewr: http://clojure-log.n01se.net/date/2008-05-23.html#17:33 :-)

15:00 tWip: it could warn about not finding something, or even doing some levenshtein/fuzzy matching

15:00 but nice work getting that up so quickly :)

15:00 hiredman: thank you

15:00 it could just slurp and spit forms into a file

15:01 I guess

15:01 ack

15:01 I missed a ( in that paste

15:02 any more bits are missing, what I get for doing everything in the repl

15:05 (doc this-should-not-exist)

15:06 (doc this-should-not-exist)

15:06 askentask: Chousuke: yes -> makes it nicer-lookign, thanks!

15:06 hiredman: well, it was fun, but I just broke it again

15:08 fixed, it also resposne to privmsgs

15:09 askentask: is it concurrent :)

15:09 hiredman: uh

15:09 I know nothing about the internals of pircbot

15:10 Chousuke: askentask: actually using -> won't work because your add-method function is evil and doesn't return the rect instance

15:11 askentask: lol i noticed

15:12 Chousuke: you can either use doto or fix it to return the rect

15:12 though why does add-method take the instance as a parameter at all? it adds a method to the class, doesn't it?

15:13 askentask: yes

15:13 how else would it now which one?

15:14 Chousuke: you pass it the class name as a parameter perhaps.

15:14 or the class itself

15:15 as it is now, your define-class defines an instance

15:15 ...

15:15 askentask: why does your connection always break when I'm talking to you? :(

15:15 hiredman: well

15:16 call the instances prototype objects :P

15:17 Chousuke: :p

15:18 askentask: ok

15:20 i should separate the add-method from def-attribute as well. there should be first one way to specify a class then one wya to initialize them. i feeel like im messing things up

15:20 like it is all intertwined and i dont know how to separate it

15:25 Chousuke: maps make fine classes too: (def cat {:meow #(println "Meow") :sleep #(println "Generic cat sleep!")}) (def fuzzy (assoc cat :name "fuzzy" :sleep #(println "Seeing fuzzy dreams"))), ((:meow fuzzy)) (doseq [c [cat fuzzy]] ((:sleep c)))

15:27 askentask: what is mod again?

15:27 Chousuke: mod?

15:27 Chouser: rem

15:27 think "quotiant and remainder" qout rem

15:28 askentask: ah yes

15:33 abrooks: The neurons that were wired when I was a young boy programming in BASIC on my C=64 still interprets REM as a comment (REMark). I guess DOS batch also reinforced that.

15:36 I do wish that "rem" was "mod".

15:38 Chouser: (def mod rem)

15:38 danlei`: abrooks: well, if you're coming from the c64, we should rename poke too =)

15:38 hiredman: clojurebot: svn?

15:38 abrooks: Actually, I'm realizing that there's room for both rem and mod and that mod's missing. rem should have the sign of the dividend and mod should have the sign of the divisor.

15:38 danlei`: s/poke/peek

15:38 abrooks: (def poke set!)

15:38 danlei`: =)

15:45 askentask: if im using (reduce + (for [x...)) it is then evaled lazily right? so it is not traversing the lsit twice(but perhaps stilla bit slower )?

15:47 Chouser: reduce kills laziness, but 'for' will only generate each number for it one time.

15:48 gnuvince: ~help ~markovnick

15:50 craigmcd: Chouser: thanks for the hint on the new gen-class. But why does this work fine: (.main my.Hello (into-array ["Bizarro"])), while this syntax doesn't: (my.Hello/main (into-array ["Bizarro"]))

15:50 askentask: Lucky Sevens

15:50 Write a program to compute the sum of all the integers between 1 and 1011 both divisible by seven and, when the decimal digits are reversed, are still divisible by seven.

15:50 1 and 10 raised to 11 that is

15:51 i wrote a nice short program that takes forever so i guess the problem is to find some pattern or do soem clever huge-integer-summing.

15:51 anyone know such stuff?

15:53 Chouser: craigmcd: foo/bar syntax is only for when foo is a namespace or when foo is a class and bar is a static member (method or field)

15:53 craigmcd: But my.Hello is a class and main is a static member

15:53 Chouser: oh, main is static.

15:53 sorry, just catching up here. :-)

15:54 craigmcd: Yeah, it's almost as if the "/" syntax for static methods isn't working on generated classes

15:54 Chouser: hm... are you calling gen-class yourself, or using :genclass?

15:54 hiredman: clojurebot: svn?

15:54 craigmcd: using ":genclass"

15:55 hiredman: clojurebot: svn?

15:55 clojurebot: svn co https://clojure.svn.sourceforge.net/svnroot/clojure clojure

15:55 hiredman: thanks

15:55 craigmcd: and I can call this main method using "java.." from the command line and it works. and I checked the class with slime inspector, and main is really static

15:57 Chouser: ok, I don't really understand -- it should work. But here's what little I know...

15:58 (.foo bar) expands to (. bar foo) without exception. But (foo/bar) has to figure out if foo is a class or not (at read time). If foo is a class, then it also becomes (. foo bar), otherwise it's resolved as a var in the foo namespace.

15:59 so it's acting as those it doesn't know at read time that there's a class named my.Hello

15:59 craigmcd: hmm.. interesting. thanks

16:00 Chouser: "as though"

16:00 but if my.Hello wasn't findable in your classpath, neither form would work. So I dunno.

16:01 Maybe bring it up on the google group so people smarter than I can poke at it.

16:01 craigmcd: Yeah, I think I'll post that one...thanks.

16:06 duck1123: clojurebot: group?

16:10 Lau_of_DK: ...

16:11 Are there wrapper for JQuery/JSon yet, so you can stay out of the javascript stuff?

16:13 tWip: isn't Chouser's clojurescript doing that in a way

16:13 translating clojure forms to javascript, as far as I can tell

16:13 Lau_of_DK: Im not sure... thats why Im asking :)

16:14 Chousuke: what are you trying to do?

16:14 powr-toc: hey

16:14 Chousuke: write javascript in clojure?

16:14 or interact with something that sends you json?

16:14 Lau_of_DK: Specifically to use JSon or JQuery from Clojure

16:15 Chouser: clojurescript's currently targetted at converting clojure code forms to js code. The datastructures on the JS side are still Persistent and require a chunk of runtime support code.

16:15 tWip: json and jquery are totally different things

16:15 Lau_of_DK: Yes, but I can use either and still be happy

16:15 tWip: jquery is a full javascript library/framework and json is a serialization format

16:15 Chouser: if you want javascript Object and Array instances from clojure Map and Vector instances, you don't want clojurescript.

16:15 tWip: you can easily wrap one of the Java libs that handle JSON parse/read

16:16 Chouser: somebody's got a pure clojure json encoder though. I'll see if I can find it.

16:16 tWip: possibly with some added code to handle translation from Java Collections to native Clojure structures

16:17 jgracin: do we have a group-by or categorize-by function anywhere? Takes pred and a collection to categorize.

16:17 Chouser: jgracin: clojure.contrib.lazy-seq I think

16:17 Lau_of_DK: http://github.com/danlarkin/clojure-json/tree/master

16:17 Lau_of_DK: jgracin: http://paste.lisp.org/display/64190

16:18 Thanks Mr. Houser

16:18 Chouser: jgracin: sorry, clojure.contrib.seq-utils

16:18 jgracin: Chouser: thanks!

16:18 danlarkin: Heyooooo

16:18 Chouser: ...which is the same as Lau_of_DK posted. Thanks, Lau_of_DK!

16:19 jgracin: Lau_of_DK: thanks

16:20 danlarkin: JSON encoder only right now, soon a decoder too, though! *crosses fingers*

16:20 Lau_of_DK: hehe

16:20 Chouser: danlarkin: sorry I called you 'somebody'

16:20 Lau_of_DK: danlarkin: you wouldnt happend to have any sample sites running?

16:21 danlarkin: Chouser: haha it's okay, I forgive you

16:21 Lau_of_DK: sample sites running?

16:21 Lau_of_DK: danlarkin: something that uses your wrapper

16:23 danlarkin: oh, no, I do not. Though someone (I forget who, I'll try to find it in the logs) a few weeks ago was saying he did

16:24 it's pretty easy to use, though, (org.danlarkin.json/encode-to-str sexprs)

16:25 ah ha, it was blackdog

16:25 Lau_of_DK: Blackdog has done some advanced stuff on the webfront, hes the guy to informed me about JSon in the first place

16:37 askentask: Chousuke: lets say i create a function spec-class that take [classname parent methods] where methods is a vector of vectors with name-functionlist pairs. how would i use -> then? i tired adding a for-comprehension but i get wrong nbr of args to for.

16:38 wait it wked with map

16:38 Chousuke: askentask: -> is just a macro

16:39 Chouser: 'for' is also just a macro

16:39 Chousuke: askentask: (-> :X (:a :b)) == (:a :X :b)

16:40 askentask: further (-> :X (:a :b) (:c :d)) == (-> (:a :X :b) (:c :d)) == (:c (:a :X :b) :d)

16:40 askentask: eate ISeq from: spec_class__2930$fn__2932

16:40 : Don't know how to create ISe

16:42 Chousuke: you need to show the code if you paste error messages :/

16:42 especially cryptic ones like that. :P

16:44 askentask: it compiles but fails when called

16:44 yes

16:44 it seems lippsaste is dow

16:44 http://hpaste.org/12262

16:45 Chousuke: askentask: you're using -> wrong in the spec-class fn

16:46 askentask: hmm perhaps that shouldnt work buti dont really know how to get what i want

16:46 Chousuke: askentask: -> puts its first argument as the second item in the following form.

16:46 you

16:47 Lau_of_DK: (boys, did you al checkout Netbeans Svn / Enclojure plugins)

16:47 Chousuke: askentask: you're actually doing (map (define-class-no-ref classname parent) #(add-method (first %) (second %)) methods)) there

16:48 askentask: in the previous form, -> just exploits the fact that the rectangle is the second parameter

16:48 and that the methods return the rectangle

16:49 hiredman: clojurebot: group? is http://groups.google.com/group/clojure

16:49 clojurebot: group?

16:49 clojurebot: clojurebot: group? is http://groups.google.com/group/clojure

16:50 hiredman: uh

16:50 close but no cigar

16:51 Chousuke: for example, the first form reduces to (def rect (def-attribute (def-attribute (add-method (add-method (define-class-no-ref :rect nil) :area '(* :width :length)) :square? '(= :width :length)) :width 10) :length 20)))

16:51 technomancy: hiredman: can you put up the source to clojurebot?

16:51 hiredman: sure

16:51 it is rather shameful

16:52 technomancy: well this is my first day with clojure, so you can be sure I won't judge.

16:52 can you toss it on github or something?

16:52 Chousuke: askentask: do you see how -> works now? :)

16:52 hiredman: uh, well, uh, I guess

16:52 I'd have to figure out git

16:53 technomancy: hiredman: or whatever SCM you prefer; heh

16:53 tWip: I'm intrigued by git as well... currently using google code hosting for webjure

16:53 and SVN on that

16:53 hiredman: technomancy: for now how about a plain http link?

16:54 technomancy: hiredman: that works for now.

16:54 since I probably won't have much to contribute at this point

16:54 tWip: you should give it a shot; it can dramatically lower the barrier to contribution.

16:54 hiredman: http://www.thelastcitadel.com/lab/clojurebot.clj

16:55 technomancy: tWip: or any DSCM really, but git seems to have the most momentum

16:55 tWip: I did use darcs for some code, but didn't like it

16:55 hiredman: bits missing to actually run, because I started off monkeying around in the repl

16:55 Chousuke: git and mercurial are both nice.

16:55 mercurial is slower than git, but works better on windows :)

16:55 hiredman: I use bzr

16:55 technomancy: nothing wrong with bzr

16:56 *for projects without tons and tons of history, at least

16:56 hiredman: heh

16:56 Chousuke: git is probably the fastest VCS around :P

16:56 technomancy: hiredman: they're trying to move Emacs to bzr, but it takes ages to do anything with it. =\

16:57 bzr log takes several minutes.

16:58 Chousuke: :/

16:58 hiredman: anyway, clojurebot is still one file, a hair less then 100 lines

16:58 rottcodd: Chouser: the symbol-macrolet spec is here http://www.lispworks.com/documentation/HyperSpec/Body/s_symbol.htm

16:58 technomancy: Chousuke: well it *does* go back further than I've been alive. but still...

16:58 Chousuke: technomancy: :)

16:58 hiredman: the github paste thing

16:59 askentask: (defn spec-class [classname parent methods]

16:59 Chousuke: technomancy: git log should be fast. it's designed to work well with browsing the entire history (it's slower if you need the history of one file)

17:00 askentask: (let [inst (define-class-no-ref classname parent)]

17:00 (map #(add-method inst (first %) (second %)) methods)))

17:00 wtf

17:00 sorry

17:00 that works , but not correctly :P

17:00 technomancy: Chousuke: it may not be the fairest comparison, true

17:00 Chousuke: wonder if there's an emacs git repo anywhere.

17:01 askentask: it creates 2 different instances rather than one

17:01 one for each method

17:01 Chouser: rottcodd: ok, thanks.

17:02 technomancy: Chousuke: git://git.sv.gnu.org/emacs.git

17:02 hiredman: clojurebot: group? is http://groups.google.com/group/clojure

17:02 clojurebot: group?

17:02 technomancy: but it takes like 30m since there's so much history to pull

17:02 hiredman: ugh, something, somewhere is swallowing exceptions

17:03 * technomancy installs clojure-mode

17:04 Chousuke: I wonder how huge that repo is.

17:05 technomancy: 172 MB

17:05 if you can get it from someone locally it would be less cruel to their server; heh.

17:05 Chousuke: still, a clone will probably be faster than most SVN repos I've had to check out :(

17:05 especially on google code

17:06 technomancy: Chousuke: for most projects, yes. but emacs' history is insaaaaane.

17:06 Chousuke: well, yeah

17:06 technomancy: oh... you can do a shallow clone if you don't care about history

17:06 git clone --depth=100 [...]

17:06 Chousuke: nah, I want all of it.

17:06 technomancy: going to do some code archeology? =)

17:07 Chousuke: perhaps :P

17:07 hm

17:08 not very speedy. only ~100kB/s :/

17:10 Well, at least I don't have to do a CVS -> git import

17:10 that would take weeks

17:21 Chouser: no docs yet, and some functionality turned off for security reasons, but if anyone wants to try it: http://clojurescript.n01se.net/

17:23 hiredman: clojurebot: mutable state is bad

17:23 clojurebot: Ok.

17:23 mmcgrana: cool! congrats on getting this up

17:23 hiredman: clojurebot: mutable state?

17:23 weird

17:24 Chouser: javascript interop example: (set! (-> document .body .style .background) "red")

17:25 mmcgrana: nice

17:28 hiredman: clojurebot: mutable state is bad

17:28 clojurebot: You don't have to tell me twice.

17:28 hiredman: clojurebot: mutable state?

17:28 clojurebot: mutable state is bad

17:29 Chouser: hiredman: nice. will such facts survive power disruption?

17:29 hiredman: not yet

17:29 right now they go into a ref

17:29 Chouser: very good.

17:31 technomancy: clojurebot: svn?

17:31 clojurebot: svn co https://clojure.svn.sourceforge.net/svnroot/clojure clojure

17:31 hiredman: clojurebot: clojurescript is Chouser's baby

17:31 clojurebot: Ok.

17:31 Chouser: clojurebot: baby?

17:31 clojurebot: Excuse me?

17:31 Chouser: clojurebot: clojurescript?

17:31 clojurebot: clojurescript is Chouser's baby

17:31 hiredman: clojurebot: clojurescript?

17:31 clojurebot: clojurescript is Chouser's baby

17:31 technomancy: clojurebot: botsnack is delicious.

17:31 clojurebot: You don't have to tell me twice.

17:32 technomancy: clojurebot: botsnack

17:32 clojurebot: botsnack is delicious.

17:32 technomancy: clojurebot: botsnack is delicious. (nom nom nom)

17:32 clojurebot: Roger.

17:33 technomancy: eventually he'll need to have some terms that don't get echoed with the "foo is" prefix

17:33 hiredman: yeah

17:34 technomancy: so someone can say: clojurebot: botsnack, and he'll say: thanks! (nom nom nom)

17:34 but... priorities. =)

17:35 hiredman: I can add a deal where if the definition is prefixed with <reply> he drops the is, like an infobot

17:35 technomancy: something like that, yeah.

17:36 should put it in a bzr repo so others can help. =)

17:37 sohail: technomancy, out of curiosity, why bzr vs git? (I use bzr personally)

17:37 technomancy: sohail: I use git too, but hiredman said he used bzr

17:38 Lau_of_DK: Theres a wiki which compares next to all known version control systems, proprietary and free

17:39 clojurebot: Produce link to above mentioned wiki

17:39 clojurebot: Excuse me?

17:39 Lau_of_DK: clojurebot: OBEY

17:39 clojurebot: Excuse me?

17:49 Chousuke: http://keithp.com/blogs/Repository_Formats_Matter/ this was a rather interesting read.

17:52 heh

17:52 tried git log on the emacs repo

17:52 it was instant

17:52 * gnuvince_ likes Mercurial

17:53 tWip: isn't git Linus' brainchild?

17:53 Chousuke: first commit message: "entered into RCS" by Jim Blandy at Date: Thu Apr 18 00:48:29 1985 +0000

17:53 technomancy: Chousuke: there's some fun stuff way back there. =)

17:53 Chousuke: yeah

17:54 hiredman: jesus

17:54 drewr: tWip: Yes.

17:54 Chousuke: I didn't expect the log command to be that fast though.

17:54 it took no time at all

17:54 tWip: it's funny how quickly it overtook cvs/svn/others in the hacker mindset

17:55 Linus' google tech talk on the subject is epic. He really lets SVN people have it.

17:55 Chousuke: tWip: well, one of the largest and most influential open source projects switched to it. :P

17:55 technomancy: tWip: for me github sealed the deal

17:56 it makes it trivial to start helping out with a project

17:56 Chousuke: maybe people also noticed that DVCS systems can do everything a centralised one can. usually better, too.

17:56 tWip: so github is sourceforge for git?

17:56 the page seems clearer, I dislike the "new" sourceforge

17:56 technomancy: tWip: depends on your opinion of sourceforge. =)

17:57 Chousuke: I also like the fact that setting up a repository is rather trivial.

17:57 Lau_of_DK: tWip: yes

17:57 Chousuke: just git init in a directory and then give someone ssh access to it :P

17:57 * kotarak thinks that git, hg or bzr are more or less equivalent

17:57 Chousuke: kotarak: more or less, yeah

17:57 * kotarak prefers hg, though

17:57 technomancy: tWip: it's just focused on code (rather than issues, mailing lists, etc.) but it does that really really well.

17:57 Chousuke: kotarak: they all have different stregths though.

17:57 kotarak: yes

17:58 hiredman: clojurebot: hg is <reply>kotarak prefers hg

17:58 clojurebot: Roger.

17:58 technomancy: tWip: makes it really easy to track what's going on in all the projects you're interested in; has great visualizations for how branches are interacting, etc.

17:58 hiredman: clojurebot: hg?

17:58 clojurebot: kotarak prefers hg

17:58 Chousuke: git is fast and efficient; hg and bzr are easier to use and more portable.

17:58 kotarak: hg is also fast

17:58 Chousuke: not as fast as git though

17:58 kotarak: fast enough for me, at least

17:58 Lau_of_DK: clojurebot: bye is <reply>/part #clojure

17:58 clojurebot: Roger.

17:59 Lau_of_DK: clojurebot: bye?

17:59 clojurebot: /part #clojure

17:59 hiredman: clojurebot doesn't do "also" yet

17:59 Lau_of_DK: :|

17:59 hiredman: Lau_of_DK: cute

17:59 Lau_of_DK: Thanks

17:59 kotarak: http://changelog.complete.org/archives/698-if-version-control-systems-were-airlines

18:00 technomancy: kotarak: that page is hilarious

18:00 kotarak: technomancy: I think I was laughing ten minutes

18:00 technomancy: I love the SVN merging room where everyone is given a brick and only one person comes out.

18:01 I still haven't hacked on any projects that use hg though.

18:02 I'm afraid to build Mozilla, and don't have much to do with the Sun world.

18:03 kotarak: patch queues are simply awesome...

18:03 Can't live without 'em anymore.

18:03 tWip: to be totally honest, I never really cared much about version control

18:04 of course, you'd have to be crazy not to use some, but mostly I'm working on code alone

18:05 rzezeski: even if you are working on it alone, it's nice to see your iterations, or to roll back to a working copy

18:05 kotarak: I'm also working alone. But I also often experiment.

18:05 With vc it's much easier to get back to a sane state. :)

18:05 tWip: oh I see that, experimenting with SVN means you don't commit :)

18:06 Lau_of_DK: Chousuke: Thank you for that link, it was an interesting read indeed

18:06 tWip: branching/merging is still too painful for real work

18:06 Lau_of_DK: (rhymes incl free of charge)

18:06 kotarak: Experimenting with hg and mq is a breeze.

18:06 rzezeski: you can experiment while commiting in SVN, it's called a feature branch

18:06 sure it's not as easy as the latest and greatest VC's, but it's not impossible, just a little more annoying

18:07 tWip: yes but "not impossible" isn't a ringing endorsement

18:07 technomancy: mercurial has a bisect tool, right?

18:07 lisppaste8: Chouser pasted "clojurescript js interop" at http://paste.lisp.org/display/70859

18:07 rzezeski: Oh I'm not saying it is, if you have the choice you should certainly pick whatever you are most comfortable with, but in the workplace you don't always have that choice

18:07 technomancy: tWip: reminds me of the Vista reviews. "It's not so bad."

18:07 Chouser: sorry to paste and run -- dinner time.

18:08 rzezeski: I have to work with SVN, and personally I don't mind it especially since I used to have to work with CVS

18:08 Lau_of_DK: Chouser: thats awesome man

18:08 Nice work

18:08 tWip: we use SVN at work also

18:09 Chousuke: I have my own "feature branch" of clojure :p

18:09 currently it just contains one commit that uncomments the add-.clj-files ant directive

18:10 tWip: is everyone using ant btw?

18:10 because I use Maven 2

18:10 * technomancy used maven to build clojure

18:10 technomancy: just because I've read horror stories about ant's executable XML and greenspun's tenth law

18:10 rzezeski: I prefer Maven, but Maven too has many flaws

18:10 technomancy: but I've heard my fair share of maven horror stories too

18:10 Chousuke: but at least I don't have to edit it every time the master branch changes. git rebase master applies all changes, then applies my uncomment patch

18:11 tWip: well the more convoluted Maven plugin configs are pretty horrific also

18:11 kotarak: technomancy: yes, hg has bisect

18:11 tWip: that's not the word I want, is it

18:11 rzezeski: I converted a fairly large project using Ant over to Maven and it was NOT an easy task

18:11 Chousuke: it's so easy to handle branching in git that you start doing them for the most trivial of things

18:11 rzezeski: Don't even try to use the release plugin or deployment plugins

18:12 hiredman: ugh

18:12 tWip: well Maven has dependency management, which is good

18:12 technomancy: seems like a build system should be written in clojure if you can ship it as bytecode to solve the chicken-and-egg problem

18:12 tWip: for some value of "good"

18:12 Chousuke: technomancy: a clojure build system would be nice. :)

18:12 hiredman: I hate that all the java build systems grab deps from all over the none universe while you are trying to build

18:12 rzezeski: yes that's probably is biggest selling point, until you get a bunch of transitive dependencies in your EAR and you wonder how the f they got there

18:12 tWip: hiredman: how is that different to say perl?

18:13 or python, or ruby? don't they do the same thing

18:13 or ASDF-INSTALL for that matter

18:13 technomancy: with ruby you get all your deps from the same server at least.

18:13 hiredman: now that you mention it, I am not a huge fan of ruby gems

18:14 but gems, at least you issue an install command to go get them

18:14 tWip: I quite like the maven style (when it works)

18:14 hiredman: a lot of maven/ant deals just go grab them when you type "ant"

18:14 tWip: Just add deps to your project definition and they are available

18:15 rzezeski: Maven is great if your project sticks to the main plugins and strictly follows Maven conventions

18:15 otherwise it can be just as bad, if not worse, than Ant

18:15 tWip: the downside is that a poorly made dependency (like say a wrong or missing scope) can grab 10 megabytes of useless stuff to your build

18:16 rzezeski: Maven...great idea...ok implementation

18:16 tWip: having sometimes forgotten to add a scope=test and seen a tenfold increase in the build artifact size :P

18:16 I think there is a dep manager for ant called Ivy iirc

18:17 * technomancy suspects a self-hosting build system is inevitable.

18:17 rzezeski: you can use Maven as a dep manager for Ant

18:17 technomancy: the great thing about being part of such a young language community is that you can have a say in how such a build system would work. =)

18:17 tWip: I'd say 1) no XML

18:17 but your mileage may vary

18:17 technomancy: tWip: of course no XML

18:17 should be a given. =)

18:19 tWip: maybe that system should include a CPAN style or cliki.net style common place to find relevant libs

18:19 but I fear reinventing the wheel

18:20 danlarkin: like pypi

18:21 technomancy: tWip: IMHO a package manager is inevitable

18:22 tWip: might be

18:25 technomancy: I don't think it should be part of the build system though.

18:26 tWip: but problems like source control, unit testing or build issues are never as interesting as the problems themselves :)

18:26 technomancy: true

18:26 tWip: so it may take considerable time to get those

18:27 but what's the rush... better to do it right, than to do it fast

18:32 technomancy: well, it's pretty easy to look at other package managers to see what they do wrong

18:32 tWip: yes, and then you are the fodder for the next generation of package managers

18:33 it's hard to get right, but for most uses "almost right" may suffice

18:34 every build system and package manager has had their fair share of weak points

18:35 * technomancy shouldn't speak authoritatively on build systems since clojure is the first language he's used that didn't have an interpreter.

18:36 technomancy: but most of the weak points of the package managers I've used are just, "we haven't gotten to that point yet" kind of problems.

18:39 tWip: interesting talks, have to sleep now as I have a 3 hour drive in the morning

18:39 technomancy: later.

18:39 tWip: bye

18:46 powr-toc: how are lazy-cons sequences garbage collected? Presumably it's when the reference to the lazy-seq is lost?

18:50 hiredman: (doc defmethod)

18:50 clojurebot: Creates and installs a new method of multimethod associated with dispatch-value.

18:51 danlarkin: hiredman: HEYOooooo

18:51 hiredman: that wasn't very useful though

18:51 danlarkin: powr-toc: right, if there's no reference to data the jvm will clean it up according to its GC scheme

19:00 mmcgrana: So I'm playing around with my html doc generator right now and I've come across a few things in the Clojure source: let me know if anyone has any thoughts on this stuff:

19:00 - clojure.core/! is still in there

19:01 - several of the *named-vars* don't have docstrings, e.g. *file* and *err*

19:01 hiredman: clojurebot: defmethod docstrings is <reply>defmethods don't get docstrings :(

19:01 clojurebot: Roger.

19:02 mmcgrana: - in clojure.contrib.seq-utils, I think flatten and seperate could use (remove f... instead of (filter (complement f) ....

19:02 - again in seq-utils, group-by and partitioin-by seem to have their arg vectors in the wrong spot relative to the docstring

19:04 maybe i should just make some patches and post them to the group

19:05 danlarkin: mmcgrana: that would be productive

19:07 mmcgrana: i still have to send a CA in, so it will be a few days of turnaround. clearly no hurry on this stuff though.

19:32 hiredman: woa

19:33 so, I am compiling some clj that uses (rand-int ...) and it is generating a lot of class files

19:34 Chouser: one class file per fn

19:34 at least

19:34 hiredman: uh

19:34 much more

19:34 ok

19:35 so I get and exception like: java.lang.RuntimeException: java.lang.ClassNotFoundException: hiredman.clojurebot$random_response__706 (NO_SOURCE_FILE:0)

19:35 evertime I run (compile ...)

19:36 different everytime, and everytime in generates more class files in ~/classes

19:36 mmcgrana: inner, anonymous functions maybe, like #(+ % 2) ?

19:36 hiredman: uh

19:36 there are over 600 of them right now

19:37 clojurebot$random_response__97.class

19:37 etc

19:37 lisppaste8: url

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

19:38 hiredman pasted "random-response" at http://paste.lisp.org/display/70864

19:38 Chouser: since the classes are given unique names, running compile will make more class files each time you run

19:38 If you want a minimal set of class files, clear out your classes dir and do one compile.

19:39 hiredman: Chouser: the compile always ends with a class not found exception

19:40 Chouser: make sure you have ./classes in your classpath, and that the dir exists before you start java

19:40 hiredman: aht may be it, maybe ./classes is not in my cp

19:42 oops

19:43 that was the wrong repl to close

19:43 Chouser: heh

19:44 hiredman: ugh

19:49 * technomancy just read somewhere that clojure doesn't take advantage of libjline if it's installed via apt-get.

19:49 technomancy: is this true?

19:50 Chouser: you mean automatically?

19:50 I shouldn't answer, I don't know. I use rlwrap

19:50 technomancy: right; like you have to manually add it to your CLI invocation

19:50 Chouser: that seems likely

19:50 technomancy: that... is terrible.

19:50 but I forgot about rlwrap

19:51 is that just a limitation of java then? no good way to take advantage of system-level libraries?

19:53 Chouser: sorry, I don't really know. I thought jline was a java lib, in which case it would be a matter of adding it to your classpath and clojure's repl knowing to look for it.

19:53 Chousuke: technomancy: you need to explicitly call jline for it to work

19:53 powr-toc: technomancy: no it's not a limitation of java... as chooser says, it just needs to be on the classpath

19:54 Chousuke: clojure never even knows jline is there.

19:54 technomancy: it just seems strange that apt-get doesn't place it on the classpath automatically

19:54 (the classpath is basically just java's load path, right?)

19:54 Chousuke: As far as I know, jline just wraps some classes and filters input before it reaches clojure.

19:54 powr-toc: technomancy: well, with java, that's usually a bad thing

19:55 Chousuke: technomancy: you can add it to $CLASSPATH :)

19:55 powr-toc: $CLASSPATH is evil though

19:56 Chousuke: well, it works :P

19:56 technomancy: just seems like it's busywork. what's the point of a package manager if it can't install libraries in the right place for you?

19:56 powr-toc: I mean it's fine for toying about, but it'll bite you in the ass later if you're not careful

19:56 Chousuke: technomancy: it does install them in the right place.

19:57 technomancy: Chousuke: in my mind the right place is somewhere where clojure can use it.

19:57 Chousuke: technomancy: that can be anywhere.

19:57 technomancy: besides, clojure doesn't use jline.

19:57 the wrapper script does.

19:58 technomancy: ok... obviously I am missing some big piece of the puzzle, so I'll just stay quiet until I know what I'm talking about.

19:58 powr-toc: technomancy: just start clojure with: java -cp /path/to/clojure.jar:/path/to/jline.jar clojure.lang.Repl


19:58 Chousuke: technomancy: in the wrapper script, it's just one additional element in the classpath specification.

19:58 technomancy: in general, you don't want system wide libraries automatically in your classpath

19:58 technomancy: Chousuke: that's what I don't understand.

19:59 it works great for every other language.

19:59 powr-toc: technomancy: if the package manager were to set your classpath system wide for you, you'd likely end up with horrendous version conflicts... between different programs

20:00 Chousuke: technomancy: java is different :)

20:00 technomancy: oh, is there no way to state dependencies on specific versions then?

20:00 Chousuke: technomancy: avoids a whole lot of problems by being explicit.

20:01 technomancy: you specify the appropriate versions in your classpath and there is no problem.

20:01 powr-toc: technomancy: jar files in and of themselves; don't know what they depend on.

20:03 technomancy: to me it all just sounds like, "make the user do the work the computer normally does". but... I'm just getting used to it, maybe once I start using it things will make sense.

20:03 Chouser: technomancy: your instincts are rational. I had a similar conversation several months ago.

20:04 Chousuke: technomancy: it's still possible to have a system-wide classpath

20:04 technomancy: I'll just try to keep my dependencies on Java code to a minimum. Sounds like a headache.

20:04 Chousuke: technomancy: but as said before, that might break things.

20:04 Chouser: technomancy: I was arguing with Rich (which is a bad sign in itself) and ended up dropping it not because I was convinced java is right but because I trusted the people that had the opposing opinion.

20:05 Chousuke: technomancy: that helps. or you can be lazy and wrap all the deps in a single .jar :/

20:05 technomancy: Chouser: yeah, my first day trying clojure/java is not a good time for me to get in an argument about this kind of thing.

20:05 Chouser: I'm still not fully convinced -- it seems odd to me every time I write an app and have to adjust my clojure command-line to set up the dependencies on .jar's I've already apt install'ed.

20:06 technomancy: Chousuke: then when a security update gets published, it's my fault if stuff doesn't get updated. =\

20:06 Chousuke: I think java's way of doing things is the only sane way if you want to maintain the "write once, run anywhere" illusion :p

20:06 powr-toc: technomancy: java 7 is supposedly going to introduce superpackages with jsr 294

20:06 Chouser: but it's not so terrible to work around, and having just built my first stand-alone jar with all the deps bundled inside, I'm wodering if I'm getting closer to the 'goodness'.

20:07 technomancy: worse still, the users will think to themselves: "I've run an apt-get upgrade to pull in the new versions, so I shouldn't be vulnerable", but the bundled versions don't get touched.

20:07 Chousuke: technomancy: the bundled versions are inside your own .jar. you need to make a new release.

20:08 powr-toc: Chouser: I can't speak for clojure so much, but in Java I tend to throw all my apps jars into a single directory, and use a shell script to pull all *.jar's in and build the classpath string dynamically

20:08 technomancy: Chousuke: right, but that's the kind of problem a package manager is designed to avoid.

20:08 Chousuke: technomancy: or you can make your software so that it sets it classpath properly.

20:08 powr-toc: then you just manage whats in the directory

20:08 Chousuke: its*

20:08 technomancy: I can never be as timely in my releases as Ubuntu

20:08 Chousuke: technomancy: so that it refers to the system-installed libraries

20:08 or you can count on the distributor to do it for you :D

20:09 technomancy: but the locations of those libraries will be different on every OS, so the distributor *has* to do it

20:09 Chouser: Chousuke: but even setting the class path from inside your app is discouraged, which means if you want to do it right you've got to do it in shell script or something.

20:10 Chousuke: technomancy: that's what ./configure solves for most apps... I wonder if there's some similar mechanism for java.

20:10 libs certainly aren't all in the same place accross all systems.

20:10 across*

20:11 powr-toc: Chousuke: there are systems for that kinda thing... maven etc... but they're not really worth the hassle unless you REALLY need them

20:11 and they're more for build time resolution

20:11 Chousuke: well, yeah

20:11 I guess it's as if java does "linking" at startup time I guess.

20:12 powr-toc: Chousuke: that's exactly what it does

20:13 Chousuke: Actually, it seems to me compiled apps don't have a real advantage. You still need to specify the lib paths correctly at compile time.

20:14 compile-time-linked apps*

20:15 powr-toc: Chousuke: they can be relative though, and in java classes can be loaded in at runtime... and not necessarily from the filesystem... I'd imagine clojure makes use of this to provide compilation from the repl etc...

20:15 Chousuke: hmm, yeah

20:15 every function is compiled into its own class and loaded.

20:16 in the end, the java system is much more complex, but also much more flexible :/

20:17 powr-toc: Chousuke: there isn't really a notion of compile-time-linked (assuming you mean statically linked) in java... it's linked at runtime...

20:19 Chousuke: that's what I thought; earlier I meant "traditional" apps, like ones coded in C.

20:19 powr-toc: Chousuke: yeah... I just re-read what you'd written... and got that sense :-)

20:37 sohail: well it's official

20:37 visual studio is stupid

20:39 technomancy: ... and?

20:40 quuxman: hi. I just downloaded clojure and I'm having a lot of trouble getting it to run with jline

20:40 it runs by itself just fine, but when I try to run it with jline.ConsoleRunner I get: ClassNotFoundException: clojure.lang.Repl

20:42 Chousuke: hmm :/

20:42 runs without jline?

20:42 quuxman: Chousuke: yeah, with the exact same command classpath, or with none at all

20:42 danlarkin: quuxman: had somebody in here the other day with the same problem, I'll tell you the same thing I told him: try rlwrap, works for me :)

20:43 Chousuke: I don't use either

20:43 I just use SLIME :P

20:44 quuxman: danlarkin: Thanks. Guess that'll have to do for now... no tab completion though.

20:44 Chousuke: quuxman: there's info for that on the wiki

20:44 quuxman: Chousuke: with rlwrap? How does that work?

20:44 Chousuke: well readline can do tab completion

20:45 quuxman: I'm just curious how it communicates with clojure

20:45 Chousuke: so you just need to generate a list of completions for it to use

20:45 it doesn't

20:45 it just blindly tabcompletes what you have in the completion file.

20:45 quuxman: Chousuke: oh, that's lame ;)

20:45 Chousuke: if you want something better, use emacs and SLIME :p

20:45 quuxman: I'm a vim guy

20:46 * quuxman ducks

20:46 Chousuke: yeah, so was I

20:46 * Chousuke uses viper & vimpulse.el

20:46 danlarkin: rlwrap works with completions well enough for my REPLing, but I'm mostly in emacs/SLIME too

20:47 Chousuke: emacs is a good enough vi for me ;P

20:47 * danlei loves partial completion

20:47 Chousuke: has a few glitches though, but works.

20:47 I use the editor in some half-vi half-emacs way nowadays

20:48 quuxman: Chousuke: I may actually check out viper and vimpulse.el when I have some time... or is it really easy to set up?

20:48 Chousuke: quuxman: it wasn't that hard.

20:49 viper comes with emacs and vimpulse.el is just one file to download. and has instructions

20:49 quuxman: Chousuke: ok cool. Ack, I don't even have emacs installed :-P

20:50 * quuxman starts 55mb download

20:50 Chousuke: sometimes enabling other modes throws me out of viper mode, but you can always get back to it with M-x viper-mode

20:50 cooldude127: Chousuke: can't get much easier to setup than that lol

20:50 Chouser: Chousuke: C-z often seems to do it

20:51 Chousuke: quuxman: I dunno if it works for you, but I tolerated emacs just for SLIME. viper is a bonus.

20:51 Chouser: manually running clojure-mode does it too :/

20:51 until I added a hook to run viper-mode whenever clojure-mode is run :P

20:52 Chouser: Chousuke: sorry, I meant C-z often gets me back into viper mode if the new buffer kicked me out

20:52 Chousuke: for me that just minimises emacs.

20:52 Chouser: ha! ok.

20:52 Chousuke: I suppose viper does that on level 3

20:52 Chouser: I'm on level 3

20:53 Chousuke: ... hmm

20:54 oh, well. having to type the occasional M-x viper-mode is not too bad :P

20:55 * Chouser nods

20:55 Chousuke: It's sad but emacs really beats vim to the ground in flexibility.

20:55 Chouser: it's ok. you can let your editor run you instead of the other way around.

20:56 if it want's you to type M-x viper-mode every so often, you'd better just comply.

20:56 :-)

20:56 Chousuke: I may figure out how to fix that some time.

20:56 I'm still an emacs newbie so I may be doing something wrong.

20:58 quuxman: where would I find my site-lisp directory?

20:58 (to put vimpulse.el)

20:59 ah: /usr/share/emacs/site-lisp

20:59 danlei: quuxman: you can put it everywhere you want and (add-to-list 'load-path "/path/to/files")

20:59 +/

21:00 Chousuke: I'm going to get some sleep now though. Good night.

21:00 quuxman: w00t... rectangular edit actually works with vimpulse. First vim clone I've used that actually bothers with such a crucial feature

21:00 though the undu is fucked

21:01 redo does not do what I expect

21:01 Chousuke: I think there was something about redo in the instructions.

21:01 Chouser: I think you do use . to keep undoing further. u again to switch directions

21:01 danlei: it's more like in the original vi

21:01 quuxman: Chousuke: oh interesting

21:02 er, Chouser. Damn your nicks are too similar

21:02 Chouser: yeah, I know.

21:03 Chousuke: well, not as bad as drewr and drewc at least!

21:04 quuxman: I'll laugh if I ever alias vim=emacs

21:04 Chousuke: I see drewr-` has grown a tail!

21:08 quuxman: how do I get rid of the menu at the top?

21:08 (in emacs)

21:09 ah: M-x menu-bar-mode

21:10 now it's just a question of how I get clojure running in emacs

21:10 Chousuke: the instructions in the wiki should work

21:10 but you'll need a more recent version of clojure

21:10 preferably SVN HEAD :p

21:11 the download version is quite ancient.

21:12 anyway, I'm off

21:21 quuxman: wow, this is kind of like the best of both worlds... most vim commands work _and_ a lot of emacs commands

21:22 most importantly M-x foo

21:22 rzezeski: does it really feel like Vim? I'm trying to relearn Emacs right now and it just doesn't feel right to my fingers

21:22 clojurebot: Goliath Online

21:22 danlei: don't be surprised. emacs is the lord

21:23 quuxman: how do I disable the annoying start message?

21:23 danlei: (setq inhibit-splash-screen t)

21:23 quuxman: danlei: thanks :)

21:25 danlei: btw: i just let emacs run all the time. (emacsclient & (start-server))

21:27 quuxman: anybody have a cute little clojure program I can fool around with to get my feet wet? Preferrably a simple graphics program

21:27 danlei: there is one at the home page, under java interop, iirc

21:29 ah, no under "hosted on the jvm"

21:29 and there is always the ant simulation

21:31 quuxman: where do I find the ant simulation?

21:32 danlei: a sec

21:33 http://clojure.blip.tv/file/812787?filename=Richhickey-ClojureConcurrency252.flv and the program should be linked there

21:34 theres also a never version under files at the google group page, i guess

21:35 *newer

21:35 quuxman: cool, I just ran the little temperature converter program

21:36 works fine aside from the god-awful fonts swing is using

21:36 danlei: hm

21:36 you're under linux?

21:36 quuxman: ubuntu

21:36 but I'm not about to jump in to a mire of font configuration fun

21:36 danlei: (javax.swing.UIManager/setLookAndFeel "com.sun.java.swing.plaf.gtk.GTKLookAndFeel") maybe helps

21:43 clojurebot: help

21:46 clojurebot: clojurebot got moved to svn head, so now, of course, nothing works

21:48 quuxman: what does this line do: (def frame (doto (new JFrame) (.add panel) .pack .show)) ; ?

21:49 danlei: you mean the doto?

21:49 Chouser: it calls add, pack and show methods of the new JFrame

21:49 then stores that JFrame in frame

21:49 quuxman: ok. But the program never uses frame

21:49 danlei: well

21:49 .show

21:49 quuxman: oh I see

21:50 so it shows a window as a side affect and runs the rest of the program

21:51 danlei: doto just makes the object implicit in the method calls

21:51 without it,

21:51 you'd have to evaluate (.show frame), for example

21:52 quuxman: presumably if you were just calling one method you could say: ((nej JFrame).add panel) ; ?

21:53 or does it not work like that

21:53 danlei: (.add (JFrame.) panel)

21:53 basically, yes

21:53 (.add (new JFrame) panel)

21:53 quuxman: how is .add in scope? What if another object had an add method

21:53 danlei: well, jframe is an argument to .add, so its clear

21:54 quuxman: crazy

21:54 danlei: foo.bar -> (.bar foo)

21:54 danlarkin: .method is reader syntax

21:54 http://clojure.org/java_interop

22:14 hiredman: (doc defmethod)

22:14 clojurebot: Creates and installs a new method of multimethod associated with dispatch-value.

22:14 arohner: oh that's cool

22:14 hiredman: clojurebot: botsnack

22:14 clojurebot: botsnack is delicious. (nom nom nom)

22:14 danlei: (+ 1 2)

22:14 hiredman: heh

22:14 danlei: :)

22:14 hiredman: just doc string lookups

22:15 from clojure.core

22:15 danlei: (doc conj)

22:15 clojurebot: conj[oin]. Returns a new collection with the xs 'added'. (conj nil item) returns (item). The 'addition' may happen at different 'places' depending on the concrete type.

22:15 danlei: nice

22:15 the format is a little messed up, though

22:16 clojurebot: botsnack

22:16 clojurebot: botsnack is delicious. (nom nom nom)

22:16 hiredman: yeah, well, yes

22:16 danlei: is the source online?

22:16 hiredman: uh

22:16 sort of

22:16 I was just going to get around to that in a better way

22:17 danlei: sure

22:19 hiredman: http://gist.github.com/27733

22:20 danlei: hiredman: thanks

22:21 hiredman: np

22:21 danlarkin: (doc test

22:21 clojurebot: I don't understand.

22:21 danlarkin: (doc coll?

22:21 clojurebot: I don't understand.

22:21 danlarkin: touch�, clojurebot

22:22 hiredman: (doc coll?)

22:22 clojurebot: Returns true if x implements IPersistentCollection

22:23 danlarkin: I wanted to see if it'd respond to a (doc without a closing paren

22:26 clojurebot: svn

22:26 clojurebot: svn co https://clojure.svn.sourceforge.net/svnroot/clojure clojure

22:27 rzezeski: clojurebot: a/s/l?

22:27 clojurebot: Excuse me?

22:27 rzezeski: :)

22:27 danlei: clojurebot: lisp?

22:27 clojurebot: I don't understand.

22:27 danlei: clojurebot: lisp is great

22:27 clojurebot: Roger.

22:27 danlei: clojurebot: lisp?

22:27 clojurebot: lisp is great

22:28 danlei: clojurebot: botsnack

22:28 clojurebot: botsnack is delicious. (nom nom nom)

22:29 danlarkin: clojurebot: clojurebot is wacky!

22:29 clojurebot: You don't have to tell me twice.

22:29 danlarkin: clojurebot: clojurebot

22:29 clojurebot: clojurebot is wacky!

22:51 hiredman: ugh

22:54 quuxman: can clojurebot run clojure?

22:54 > (+ 1 2)

22:57 hiredman: not at this point

22:57 I am leary of allowing other people to run code on my computer

22:58 in the future it may run some subset

23:04 Chouser: hiredman: wise. But java does have sandbox features that might be useful.

23:09 rzezeski: someone help a git n00b please...I want to checkout (clone?) swank-clojure...I tried "git clone http://github.com/jochu/swank-clojure" but that said something about update-server-info...

23:11 danlei: git clone git://github.com/jochu/swank-clojure.git

23:12 works for me

23:12 rzezeski: that seemed to do the trick, thx

23:16 danlei: is _ inside a lambda list something special, or is it "just" used by convention?

23:16 Chouser: convention

23:17 danlei: thanks

23:32 hiredman: clojurebot: where are you is <reply> http://gist.github.com/27733

23:32 clojurebot: You don't have to tell me twice.

23:33 hiredman: clojurebot: where are you?

23:33 clojurebot: http://gist.github.com/27733

23:36 spaceman_stu: thanks for pasting the code for the bot hiredman. Interesting to look over

23:39 hiredman: I think I got an automated dingo that will update that page from my personal bzr repo

23:39 Chouser: anyone have an idea for converting hex stored in a string to an int?

23:40 danlarkin: hiredman: what's the purpose of the <reply> part?

23:40 Chouser: java doesn't have anything built in to do that?

23:40 Chouser: beats me, that's why I'm asking.

23:41 hiredman: clojurebot: clojurebot?

23:41 clojurebot: clojurebot is wacky!

23:41 hiredman: without the reply

23:41 with the <reply>

23:41 arbscht: (Integer/parseInt "A" 16)

23:41 hiredman: clojurebot: where are you?

23:41 clojurebot: http://gist.github.com/27733

23:42 Chouser: arbscht: fantastic, thanks

23:42 hiredman: <reply> lest you specify a response without it having to be in the format "A is B"

23:43 arbscht: like that?

23:43 danlarkin: ah ha, I see

23:56 arohner: is it possible to create a macro that emits a call to binding?

23:57 every time I try, the symbols are evaluated

23:57 and emitting (binding [(quote foo) (bar)]) doesn't work

Logging service provided by n01se.net