#clojure log - Oct 20 2009

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

0:00 steiger: bye guys

0:13 technomancy: "the biggest issue with all dynamic solutions is they often don't work in production without specific bridges to the application host (netbeans, osgi, netkernel etc)." <= rich earlier today

0:13 jruby probably doesn't care about that kind of compatibility

0:14 neither do _I_ for that matter

0:15 I can understand why Clojure doesn't offer a dynamic classpath out of the box, but it would be great if it provided a way to do that if you really wanted it.

0:17 ,(.getContextClassLoader (Thread/currentThread))

0:17 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)

0:18 technomancy: that's a #<DynamicClassLoader clojure.lang.DynamicClassLoader@84cc09>

0:18 maybe there's a way to use that to load a given class

0:23 nope; looks like even classes explicitly loaded with the DynamicClassLoader do not honor its dynamic classpath.

0:23 that's a shame

0:31 eyeris: My god I hate the classpath.

0:34 mikehinchey: add-classpath doesn't do what you need?

0:34 eyeris: I hate that my code has to be in the same classpath as my tools

0:35 e.g. vimclojure's nailgun server's classpath has to be able to access both my code and it's own

0:35 which means that my code and vimclojure both have to be compatible with specific versions of clojure and libs

0:36 But in general, I shouldn't have to have a different script to launch each tool

0:36 mikehinchey: how would it execute your code if it couldn't access them?

0:36 eyeris: that all just manipulate CLASSPATH a little differently

0:36 I am not trying to solve the problem

0:37 I am just bitching that it suck

0:37 s

0:37 technomancy: mikehinchey: add-classpath only alters the current instance of clojure.lang.DynamicClassLoader

0:38 in many instances that's not enough

0:38 not that I know why

0:40 riddochc: This is weird...

0:40 clojurebot: (str "\" "/") ")

0:40 clojurebot: Titim gan éirí ort.

0:41 riddochc: Woah. Even weirder.

0:41 mikehinchey: oh, maybe your onerous library is on the system classloader, so a child cl won't work

0:41 riddochc: For me, it gives: "\" clojure.core$_SLASH___4461@18c3679) "

0:41 This is out of an effort to get (str "\" "/") => "\/"

0:42 Which was brought about by trying to do something like (println (re-gsub #"/" "\\\/" "one/two/three"))

0:43 mikehinchey: ,(str "\\" "/")

0:43 clojurebot: "\\/"

0:43 technomancy: mikehinchey: I don't think it's _the_ system classloader, since JRuby is able to modify the classpath in a way that makes it work.

0:43 but it's some other classloader that isn't honoring my changes

0:59 riddochc: Now, *that's* what I wanted:

1:00 clojurebot: (println (re-gsub #"/" ,(str "\\\\" "/") "one/two/three"))

1:00 clojurebot: It's greek to me.

1:00 riddochc: ,(println (re-gsub #"/" ,(str "\\\\" "/") "one/two/three"))

1:00 clojurebot: java.lang.Exception: Unable to resolve symbol: re-gsub in this context

1:01 riddochc: Well, okay. It prints "one\/two\/three" - leaning toothpick syndrome, for sure.

1:02 tomoj: what's the point of (str "\\\\" "/") ?

1:08 riddochc: A situation of genuine double-escape need... Clojure's producing a string that will get interpreted by another program as code.

1:13 Made even more fun, of course, by the fact that things need to be escaped differently for this other program than they are for Clojure.

1:13 And yes, it deserves a few lines of comments.

1:33 hiredman: java.lang.ClassFormatError: Duplicate method name&signature in class file hiredman/reader/StringReader

1:33 what a drag

1:33 the java part compiles fine but compile-clojure pukes

2:14 Atif: ping

2:14 arbscht: pong

2:15 aatifh: arbscht, i have this float value 38.20000076 and just 38.20 how to do that?

2:18 ping

2:35 ping

3:10 yason: aatifh: assumedly you want to print the floating point number into a string?

3:10 aatifh: yason, yes

3:11 yason: aatifh: see the format function

3:11 aatifh: yason, hmm

3:11 yason: it's akin to printf() in C

3:17 aatifh: yason, so, thats it (format "%.2f" (Float/parseFloat "-12.1021"))

3:17 yason, I hope its a better way

6:43 mikem`: date

7:39 serp_: platt katt

8:55 AWizzArd: ~max people

8:55 clojurebot: max people is 185

8:56 licoresse: ~what's for dinner?

8:56 clojurebot: for is a loop...in Java

8:57 licoresse: ,*clojure-version*

8:57 clojurebot: {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}

8:58 snowwhite: What is the best to get the datetime object of a month before the current datetime?

8:58 *way

8:58 AWizzArd: What is a datetime object?

9:00 snowwhite: AWizzArd, Java datetime object

9:01 AWizzArd: i heared of java.util.Date

9:01 ,(.format (java.text.SimpleDateFormat. "yyyy-MM-dd_HH-mm-ss") (java.util.Date.))

9:01 clojurebot: "2009-10-20_06-08-37"

9:02 AWizzArd: maybe this is what you want

9:02 liwp: I think if you want to do maths with dates (i.e. the month before the current time) you'll have to use java.util.Calendar

9:03 if you have to do complex date/time stuff, look into yoda (?) which is an advanced date/time java lib

9:04 ahh, joda: http://joda-time.sourceforge.net/

9:04 licoresse: (dec (.getMonth (java.util.Date.)))

9:04 liwp: licoresse: and now turn that into a date again ;)

9:05 licoresse: :D

9:05 chouser: It's just too horrible:

9:05 ,(.getTime (doto (java.util.Calendar/getInstance) (.add java.util.Calendar/MONTH -1)))

9:05 clojurebot: #<Date Sun Sep 20 06:12:33 PDT 2009>

9:06 chouser: snowwhite: that's the normal way to do it with builtin java classes, but from everything I hear I'd recommend you use joda time if a 3rdparty lib is at all an option.

9:12 liwp: looking at the joda api (I've never used it myself) it seems that (new Instant()).minus(Months.ONE) could work

9:13 there's probably some other, more idiomatic way of doing it, which would avoid the Instant instantiation...

9:16 snowwhite: chouser, Thank you so much.

9:16 mikem`: hello, beginner having some trouble: http://paste.lisp.org/display/88978 what's this exception telling me? Note there are some annotations with more details down the page

9:19 I think it's the laziness biting me

9:21 tomoj: you defined process-spec-list to just be the identity, and (get-package-specs ..) worked, but (process-spec-list (get-package-specs ..)) didn't?

9:22 that's... odd

9:22 Chousuke: try (println (doall specs))

9:22 to see if it has something to do with laziness

9:24 mikem`: Chousuke: ah, you're right. I needed to doall the sequence

9:24 Chousuke: that's weird though

9:25 it should work even without doall :/

9:25 mikem`: hm, maybe I should get the hang of things first before using lazy functions

9:26 chouser: what is get-package-specs ?

9:27 mikem`: Chousuke: get-package-specs is: http://paste.lisp.org/display/88978#4

9:28 Chousuke: mikem`: that doesn't return a vector though :)

9:28 I don't think that should explode though.

9:28 mikem`: ah, my docs are out of sync :)

9:28 tomoj: that shouldn't cause a Character->ISeq error, should it?

9:28 Chousuke: unless read-lines does something silly.

9:29 chouser: read-lines is a bit dangerous, but I don't see how it could cause that error

9:30 rhickey_: if you realize the lazy seq after the file is closed you will have problems. Look through the stack trace for the cause

9:31 Chousuke: read-lines is not a core function though.

9:31 mikem`: is it from contrib or did you write it yourself?

9:31 mikem`: read-lines? it's from contrib.duck-streams

9:32 Chousuke: 'k. I guess it should be fine.

9:32 chouser: read-lines will tend to leak the file handle rather than close too early.

9:32 mikem`: I can't reproduce it here -- can you paste the whole stack trace?

9:33 mikem`: chouser: i'm having troubles reproducing it too, now

9:34 are these lazy seqs cached somehow?

9:34 rhickey_: mikem`: have you rebuilt Clojure while running?

9:34 chouser: I wonder if some of your fns were not defined as you thought they were. 'source' shows the definition of a fn as it is in a file, not necessarily the way it's currently defined.

9:36 mikem`: rhickey_: nope. I was playing with the definition of process-spec-list, and it was probably wrong at the start. but the error didn't go away even when I changed its definition to the identity. that's why I'm asking whether the lazy-seq is cached somehow

9:36 chouser: ah, i see. I thought source would show me the function as it is currently defined in memory

9:36 rhickey_: mikem`: are you using Slime?

9:36 mikem`: rhickey_: no, vimclojure

9:37 chouser: lazy-seqs do cache their realized values, but if you're calling 'get-package-specs' each time then you're getting a new seq and nothing should be cached.

9:37 rhickey_: a stack trace would help

9:38 mikem`: in that case, it might be an issue with the function as defined in the source vs being executed

9:38 if i get this exception again, I'll get the stack trace :) thanks for the help

9:40 chouser: rhickey_: all the dispatch-fns in a multiprotocol should have the same range even if their domain is different?

9:40 I guess that's essentially what you say in the first sentence.

9:41 tomoj: I wonder why compile errors in slime show up in *inferior-lisp* instead of popping up debugger buffers

9:42 The-Kenny: tomoj: They trigger a debugger-buffer here.

9:43 tomoj: The-Kenny: orly? what versions of emacs, clojure-mode, and swank-clojure?

9:44 The-Kenny: tomoj: http://img4.abload.de/img/screenshot2009-10-20at1aii.png

9:44 tomoj: A very recent slime from cvs, clojure-mode etc. fresh from github.

9:44 tomoj: is that aquamacs?

9:44 The-Kenny: Yes

9:45 * eevar2 is happy with emacs.app 23.1 from macports

9:45 tomoj: hmm.. I'm using emacs 22. I'll try it on aquamacs to see if that's it or if there's something wrong with my clojure/slime setup

9:45 eevar2: and now the people in #emacs don't shun me any more ;)

9:45 rhickey_: chouser: no, just that the mapping of the set of methods must be to a single dispatch value

9:46 Chousuke: emacs.app 23.1 works fine

9:46 tomoj: I get a "Compilation failed: ..." in the minibuffer and the stacktrace in *inferior-lisp*

9:46 Chousuke: though it's a bit slow

9:46 rhickey_: chouser: but one mapping could be to [:a :b] and another to 42

9:48 Chousuke: I tried Yamamoto Mitsuharu's mac'ified port of emacs and it was a bit faster but I hit some bug that made me unable to type square or curly brackets, so I was kind of forced to return to plain old emacs.app :P

9:49 I wish they'd use git or something though. having to apply patches manually is a pain.

9:50 tomoj: does anyone using gnu emacs get compilation errors in a debugger buffer?

9:56 cgrand: rhickey_: have you any plan to suppoty primitive types (for args or return value) in protocols fns?

9:56 rhickey_: cgrand: not other than the ones to support them in general for fns

9:56 since protocol fns are merely fns

9:57 I guess the dispatch arg cannot be primitive in any case

9:57 tomoj: is there somewhere I can read about protocol fns?

9:58 rhickey_: http://www.assembla.com/wiki/show/clojure/Datatypes

9:58 http://www.assembla.com/wiki/show/clojure/Protocols

9:58 tomoj: thanks

9:58 cgrand: ok, then what are you plans for primitives support in fns?

10:00 rhickey_: cgrand: Not fully worked out, but I'm thinking about supporting only longs and doubles, cutting back on the number of arity overloads in IFn (10?) and adding combinations for up to 4? args of mixed type

10:01 returns might have another interface, since can;t overload on return type, but also require more inference of return type, or more hints (call foo returning long)

10:01 sine longs cover all integer primitives and doubles cover floats

10:01 since

10:03 cgrand: ok, thanks

10:04 rhickey_: so compiler seeing (foo x) used as an arg taking long, or #^long (foo x) will convert foo to ILongFn and then invoke

10:05 Chousuke: is there any way to force clojure to recompile a namespace? I have problems bootstrapping my reader because clojure doesn't seem to recompile namespaces of which I have another (compiled) version already loaded...

10:05 cgrand: with protocols and datatypes, PersistentVector (for example) would be still be implemented with reify to support java Interfaces (and IFn?)?

10:05 chouser: this is probably beyond 1.1?

10:06 [rephrasing] primitive support in fns will probably be after 1.1?

10:07 rhickey_: chouser: definitely, probably after cinc so we can use macros for the vast boilerplate :)

10:08 cgrand: I'm still thinking about that. Obviously if there are still lots of interfaces that will need to be implemented then that will push one off of datatypes...

10:09 chouser: ah, yes. I used a couple macros in finger trees for reify boilerplate. Turned out well there I think.

10:09 rhickey_: supporting interface implementation in datatypes definitely complicates things, but I have looked at it

10:10 tmountain: just curious... how soon should we realistically expect to see cinc?

10:10 rhickey_: In the end I decided that reify still had the problems closures do, the data is opaque and inaccessible to all but the code created at the same time, thus inextensible

10:12 if I bring interface implementation support to datatypes it will be strictly curtailed to interfaces only, none of this abstract/super/protected junk

10:12 implementation inheritance is truly a mess

10:14 saml: is it easy to replace some java classes with clojure without letting the team know?

10:18 Chousuke: saml: if everything uses interfaces, maybe... otherwise, maybe not :P

10:19 saml: this code makes me want to go home

10:21 rhickey_: tmountain: not until after the mechanisms are in place to avoid Java - reify, protocols and datatypes are about that.

10:24 tmountain: rhickey_: just perusing the Datatypes wiki page... it's very cool to see even more performance enhancements coming down the pipe

10:28 AWizzArd: rhickey_: will you implement datatypes using newnew?

10:29 rhickey_: AWizzArd: no, they represent a different approach to the same issues, more finely sliced even than new new.

10:38 RomanRoe: Is it possible to store the vector used in a binding in a var for reuse? E.g. (def myb '[*a* 1]) & (binding myb ...) ?

10:42 rhickey_: RomanRoe: no

10:43 compile time is about forms, and runtime about their values

10:44 chouser: saml: yes, you can use gen-class and gen-interface to make a very clean Java API so that users of your classes don't need to know it's implemented in Java.

10:45 rhickey_: protocols+datatypes could replace reify, couldn't they? But that's not the plan because reify will still perform better?

10:46 rhickey_: chouser: what protocols + datatypes are missing is a bridge back to Java interfaces, esp. consumption from Java

10:46 perf-wise I expect protocols to be competitive if they don't get laden with more dynamicity :)

10:47 dataypes are raw Java classes

10:47 smae perf

10:47 same

10:47 RomanRoe: rhickey: thanks. would it work if I create a macro the wraps the binding macro?

10:48 rhickey: guess I simply have to try ;-)

10:48 chouser: rhickey_: so might reify be cut yet?

10:51 rhickey_: chouser: I see two things needed - some story for abstraction in Clojure proper (current best idea - datatypes + protocols). That might include interface implementation in datatypes, but I strongly desire not pulling in Java semantics. The other is uber-proxy, and reify is mostly there.

10:52 so uber-proxy could get all the host badness, super stuff, protected access etc, and better perf than current proxy. It certainly is what people expect of proxy

10:52 and there (proxy), closures make sense

10:52 then datatypes might get interface impl only, no superclasses, no closure

10:53 proxies remain anonymous, datatypes have useful explicit names

10:53 proxies have limitations of interfaces, datatypes don't

10:54 so good coverage of space

10:55 but I'm not focusing on the interop (proxy/gen-class) part since I want to do any enhancements to those in cinc - I'm tired of writing Java

10:55 chouser: ok, so current plans for reify have changed to not be used for native design, just interop. datatype+protocol is your current thrust for cinc.

10:56 rhickey_: chouser: yes, I'd really like for Clojure's extensibility/abstraction story to not suffer the expression problem

10:57 yet be high-enough perf to define the language itself in

10:58 so you need raw, accessible, data, Clojure is already fast at manipulating that

10:58 chouser: right, you just need a way to define it: datatypes

10:58 rhickey_: primitive args will be needed to allow high-perf code to cross function boundaries

10:59 but most altering fns create a new structure, so ordinary fns fine - after all we are going through ordinary fn > RT dispatch -> interface right now

11:02 cgrand: and with protocols that would be fn > protocol dispatch > fn. Right?

11:02 patricius_: Hi. I've been searching the net, but I can't find a clear explanation of the difference between the send and send-off functions. Can aynone explain?

11:02 I think the documentation is a little vague.

11:03 chouser: patricius_: send is for actions that are CPU-bound. send-off is for actions that might block such as on IO

11:03 patricius_: ah, thanks!

11:04 RomanRoe: patricius_: http://java.ociweb.com/mark/clojure/article.html#Concurrency scroll down to section "Agents". Helped me a lot!

11:04 patricius_: RomanRoe: thanks

11:05 Chousuke: this bootstrap stuff is giving me a headache

11:05 rhickey_: cgrand: yes, protocol dispatch built into first fn

11:06 chouser: patricius_, RomanRoe: note that there are implementation details in that article that are subject to change. This can aid understanding, just don't assume it will all remain true indefinitely.

11:08 RomanRoe: chouser: to put it in other words: when in doubt, check the source, right? ;-)

11:09 chouser: RomanRoe: well ... I was sort of going the opposite way. Check the source for *current* behavior, but rely on official docs (docstrings, clojure.org, rhickey in #clojure) for what constitutes the contract and is more likely to remain true going forward.

11:09 Chousuke: I get so far that Clojure tries to compile itself using my reader, but then explodes in the init of the ClojureReader class with the exception java.lang.UnsupportedOperationException: read (clojure.reader.ClojureReader/-read not defined?)

11:10 cgrand: rhickey_: ah ok, so fn > fn with the protocol built into the first fn for perfs.

11:10 Chousuke: and I have no idea what it's doing :(

11:10 chouser: for example, nowhere does Clojure promise that send will use a pool of threads of size CPUs+2. That happens to be true, but the formula could be tweaked at any time.

11:10 What will remain true is that send will be appropriate for non-blocking actions, and send-off for blocking ones.

11:12 RomanRoe: chouser: yep, makes sense

11:13 cgrand: rhickey_: another question (sorry to bother you), what about volatile and mutable fields? They are required for reference types, lazyseqs and transients.

11:15 patricius_: Does anyone know of an article about Clojure that I can do a 25 minutes presentation over? I'm attending a programming languages course and every student needs to present a couple of articles on programming languages and associated technologies.

11:17 chouser: patricius_: needs to be a published article, like in a real journal?

11:18 patricius_: Not necessarily.

11:19 chouser: We've had a tutorial on SmallTalk presented, which never apperead in a journal or something like that.

11:20 chouser: patricius_: there are quite a few blog posts out there that might be 25-minute size. were you hoping for a language introduction, or just some interesting feature or problem solved in Clojure?

11:22 patricius_: chouser: Well, I think an introduction to the language would be good. A detailed explanation of the concurrency features would be nice as part of that. We haven't seen a Lisp dialect in the course yet, and since I'm working with concurrent languages as part of my semester project, I think Clojure could be nice to present. In any case, my teacher will have the final decision in deciding whether the article (or website or whatever) is good enough.

11:26 chouser: perhaps the clojure tutorial here will do: http://java.ociweb.com/mark/clojure/article.html

11:26 chouser: but it maybe too long

11:26 chouser: yeah, maybe.

11:29 patricius_: chouser: anyhow, thanks for your help

11:34 rhickey_: cgrand: no bother. I'm trying to see if a nested mutable thing (a la j.u.c.Atomic*) is good enough for the base mutability case

11:34 I'd really like to avoid plain "holes" in datatypes

11:35 with reify they would have been bottled up pretty well, with datatypes not at all

11:36 cgrand: ok so better push them in host-dependent code than pollute datatypes

11:37 rhickey_: cgrand: exactly

11:38 but there may be cases where the extra alloc is prohibitive

11:41 cgrand: rhickey_: thanks, things begin to fall into place

11:43 Licenser: hmm hmm hmmm

11:43 you are discussing thins that sound interesting :)

11:57 AWizzArd: Can (load my-path) accept compiled .class files, or only .clj files (or both)?

12:05 Chousuke: ooh

12:06 after adding a hideous hack to RT.java, the reader actually works

12:06 though, it throws an exception reading core.clj

12:07 AWizzArd: Chousuke: to get your own reader you had to change existing code yes?

12:07 I mean, not just writing a new .clj file, but editing the Clojure files themselves.

12:08 Chousuke: yes.

12:09 I have a hideous hack in RT.java involving using *warn-on-reflection* as a switch to force recompiling classes *but* not all classes ;(

12:10 it turns out that when I want to recompile clojure.core using my reader, it goes and recompiles my reader as well, and... boom.

12:10 AWizzArd: Is there something like CLs defvar in Clojure? That is: (defvar x 10), x ==> 10, (defvar x 20), x ==> still 10. (I know about the defvar in Contribs "def", but this isn't doing what I want).

12:10 Chousuke: defonce

12:11 AWizzArd: good

13:33 Chousuke: hm, interesting

13:34 I apparently managed to compile clojure using my reader now, but the result fails with "Invalid method Code length 89075 in class file clojure/core__init"

13:39 hiredman: :(

13:50 mattc58: hey are there any good canonical network programming libraries out there I could use as a model for something I'm doing? Not just a toy example but a real driver for something.

13:51 i'll be writing a Clojure library to another app that has a well defined protocol specification

13:51 btw, hello everyone

14:05 kmurph79: the current clojure doesn't seem to be compiling -- anyone else have this problem?

14:06 tmountain: mattc58: have you looked at clojure.contrib.server-socket ?

14:06 Chousuke: kmurph79: works for me

14:06 mattc58: tmountain: yes I have and I've used it a bit to get going. looking more for another network library that goes against an API that someone else has already created.

14:07 rhickey_: kmurph79: ok here

14:07 tmountain: mattc58: something like apache MINA?

14:08 kmurph79: thanks, maybe i have a bad ant or java

14:10 mattc58: tmountain: is there a clojure library for it? i'm unfamiliar with it but looking at the site now.

14:10 cemerick: mattc58: are you looking for something like python's twisted?

14:11 mattc58: cemerick: no, what I'm doing precisely is playing around with MongoDB and a couple other databases. no clojure drivers exist for it, so I might do that. so, it'd be a lot of network / socket programming against their API.

14:12 tmountain: mattc58: I believe you'd have to wrap the Java calls to use MINA, but I've heard it's a good bet for blackbox networking applications

14:12 cemerick: mongo doesn't have a REST or thrift api?

14:13 mattc58: there is a REST API in dev, but the normal way of using it is through native apids

14:13 apis

14:13 there's a java, for example that i could just wrap

14:13 rhickey_: mattc58: usually the easiest way to go is to wrap the Java API

14:13 he

14:13 heh

14:14 cemerick: more than easiest -- code reuse and all that is a good thing :-)

14:15 rhickey_: http://github.com/geir/mongo-java-driver/blob/master/src/examples/clojure/mongo.clj

14:16 mattc58: yeah i saw that actually

14:16 rhickey_: I spoke with Geir last fall and gave some input on making the Java driver collection-class savvy, and thus pretty transparent for langs like Clojure which use those interfaces

14:19 cemerick: rhickey_: any chance I could convince you to add a nbproject/private/ line to clojure's .gitignore? The constant merge failures on .gitignore are more frustrating than I'd like to admit.

14:20 adityo: ,(Float/parseFloat "59641879")

14:20 clojurebot: 5.964188E7

14:20 rhickey_: cemerick: sure just put up a patch

14:20 cemerick: rhickey_: great, thanks.

14:21 mattc58: as a general statement then, are we saying that if a good Java API exists that we should simply use that, and not create new Clojure software for the same purpose?

14:21 adityo: how do i get the entire representation i.e 59641879.00

14:22 mattc58: as I use Mongo more for a project I'll determine if that actually works well in practice (it should in this case)

14:23 cemerick: mattc58: There are differing philosophies there. IMO, if the java API is well-supported and does the job, you'll benefit a lot from whatever community exists there.

14:24 rhickey_: mattc58: there are shades of gray. I'd certainly use a Java lib before writing to a wire protocol. OTOH, a lib might benefit from some Clojure-specific wrapping. Most JAva libs will have had much more use than a fresh Clojure lib, and getting leverage out of that is a big benefit for Clojure.

14:24 cemerick: If the API in question isn't clojure-friendly in some way, then it's definitely a judgement call.

14:25 rhickey_: so, it's rarely worth reinventing the lib's heavy lifting, just a question of wrap or use directly

14:26 mattc58: yeah, this all makes sense to me. ok thanks, exactly what I was looking for.

14:27 cemerick: I *almost* feel bad dispensing such advice as I dump a metric ton of legacy java code for new clojure goodness, but I have a special situation. :-)

14:27 chouser: cemerick: there's a big difference between java code that others are voluntarily maintaining, and maintaining your own .java code.

14:28 rhickey_: hmm... (deftype Name [interfaces-only] [fields] [interfaces' + Object methods a la proxy]) is doable, with more efficiency than proxy, and all written in Clojure a la proxy

14:28 with dynamic update of method defs without reload

14:28 cemerick: chouser: very, very true.

14:29 * chouser says that as he eyes dumping a couple dozen C++ classes for new clojure goodness.

14:29 chouser: rhickey_: how more efficient than proxy?

14:30 rhickey_: the biggest overhead for proxy are construction-time instantiation of fn/closure per method, plus map lookup on call, both can be eliminated for deftype

14:31 since fns would be once for entire class, and coud be stored in static fields of class, so no map lookup on call

14:32 cemerick: rhickey_, the biggest tease on freenode ;-)

14:32 liebke: adityo: do you want to change the number representation for the purposes of printing? (format "%.2f" (Float/parseFloat "59641879"))

14:32 rhickey_: but still could be dynamic, since deftype will just generate (set! DefTypeClass/methodfnfield (fn [this]...))

14:33 adityo: liebke: exactly what i wanted..thanks :)

14:33 rhickey_: as long as you don't change fields or interfaces, no reload required

14:33 liebke: adityo: you're welcome :)

14:34 rhickey_: this way no one would be forced off deftype in order to comply with JAva interface, also path to supply equals/hashCode/toString for deftypes, often needed

14:36 chouser: does no construction-time closure mean no closures at all for deftype?

14:36 and yet method fns?

14:37 rhickey_: when you say proxy for a class with 5 methods, 6 objects are created right then, with deftype 5 fns will be created when you say deftype, and only the one object when an instance of that type is created

14:38 those fns could be closures, doesn't matter, but I don't imagine deftypes at other than the top level too often

14:38 but first-class fn per method, just shared for all instances

14:38 chouser: ah.. I see. by splitting def and ctor you can of course reduce ctor-time work.

14:39 rhickey_: right, deftype isn't about creating an instance at all, where proxy gave each instance its own set of fns

14:39 so put the fns in static fields

14:39 no lookup, still swappable

14:40 chouser: so interesting. by bundling the data in the object (like normal java objects after all) you remove the use case for instance closures

14:40 rhickey_: proxy will still be a better fit when you want closures, for handlers etc

14:40 also proxy had per-instance swappability, rarely used

14:41 chouser: and by making the methods swappable (for all instances simultaneously, right?) you remove the staticness of java classes (or even hypothetical named reify classes)

14:41 rhickey_: right

14:42 * rhickey_ prepares for massive hack of proxy...

14:43 chouser: but still no access to protected fields

14:43 oh, but this is for datatypes -- native clojure, not interop

14:43 rhickey_: the only remaining overhead will be boxing in/out of fns when needed, but if ever there was a candidate for escape analysis that's it

14:43 right - what protected fields? :)

14:44 since no lookup, can inline right into fn bodies

14:46 chouser: (.invoke @MyClass/methodFn this arg1 arg2)

14:46 ?

14:47 rhickey_: right, no @

14:47 chouser: oh ... not an atom?

14:48 lock?

14:48 rhickey_: no, volatile

14:48 last-one-in-wins replacement

14:50 never read-then-write

14:50 chouser: ok

14:52 rhickey_: this seems to fit together well now

14:54 lisppaste8: rhickey pasted "deftype with interface support" at http://paste.lisp.org/display/88999

14:54 neotyk: ~logs

14:54 clojurebot: logs is http://clojure-log.n01se.net/

14:56 * cgrand never liked the implicit 'this in proxy

14:58 lisppaste8: rhickey annotated #88999 "deftype with interface no this" at http://paste.lisp.org/display/88999#1

14:58 rhickey_: cgrand: this can be autohinted, without it you're left with this first pass ^^

14:59 liebke: I like that better, explicitly passing 'this

15:00 rhickey_: liebke: and writing both 'this' and that hint over and over?

15:00 In proxy I agree could be more of an issue due to potential nesting, less of an issue here at top level

15:01 liebke: I wouldn't like to write the hint over and over, but writing 'this' over and over is fine with me :)

15:02 rhickey_: liebke: well, people won't write the hint, then will complain Clojure is slow, also won't remember this, since they will be looking at docs without it

15:02 but ok, 2 for explicit this, any other views?

15:03 liebke: true, the fundamental problem with programming language design is people :)

15:03 danlei: I agree that it should be implicit

15:03 chouser: there's middle ground -- [(equals [this that] ...)] would still allow for auto-hinted this

15:04 rhickey_: chouser: yes, the macro could retrofit the hint

15:04 chouser: on the other hand, if the map in the second example were eval'd, that would make merging in some implementations pretty easy.

15:04 cemerick: yeah, some good old-fashioned tree-walking :-P

15:05 I'll generally lean towards explicit this, FWIW.

15:05 rhickey_: chouser: yes, that second example was following the newer approach of protocols aimed at easier reuse of impls

15:06 Licenser: You know what is one thing that clojure misses, a good Textmate integration :/

15:06 rhickey_: of course, with the map approach adding hints is not possible

15:06 chouser: right

15:06 danlei: for me the major point is that nesting at toplevel won't be much of an issue. what would be the benefit of explicit this?

15:07 Licenser: I know it sounds stupid but in the OS X world a lot stands or falls with this :(

15:07 danlei: besides being ... well ... explicit

15:07 cemerick: Licenser: you mean TM integration?

15:07 Licenser: cemerick: a good bundle that is easy to install / use. something that

15:07 'just works' Sorry sully return key

15:07 chouser: Licenser: http://nullstyle.com/2008/11/09/ann-clojure-textmate-bundle-01/

15:08 dunno anything about textmate, but google does. :-)

15:08 That's almost a year old -- is that a good sign, or bad?

15:08 Chousuke: hm

15:08 Licenser: chouser: a bad sign

15:08 arsatiki: GetBundles installs the wrong clojure bundle by default

15:08 Licenser: the bundle you can get with GetBundles is horribly broken

15:09 arsatiki: the more recent version from github works so much better

15:09 Chousuke: I wonder what's causing core__init.class to become 265kB in size :(

15:10 cemerick: I'm really surprised that anyone uses TM for clojure.

15:10 Licenser: The first time I instaled clojure, and set it up in TM I had to hand fix the bundle to even work somewhat propperly - a pain that I really don't want to go through again.

15:10 cemerick: 'course, there's vi folk here, so....

15:10 * cemerick ducks, runs

15:10 Chousuke: I don't know nearly enough about the JVM to debug this...

15:10 Licenser: cemerick: You get used to TM once you start, I didn't belived it myself

15:10 cemerick: Licenser: I use it for one-off editing, but never for sustained development.

15:10 Licenser: cemerick: I usually use VI for a lot but TM just integrates so nicely into OS X that it's something you don't want to give away again once you tried it

15:11 arsatiki: I've generally found myself more and more dissatisfied with TM lately

15:11 cemerick: Chousuke: what's the error?

15:11 rhickey_: it seems to me that forgetting 'this' is a common bug for users of gen-class

15:11 arsatiki: Probably has to do with the fact that TM crashes for me almost daily now.

15:11 Licenser: cemerick: what are you using for long term things?

15:11 Chousuke: cemerick: the class is too big, simply

15:11 cemerick: JVM has a 64k limit on class files

15:12 cemerick: and I go 201kB over that.

15:12 Licenser: I used Aptana (Eclipse) for a while but I had some very annoying things with it which made me keep my hands of it

15:12 Chousuke: the verbose decompilation dump is *3.5MB*

15:12 Licenser: Chousuke: heh I had this problem with JRuby once - was very frustrating

15:13 cemerick: Chousuke: hrm, my core__init.class is 220K...but I'm not getting any errors.

15:13 Licenser: Netbeans + enclojure.

15:13 Licenser: cemerick: I'll try that one then - gladly I'm not the person that refuses to try new things :P

15:13 bballantine: cemerick, Licenser - sorry to butt in -- I think the clojure eclipse plugin (counterclockwise, I think it's called) is young but good.

15:14 Chousuke: cemerick: ah, right, it was just "invalid method code length"

15:14 it looks like it's ~20k over the limit :/

15:14 Licenser: bballantine: I've no clue, I used eclipse with Ruby not clojure

15:14 cemerick: We use NetBeans RCP, so eclipse is irrelevant for us.

15:14 bballantine: Licenser, I've used Aptana as well (for ruby on rails) and hated it. I use eclipse for all java-related stuff and really like it.

15:15 cemerick: Good luck to 'em though.

15:15 Licenser: bballantine: it looked like a good choice since in the project half the team (or most of it) were poor windows users

15:15 bballantine: i now mostly use VI for small stuff and ruby, I use eclipse for java and big python.

15:15 Chousuke: I think I'll check how big the regular clojure class file is

15:16 The-Kenny: Nacht

15:16 Chousuke: hmm, right. 216kB for me

15:16 The-Kenny: sorry.. wrong window

15:16 Licenser: Nacht The-Kenny schlaf gut

15:16 The-Kenny: Licenser: heh, I'll stay. A friend of me will go to bed now ;)

15:17 bballantine: Licenser - also, eclipse works much better on Linux than OS X for whatever reason.

15:17 Licenser: Ah well even better :)

15:17 bballantine: yes that is something we found out too

15:17 Chousuke: any ideas on how to make it smaller?

15:17 Licenser: Chousuke: remove comments? *hides*

15:18 rhickey_: Chousuke: have you got some huge data literals in there?

15:19 lpetit: counterclockwise will have its next release make it beat up emacs, vimclojure, La Clojure and netbeans so hardly that they will not be able to reach its level without a lot of dev effort.

15:19 no, it's an easter egg, of course :-)

15:19 Licenser: so the SOTA for editing clojour is the enclojure plugin and netbeans?

15:20 lpetit: What's great about clojure IDEs is that there is room for everybody

15:20 You can just keep using your preferred IDE

15:20 Licenser: I'd preffare TM since I got used to it and like how it functions

15:20 saml: notepad + clojure.jar

15:21 Licenser: saml: when I try to run notpad.exe it tells me it isn't a executable

15:21 lpetit: If you don't have any constraints, and any preferred IDE, then I would suggest to try enclojure which seems to be currently both the more advanced in terms of functionality and in terms of "user friendliity"

15:21 lisppaste8: rhickey annotated #88999 "deftype with interface explicit this" at http://paste.lisp.org/display/88999#2

15:21 saml: it's because you missed e for excellence

15:21 lpetit: But if eclipse is your IDE, counterclockwise is good enough for you, already, and will improve over time

15:22 Chousuke: rhickey_: well, it's core.clj, just compiled using my reader...

15:22 saml: i installed cljoure plugin for eclopse

15:22 Chousuke: rhickey_: it seems the init method is doing a Symbol.create and Symbol.intern for pretty much every symbol. :/

15:24 rhickey_: Chousuke: why would it be different than the Clojure reader?

15:25 Licenser: lets see now netbeans works

15:25 Chousuke: rhickey_: beats me. Maybe it's the horrible loading hacks and workarounds I put in RT.java to get it to actually compile in the first place...

15:26 liebke: rhickey: I think I like the map version better just because you pass it an actual fn, and not the 'proxy'-like method specification

15:27 rhickey_: liebke: I think the manual hinting that will require will be unbearable for many people

15:27 Chousuke: rhickey_: I had to convince it to compile a namespace that's already loaded :/

15:27 liebke: that is probably true

15:27 mwoelker: Hi there everyone, my email regarding side-effect free AOT compilation still hasn't gotten any responses and I was wondering if it's just considered a non-issue or if I did something wrong or if it has just been lost in the noise

15:29 rhickey_: mwoelker: sorry I haven't chimed in on that yet. Basically the problem is the use of reflection during compilation. That's something I want to move away from, but it will have to wait for clojure-in-clojure

15:30 lpetit: That's a joy to see so much interesting stuff in the pipe !

15:30 Chousuke: http://gensoukyou.net/core.dump.gz <- here's the disassembly of it, if someone feels like taking a look at it

15:30 jlilly: rhickey_: I'm not overly familiar with the implement x in x efforts. My impression was that they were mostly academic. What are your expectations for clojure-in-clojure?

15:30 mwoelker: rhickey_: but it should be possible to replace the reflection with some asm equivalent?

15:30 * hoeck1 votes for implicit "this" (in deftype)

15:31 rhickey_: jlilly: I want to stop having to write/maintain Java, especially when trying to enhance Clojure. Also ports will be greatly facilitated by having the bulk of the compiler and data structures written in Clojure

15:32 mwoelker: yes, something that looks at jars

15:32 jlilly: rhickey_: I suppose it doens't introduce performance concerns b/c its compiled.

15:32 rhickey_: jlilly: the exercise has also highlighted a missing piece of Clojure - it is built on abstractions but doesn't provide a mechanism for defining same other than Java's

15:33 so it is driving this protocols/datatypes design, which will be a great enhancement to Clojure

15:33 drewr: rhickey_: wouldn't I still have a hard time writing clojure in C because the interop is so Java-centric?

15:33 jlilly: my previous experience (mostly just hearing of it) was w/ the python & ruby communities. I guess they face a different set of problems w/r/t being dynamic.

15:33 drewr: or maybe implementing the language would be feasible, but using it would be quite a different experience

15:34 rhickey_: drewr: the design presumes some object system a la Java/CLR but JavaScript and Obj-C are also doable

15:34 making it easy to port to C is a non-objective

15:34 C being bereft of facilities

15:34 drewr: ok, so C was a bad example

15:35 wouldn't the interop on obj-c make it a very different language?

15:35 cemerick: drewr: chicken scheme could probably get you to a native executable

15:35 rhickey_: it really requires very little, and deftype/protocols make it clear how little

15:35 cemerick: native + cross platform, that is

15:35 drewr: as a trivial example, clojure would need to provide a wrapper around .toUpperCase, right?

15:36 not that it wouldn't be nice to have a clojure string lib

15:36 rhickey_: drewr: there would be things like that, and I imagine we'll go through to encapsulate some of that. But writing portable apps is also a non-objective

15:37 the whole point of moving to a different host is to leverage that host

15:37 wrapping all hosts defeats a purpose of Clojure

15:37 so some core facilities and libs will port, other than that each app should/will touch the platform directly

15:38 drewr: makes sense

15:38 rhickey_: but say a consultant wouldn't have to switch language to move to different client targets

15:39 hiredman: dmiller is looking at porting contrib to clojureclr

15:39 which will face a lot of .toUpperCase kind of stuff

15:40 http://www.thelastcitadel.com/images/contrib.svg

15:46 rhickey_: hiredman: comparable facilities are definitely there (especially on CLR) so it's just a matter of encapsulation

15:46 hiredman: sure

15:47 mwoelker: rhickey_: Another issue that was recently raised on the ML was joint compilation with Java or other JVM languages. Without going into to much detail, what's clojure story for that topic?

15:47 rhickey_: he end result will be core + a substantial portion of contrib will be portable

15:48 mwoelker: that's a hard problem - essentially you have to start compiling Java. I'm hoping maybe some frameworks will fall out of the IDEs which do that.

15:48 hiredman: headius there was talk of a "super compiler" at the jvm lang summit

15:48 said

15:48 rhickey_: right, there was talk of that, but it may be hard to generalize

15:49 especially to any combination of langs

15:50 hiredman: :/

15:51 mwoelker: what about the two pass stub compilation approach, just assume all symbols/classes/methods can be resolved in the first pass and generate appropriate class skeletons, and on the second pass (when all other class skeletons are there) do the actual semantic analysis?

15:52 hiredman: I know Chousuke was/is running to issues with bootstrapping his cinc reader into clojure

15:52 (I ran into some too when I was messing with it)

15:53 but metacicularity makes my head hurt

15:53 rhickey_: mwoelker: as I said, it means moving away from reflection as the means to determine class facilities, What the replacement is is an open question - ASM won't help you until you have class files, doing a prep-pass requires static analysis which is possible for Java but much less so for Clojure, where macros can hide anything

15:54 there are disciplined ways to ease the pain, rigorous use of interfaces, splitting gen-interfaces into their own files etc

15:55 mwoelker: rhickey_: as a newcomer to lisps, I guess I still haven't quite wrapped my head around how powerful macros really are...

15:55 rhickey_: but the general case is unsolveable as (gen-framework foo) could read a database and expand into anything

15:55 cemerick: wow, contrib is up to 3.2MB, compiled :-|

15:58 mwoelker: rhickey_: Well, the macro could still create the appropriate skeletons on the first pass, and the actual method bodies on a second pass. One would have to hope that the DB isn't messed with in the meantime...

15:59 hiredman: there is a lot in contrib

16:01 rhickey_: mwoelker: that's not the way a Lisp works.

16:02 cemerick: indeed. The diagram you linked to earlier is a little staggering. Has anyone put together a linker yet? (for lack of a better term)

16:02 stuartsierra: rhickey_: And I've written some gen-framework's :)

16:02 hiredman: cemerick: package manager?

16:02 mwoelker: rhickey_: I feared as much. So what else is there? Iterative compilation until a fixed point is reached?

16:03 cemerick: hiredman: no -- given a top-level, determine ns dependencies, and only package those into the jar, etc.

16:03 hiredman: oh

16:04 cemerick: mwoelker: are you knocking up against layered language dependencies?

16:04 rhickey_: mwoelker: it's a tradeoff of a Lisp that the dynamism hurts static analysis, but you can't superimpose a compilation model - there's one built in and it involves running arbitrary user code

16:06 it may be the case that you only need to statically analyze one half (the Java bit)

16:06 that would ensure Clojure compilation could proceed

16:06 technomancy: why does defn support metadata maps in two positions? (before the name vs after the body)

16:06 rhickey_: then patch and finish Java compilation

16:07 technomancy: before the name doesn't have anything to do with the syntax of defn, that's just adorning the name

16:07 mwoelker: rhickey_: Coming from a more "static" background, I am just afraid this lack of joint compilation might hinder wider acceptance and adoption

16:07 technomancy: oh, right that's a read-time thing.

16:08 rhickey_: mwoelker: quite a bit of useful things can be built without circularity

16:08 mwoelker: rhickey_: well it wouldn't even have to be circular, just lots of layers of clojure/java/... code

16:09 cemerick: mwoelker: it's pretty rare for joint compilation to be a hard requirement. The workarounds are generally very straightforward.

16:10 mwoelker: cemerick: so the solution would be to partition code into subprojects (written in only one language) and have the build tool figure out the right compilation order based on the dependency analysis?

16:11 cemerick: mwoelker: I can't imagine bothering to get so fancy. You've got some existing libs, presumably written in java. Make a new project that depends on those libs, written in clojure. Given the existing interop features of clojure, that handles 90% of the use cases.

16:12 Beyond that, you can use gen-class to wrap clojure libs so that they look just like Java from Java or other JVM langs. Package that up into a jar, and you've got Just Another Java Dependency.

16:12 mwoelker: That sounds like a good plan, I guess the case I was worried about was porting applications bit by bit (or even only just replace Java code with clojure in certain places), think polyglot programming, but I have to admit that may be quite an edge case

16:13 rhickey_: mwoelker: but that code, if properly written, will have interfaces defined on the Java side. It will be able to call Clojure code that implements those interfaces without a compilation dependency

16:13 cemerick: All of our projects are hyrid, about a 95/5 clojure/java mix. If the dependencies go in the right direction and you just set up the clojure compilation to happen after the java compilation, you're golden.

16:14 hybrid*

16:16 mwoelker: Okay, that should work. Thanks a lot for your insights and the discussion (and last not least patience). It is much appreciated.

16:16 chouser: We have java, C++, clojure, python, jruby, and protobuf code with interdependencies. It isn't pretty, but each component knows how to build itself and declares its dependencies to be built first. Hasn't been much of a problem.

16:17 this is all using cmake which I would not, by the way, recommend. At all.

16:17 mwoelker: chouser: wow that sounds like a boatload of fun

16:18 chouser: heh. yeah.

16:18 rhickey_: so, no consensus on these: ? http://paste.lisp.org/display/88999

16:18 mwoelker: chouser: heh I was just about to ask what you were using, just in case I ever got into unenviable position to working with such a mixture...

16:18 chouser: I don't think we have any C++ that depends on anything JVM, or anything that depends on the python or jruby.

16:19 cemerick: chouser: Ouch. Like, ouch. :-/

16:19 chouser: but all the rest is pretty mixed up -- jruby that needs java that needs clojure that needs more java and c++

16:19 hiredman: really, I liked datatypes as just containers with no attached methods

16:19 rhickey_: hiredman: the methods are only if you need to implement interfaces - you can't define any other methods

16:19 cemerick: hiredman: I think the method impls are totally optional, right rhickey_ ?

16:20 rhickey_: cemerick: right

16:20 cemerick: I prefer #3, with the type hinting done automagically.

16:20 rhickey_: strictly for interfaces, equals/hashCode customization, which must be in class

16:20 mwoelker: rhickey_: FWIW I prefer the "autohinted this" version

16:21 chouser: I guess I have a slight preference for autohinted explicit this.

16:22 I can see an eval'd map being handy at times (to avoid otherwise potentially messy macros) but not sure if it's worth supporting both.

16:22 rhickey_: geez, you guys have been doing FP for too long :)

16:22 hiredman: sounds like a quorum

16:23 rhickey_: think about the poor folks coming from Java, never had to declare this before...

16:23 * hiredman is on the simon jones interview in coders at work

16:23 mwoelker: that would be me I guess

16:23 cemerick: doesn't ruby have explicit this?

16:23 obviously, python does, and people manage

16:23 chouser: python does

16:23 yeah

16:24 wtetzner: is there a way to give type hints in code that's generated by macros?

16:24 hiredman: well, if python does it, lets do the opposite

16:24 cemerick: I'm surprised there's no into!

16:24 (yet)

16:24 rhickey_: ut this is a bridge/interop thing where the interfaces are declared in Java as taking x, not this,x

16:24 but

16:25 cemerick: of course, that's just so much sugar :-)

16:25 rhickey_: into! ?

16:25 Chousuke: hoh

16:25 Kjellski: Hi there =)

16:25 Chousuke: now I got the size reduced

16:26 turns out duplicating every object with line metadata added was kind of... bloating the whole thing

16:26 however now I have another error :P

16:27 it's not finding the ClojureReader.read() method, and disassembly of the classfile shows a clojure.core$read__1264@32486cdd(java.io.PushbackReader, java.lang.Object);

16:27 and... what? :|

16:28 rhickey_: how about - if you don't supply this, and call it 'this', then the macro will supply it?

16:28 user preference

16:29 mwoelker: might make it harder to read other people's code...

16:29 cemerick: just think of the poor fellow who calls the first argument 'me', but binds 'this' to something else in the impl

16:29 rhickey_: sure, something like (defn into! [tc coll] (reduce conj! tc coll)))

16:30 rhickey_: cemerick: oh, for transients, but into uses a transient inside already

16:30 lpetit: I think I also slightly prefer "deftype with interface explicit this".

16:31 cgrand: rhickey_: how do you know that this is missing when methods are overloaded?

16:31 and I prefer explicit auto-hinted this (no surprise)

16:31 lpetit: "explicit auto-hinted first arg"

16:32 yes really, KISS

16:32 is it me saying that ? :-)

16:33 hiredman: Chousuke: how did you end up getting around the load being undefined thing

16:33 rhickey_: cgrand: overloaded by arity will have this in each sig

16:34 cemerick: rhickey_: oh, I see what's going on. I guess I'll just have to internalize that persistent! and transient are O(1)?

16:35 rhickey_: cemerick: yes, that's the beautiful thing

16:36 hiredman: lisppaste8: url

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

16:38 hiredman pasted "incremental reader replacement" at http://paste.lisp.org/display/89006

16:39 hiredman: so then once a clojure implementation of StringReader was read in and compiled, clojure.core/STRING-READER could be redef'ed to the clojure version

16:43 * danlei converts to autohinted explicit this, after thinking about it

16:44 chouser: I think I dislike the optional "this" more than I dislike the implicit "this"

16:44 danlei: yes, I don't like that either

16:45 a bit too much magic for my taste

16:45 chouser: I'm trying to remember how many confused comments I hear from people forgetting 'this' in gen-class fns vs. people asking how to get at 'this' in proxy.

16:46 There have been a few of each -- I don't think overwhelming either way.

16:46 lpetit: having explicit arguments everywhere would seem more FPy and consistent with the rest.

16:47 hiredman: gen-class's case is more frustrating because by the time you get to that point with gen-class you have been suffering for a long time

16:47 chouser: hiredman: heh. yeah.

16:47 lisppaste8: rhickey annotated #88999 "deftype explicit this, leaner, cleaner?" at http://paste.lisp.org/display/88999#3

16:48 hiredman: looks like new new

16:49 rhickey_: with this, a simple struct-like thing can just be (deftype my.Struct a b c)

16:49 danlei: getting rid of one nesting level ready more clojury for me, at first impression

16:49 s/ready/reads

16:50 chouser: require all fields before any methods?

16:50 danlei: I like it

16:51 rhickey_: chouser: dunno, the way this works it's keying of symbol/seq/key, could be intermixed

16:51 It present extensibility issues, but the key is an escape hatch for more verbose things

16:51 hiredman: I know protocols vs. multimethods was hashed over a lot yesterday, what bout deftype vs. new new

16:52 technomancy: ,((fn [& args] args))

16:52 clojurebot: nil

16:52 technomancy: shouldn't that be an empty seq?

16:52 hiredman: ,(empty? nikl)

16:52 clojurebot: java.lang.Exception: Unable to resolve symbol: nikl in this context

16:52 hiredman: ,(empty? nil)

16:52 clojurebot: true

16:52 chouser: technomancy: & is next, not rest

16:52 technomancy: hiredman: smells like CL to me. =)

16:53 rhickey_: hiredman: imagine new new becomes a better proxy, access to supers, protected etc, and faster

16:53 technomancy: I guess I'm just not used to being able to use nil in seq-ish contexts

16:53 chouser: ,[(first nil) (rest nil) (next nil) (filter true? nil) (map inc nil)]

16:53 clojurebot: [nil () nil () ()]

16:54 rhickey_: I'd very much like to avoid the verbosity of gen-class with deftype

16:54 hiredman: so new new would have the verbosity of gen-class?

16:54 rhickey_: hiredman: not related

16:54 hiredman: hmmm

16:54 rhickey_: I was referring back to leaner/cleaner

16:54 chouser: rhickey_: I guess you expect :implements to be less common than an empty [] for interfaces?

16:55 rhickey_: chouser: I guess

16:55 chouser: hm, nm. Even if more common I think I like the explicitness

16:55 rhickey_: of coure then implementing a protocol should get a different name

16:55 course

16:56 chouser: considering when used in pure native clojure code, you won't need interfaces -- protocols go on top of deftype, not the other way around.

16:56 lpetit: rhickey: just to understand the limits of your example in lisppaste : what is provided as an example is the expansion of what would be done automatically by deftype if no equals / hashCode was provided (I mean, the example seems to do something very generic)

16:56 rhickey_: chouser: right

16:56 chouser: so yes, I think leaner explicit this is the best yet

16:57 liebke: rhickey_: I like the explicitness of :implements, but my code uses keywords everywhere, so I'm biased :)

16:57 chouser: It would be nice if field names were less obscured by their metadata, but I don't know what to do about that.

16:57 rhickey_: lpetit: I'm still thinking about auto-generated equals and hashCode, but yes, I'd like to avoid having people need to define the obvious right thing for an immutable datum

16:58 cemerick: rhickey_: it would be nice to be able to say (-> [] transient some-fn other-fn (into (get-data)) last-fn persistent!), etc.

16:58 make that into!, of course

16:59 rhickey_: cemerick: I'm not opposed

17:00 cemerick: OK, I'll tinker some more and see if it's really warranted. I'll file a ticket w/ patch based on that.

17:02 rhickey_: chouser: yes, we'd talked here about ethel^int in the past, post deprecating ^

17:03 actually that wouldn't have to wait, presuming no one depends upon ^ being non-constituent

17:04 danlei: rhickey_: if something is a field or method implementation would be decided by whether it's a symbol vs. seq in leaner deftype, right?

17:04 rhickey_: danlei: yes

17:05 trailing symbol meta?? name^{:tag String :alias :foaf:name}

17:05 ethel^int, foo^String

17:06 liebke: I like the trailing metadata, it's seems clearer to me

17:07 lpetit: rhickey: about predefined equals function, could equals (and to some extend participation to hashCode, though I'm not sure if feasible) semantics of fields be placed closer to the fields (in the metadata for the field) if field needs special treatment (e.g. not being considered ?? , being treated as equal by identity, or using a particular function / code snippet) ?

17:08 yes, first introducing the thing, then the metadata to the thing, sounds good

17:08 chouser: leaner explicit this combined with trailing symbol meta would look quite nice indeed.

17:09 all the member names would line up along the left, starting with a paren for methods.

17:09 rhickey_: lpetit: I don't know if the added complexity will be worth specifying that, if the default is good and you can define your own equals easily. Certainly per-field code is out, just ignore/identity/equality flags

17:11 lisppaste8: rhickey annotated #88999 "deftype explicit this, leaner, meta trailing" at http://paste.lisp.org/display/88999#4

17:11 danlei: how about allowing symbols and lists as fields, like this (deftype foo [bar int] ...)?

17:11 s/list/vector

17:11 lpetit: rhickey_: thought about this because I guess except for rare cases, equals will really still be boilerplate, once you define ignore/identity/equality flags. And it's so easy to add a flag and forget to update the equality function.

17:11 to add an attribute, I meant

17:12 rhickey_: danlei: metadata on symbols has a lot of advantages for flowing through macros, and is used everywhere else

17:12 chouser: a bit OT, but evaluation order of things in {} and #{} are undefined, right?

17:13 rhickey_: chouser: probably unspecified

17:13 lpetit: it's interesting

17:15 lpetit: rhickey_: I have no idea if there's something to do concerning the hashCode computation story, though, except that this ignore/identity/equality flag could also serve the default hashCode algorithm !

17:18 hiredman: are def'ed types going to implement one of the meta interfaces by default?

17:18 er

17:18 datatypes

17:18 rhickey_: lpetit: if the default is per-field =, the biggest overrides will be :ignore, something to say :array=, and :identity for objects with broken equals

17:19 hiredman: yes, will get auto meta and with-meta support

17:21 lpetit: rhickey_: yes. And the hashCode default algorithm will be able to altogether ignore the field if :ignore, use object identity in some way if :identity. As for :array=, I dunno

17:21 rhickey_: lpetit: I think it could work, and could inform both equals and hashCode - good idea!

17:22 lpetit: rhickey_: and that would be appreciated even from start from the java guy coming to clojure, which surely will be bored to have to define equals/hashCode pairs (or not to and live with buggy code :) )

17:22 rhickey_: there's System/identityHashCode

17:23 arrays are tricky, since you might need to further specify for their contents...

17:24 lpetit: rhickey: yes, I see java.utils.Array has hashCode functions for arrays of primitive types, and a deepHashcode for arrays of Object types

17:25 rhickey_: ^{:equals :identity|:ignore|[]}, with [] possibly containing nested spec?

17:26 I guess you'd never have nested :ignore, and nested :identity might be rare as well

17:26 so many broken equals in the world though

17:27 lpetit: rhickey_: but for arrays the problem seems to still be symmetric for equals and hashCode in java.utils.Arrays : deepHashcode()/deepEquals(), hashCode()/equals()

17:27 rhickey_: could have nested arrays

17:27 lpetit: right, but we have overrides and will need them for array contents too

17:28 lpetit: rhickey_: "we have overrides" ? I'm not following you here

17:29 rhickey_: lpetit: if you would want to say :identity for a field you might also want to say it fr members of an array field

17:29 serp_: java supports method overloading where the arguments determine what method to call... does clojure?

17:29 rhickey_: deep* hardwire defaults

17:30 serp_: Clojure has multimethods for such overloading

17:30 serp_: I see

17:30 rhickey_: serp_: but not type overloading within fn

17:30 hiredman: ~multimethods

17:30 clojurebot: multimethods is what separates the boys from the men.

17:30 rhickey_: generally considered evil

17:30 hiredman: clojurebot: cute, but not useful

17:30 clojurebot: Titim gan éirí ort.

17:30 rhickey_: (type overloading)

17:31 certainly an interop mightmare

17:31 nightmare

17:31 serp_: I don't know what multimethods are =(

17:32 hiredman: http://clojure.org/multimethods

17:33 serp_: hiredman: thx

17:36 lpetit: rhickey_: ^{:equals :identity|:ignore|[]} with [] only relevant for arrays I guess (not a way to a la carte redefine equality semantics of arbitrary datatypes ;-) ? )

17:37 rhickey_: lpetit: right [] for arrays, useful in that it can contain another [] or :identity

17:39 lpetit: rhickey_: ok. sounds good. Not difficult to read, not too difficult to remember. The :equals name, maybe, implies too much that it solely concerns equality (and not hashCode), though it will affect the behaviour of the default hashCode method. But I don't have anything better to offer yet

17:40 rhickey_: defaulting to deepEquals for arrays would be a break with = for arrays, which right now is identity as is anyarray.equals

17:40 but I want deftype to be "right" for immutable by default, so maybe could do deepEquals for arrays

17:41 lpetit: rhickey_: java.utils.Arrays has both Arrays.equals() and Arrays.deepEquals(), even for Object[]

17:41 rhickey_: I agree about equals/hash, but they are supposed to agree

17:42 lpetit: rhickey_: yes, forget, :equals does the job well

17:43 rhickey_: lpetit: deep just handles nesting, which you would want

17:43 if the default was deepEquals for arrays, I think we could just do with :ignore and :identity

17:44 lpetit: rhickey_ : but wouldn't it be a problem for people wanting arrays for performance ? I can imagine by default in clojure people will not use arrays at all, except for performance => and then maybe what they want for hash is a quick System.identityHashCode call

17:44 rhickey_: lpetit: then they will flag the array field with :identity

17:45 lpetit: rhickey_ : oh yes you're right :)

17:47 rhickey_: there's still the Arrays.equals(Object[]) versus Arrays.deepEquals(Object[]). The former is said to be identical to Arrays.asList(Object[]).equals(). Is this worth the trouble having array equality have Arrays.equals(Object[]) by default and a :deep key for Arrays.deepEquals() ? (or the other way around ?)

17:48 rhickey_: lpetit: no, they differ only for nested AFAICT, and I can't see equals for nested

17:49 you wouldn't be able to reach into any Clojure composite like that either

17:49 lpetit: rhickey_: Arrays.deepEquals(Object[])

17:50 rhickey_: ok I've reached my incompetence level here, but I think we've almost closed the deal, haven't we ? :)

17:51 rhickey_: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#deepEquals(java.lang.Object[],%20java.lang.Object[])

17:52 only differs from Arrays.equals in the nested case, and then, without deep, would compare nested arrays by identity. I don't see the use case, and it wouldn't be possible to distinguish similarly nested Clojure data structures, they always do deep

17:54 lpetit: rhickey_: ok so deepEquals by default, and as far as I'm concerned, the deal is close :) (and that's an opportunity for me to go to bed :) )

17:55 Chousuke: *sigh*

17:55 rhickey_: lpetit: thanks for the input!

17:55 lpetit: Chousuke : grmlml :)

17:56 Chousuke: I'm this -><- close to succeeding in bootstrapping my reader but I hit yet another roadblock with the (load "core_foo") thingies in core.clj

17:56 I can't convince Clojure to recompile them even though they're already loaded :/

17:58 hiredman: :(

17:58 div: rhickey_: I assume that any :equals annotations would be overridden when an actual equals implementation is provided ?

17:58 Chousuke: and as a result the final .jar file won't have the .class files so it won't start because it tries to load the script files using the reader which requires core.clj which require the core_foo thingies...

17:58 hiredman: I have the urge to go home and traipse through src/clojure/lang for the rest of the day

18:00 Chousuke: I think I will need to rip open RT.java and add some kind of a "recompile" function to it.

18:00 rhickey_: div: yes, just ignored

18:00 div: ok, makes sense

18:00 hiredman: Chousuke: have you, uh, touch'ed the files you want to recompile?

18:01 http://ant.apache.org/manual/CoreTasks/touch.html

18:01 lpetit: div: so that IDE devs can add a layer of warnings not provided by the compiler :-p

18:02 div: lpetit: yes, a simple warning can go a long way :)

18:02 lpetit: I hope ccw was so advanced that I could start doing such added value stuff. Alas ...

18:03 Chousuke: hiredman: I can't do that, since then it won't load the class files before trying to recompile them :P

18:03 hiredman: hmmmmmm

18:04 Chousuke: hiredman: what I want it to do is, load clojure.core and clojure.lang.reader from .class files generated by the bootstrap process, then recompile everything using the new reader

18:05 but the thing is, it won't recompile clojure.core or clojure.lang.reader because they're already loaded :P

18:06 and if I override that check, it'll *always* recompile all the dependencies... and my head hurts

18:08 hiredman: nice

18:09 Chousuke: oh, and there's more.

18:10 I can't use gen-class to generate a hook for the java side to the reader because if I then during the second stage try to recompile the genclass'd namespace, it'll generate garbage because an existing class of the same name is already loaded (presumably to avoid collisions)

18:10 Licenser: hmm hmm, I

18:11 I've alist like (([1 2] [1 2]) ([1 2] [1 2])) how can I 'flatten' that?

18:11 hiredman: ,(doc flatten)

18:11 clojurebot: "clojure.contrib.seq-utils/flatten;[[x]]; Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."

18:12 Licenser: that is too easy darn

18:15 travisbrady: Does anyone have thoughts on what concerns would govern the decision to learn Clojure over Scala or vice versa?

18:16 Chousuke: syntax. :)

18:16 somnium: ~scala

18:17 hiredman: ~tell me about scala

18:17 clojurebot: {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

18:18 hiredman: ~scala {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

18:18 clojurebot: Any = 1

18:28 rhickey_: updated to reflect today's discussion: http://www.assembla.com/wiki/show/clojure/Datatypes

18:28 need a new name for implement in protocols?

18:31 Licenser: I've another silly question, I've a function that expects a argument and n vectors (like (fun 1 [1 2] [3 4]...)) now I have those vectors in a list so '([1 2] [3 4]) but passing them that way isn't really liked by the function, how the heck do I pass the function the parameters o.O

18:31 I

18:32 I'm sure there is some super easy and cool way to do that which I don't know about

18:32 Chousuke: apply

18:32 liebke: Licenser: (apply fun '([1 2] [3 4]))

18:32 Licenser: you are my heros!

18:33 thank you a lot

18:33 travisbrady: hiredman: haha, ok, fair enough. I'm thinking more like "Clojure is really good at X" types of things

18:34 but thank you still, i agree Scala syntax can be really ugly

18:34 danlei: rhickey_: what does the "under any name?" wrt this mean? whether other designators may be chosen?

18:36 technomancy: travisbrady: you're unlikely to get an unbiased answer in here, but the fact that imperative code can be idiomatic in Scala but not in Clojure is the biggest thing from my perspective.

18:36 travisbrady: technomancy: ahh, that's helpful actually.

18:37 I've never used a lisp previously, so I'm leaning toward Clojure

18:37 technomancy: travisbrady: also keep in mind that you can read the entire implementation of Clojure in a day or two.

18:37 danlei: travisbrady: I don't know anything about scale, but are data = code and vice versa? if not, I'd consider it a drawback.

18:37 ambient: this is a bit weird: "no matching method found: aset" inside (defn daset [a vals] (doseq [[i j] (partition 2 vals)] (aset #^doubles a i j)))

18:42 danlei: travisbrady: to be more precise: in lisps, the code is made up from s-exprs, lists, and all built-in functionality of the language can be used to operate on that easily

18:43 travisbrady: wow, read all of Clojure's source in two days. cool. Scala is a shorter path in some senses for me since it let's you write really straight up imperative code

18:44 is there anything like sbt for clojure to simplify building and such?

18:44 danlei: you could also write imperative code very well with common-lisp

18:44 and with abcl even on the jvm

18:45 if you *want* to write imperative code, of course

18:46 Chousuke: technomancy: entire implementation excluding the icky java parts, right? :P

18:47 cgrand: ambient: you must fully hint aset

18:47 hiredman: of course

18:47 cgrand: ambient: (aset #^doubles a (int i) (double j))

18:47 hiredman: I don't think the java parts are that horrible

18:47 ambient: cgrand sorry, i just figured out i was giving the function wrong parameters

18:48 technomancy: Chousuke: if you leave out Java it's hours, not days. =)

18:48 Chousuke: hiredman: it's not horrible, for java code :P

18:51 hiredman: it's kind of intimidating, but once you start fitzing with it, it starts to look like clojure code with a lot of noise

18:52 Chousuke: LispReader is a good example

18:52 hiredman: yeah, all those AFns

18:53 Chousuke: it's got the same basic idea as my clojure reader... only, it's in java and mine is in clojure :P

18:53 licoresse: is someone working on proper error output from clojure compile messages?

18:53 (slime)

18:53 Chousuke: probably not.

18:53 licoresse: hm

18:53 technomancy: someone was talking about hooking it into the rubinius-style backtrace lib

18:54 Chousuke: I don't think anyone wants to work on the compiler too much at this point.

18:54 because it'll eventually get redone anyway

18:54 licoresse: any thoughts on how?

18:54 Chousuke: some simple things could be done though

18:55 for example, the no matching method errors should print the expected parameter types too :P

18:56 hiredman: the tapestry guy (hslip?) hade some kind of clojure stacktrace thing

18:56 http://tapestryjava.blogspot.com/2009/10/cascade-exception-reporting.html

18:57 hlship

19:04 somnium: it looks like a slime stacktrace with css

19:05 * hiredman doesn't use slime

19:05 hiredman: I assumed you where complaining about the pages of java exceptions

19:07 somnium: ah, the second picture is nice, slime doesn't do that yet (obfuscate the java internals)

19:07 technomancy: it does dim them though

19:13 rhickey_: danlei: yes, arbitrary name for this

19:15 danlei: rhickey_: well, when using explicit this, why would one not allow arbitrary designators?

19:16 rhickey_: danlei: right, just wanted to be clear you have to add an arg for 'this', whatever you call it

19:16 danlei: rhickey_: ok, thanks (just wasn't clear to me)

19:17 rhickey_: danlei: well, it might not yet be clear :) those are just notes, not docs

19:17 danlei: rhickey_: yeah, I'm aware of that :)

19:18 it was just the formulation which confused me

19:30 mikehinchey: I submitted a patch to clojure.stacktrace to get it closer to clj syntax

19:32 peregrine81: Hey all I am doing eulers project again and I

19:32 technomancy: one of these days I'm going to go through the submitted patches, try them out, and +1 the ones that look good

19:32 peregrine81: m trying to find the Least Common demonator for 1-20. and it seemingly runs forever.. here is the gist

19:32 http://gist.github.com/214717

19:32 technomancy: since it sounds more productive than complaining that my patches take too long to get applied. =)

19:33 danlei: :)

19:33 peregrine81: I had a really elegant solution with regular recursion but kept getting stack overflows

19:36 mikehinchey: technomancy: that might be good. I'd like to know where I could put some time in to clojure, because my submissions haven't moved in as I expected.

19:37 technomancy: mikehinchey: I'll vote for your patches if you vote for mine. =)

19:38 I think it's more about just QAing them so when rich does get to them the problematic ones are already sorted out.

19:44 The-Kenny: peregrine81: It's possible to increment the stack-size of the jvm if you start it.... but I'm not sure if that will help.

19:44 mikehinchey: technomancy: yes, I might create a branch with a bunch of patches to make sure they apply cleanly and tests pass

19:44 technomancy: even patches that were once good can succumb to bitrot.

19:44 peregrine81: The-Kenny: this solution runs without stack issues, but it just never finds an answer

19:46 tomoj: your current solution doesn't make any sense at all to me

19:46 mikehinchey: exactly

19:49 peregrine81: tomoj: why not?

19:49 oops sorry I will be back in 20

20:07 peregrin181: alright I am back

20:10 alright so to catch everyone up I have this code to calculate the least common denominator of 1-20 and it runs forever and I don't know why. Here is the code: http://gist.github.com/214717

20:13 I know the LCD of 1-10 is 5250 so I don't need to find the LCD for numbers below 5250 nor the numbers 1-10

20:15 danlei: without any mathematical knowledge on my side, I'd write something like this:

20:15 (which might be spoilery)

20:15 (defn find-divisible [r]

20:15 (first (drop-while (fn [n] (not (every? #(zero? (rem n %)) r))) (iterate inc 1))))

20:16 tomoj: that's probably very slow

20:16 danlei: well possible, yes

20:16 but how fast must it be?

20:16 it solves the task fine

20:16 tomoj: oh, euler doesn't care

20:17 danlei: "Elapsed time: 128.06173 msecs"

20:17 not fastest, but fast enough for my neurons .)

20:17 tomoj: much faster than I thought

20:17 danlei: 1-10

20:18 should explode

20:19 tomoj: ah, yes, 1-20 is not so fast :)

20:19 danlei: yes, I'm waiting :D

20:19 tomoj: I think when I did that one I prime-factorized

20:20 i.e. factor each of 1-20 into a map of primes->multiplicities, and then merge with max, and then multiply the result up

20:27 peregrin181: tomoj: I'm sorry I don't understand

20:28 tomoj: I will need to study this closer

20:28 tomoj: wait, I think what I described was something else

20:28 peregrin181: tomoj: Why doesn't mine work?

20:28 tomoj: no, no it wasn't

20:28 I still have no idea what your code is trying to do, sorry :(

20:29 I mean I know what it's trying to do, but I have no idea how it's trying to do it

20:29 peregrin181: I start at 2520(cause I know 1-10 is 2520) and check numbers 11-20 to see if they have a remainder of 0

20:30 tomoj: ah, I see

20:30 yes, this takes a very long time because it's a big number, I think

20:30 danlei: combinatorical explosion, just like my snippet

20:30 tomoj: 1-10 is easy so you haven't saved much work

20:30 peregrin181: danlei: I mean I don't understand yours :)

20:31 danlei: peregrin181: what exactly don't you understand?

20:31 peregrin181: danlei: Any of it. I am very green in the world of Clojure/lisps

20:31 danlei: peregrin181: I'll explain, but it's slow, as tomoj said

20:32 peregrin181: danlei: other then anonymous function and functions

20:32 danlei: (defn find-divisible [r]

20:32 (first (drop-while (fn [n] (not (every? #(zero? (rem n %)) r))) (iterate inc 1))))

20:32 start from the every?

20:32 every? returns true if a given predicate holds for all elements of a seq

20:33 so the every? will return true, if all (rem n %) are true for the values in r, which is a range

20:33 (the range ist the argument to find-divisible)

20:33 peregrin181: so [1-20]

20:34 danlei: drop while drops everything while a predicate is true

20:34 you get the picture?

20:34 peregrin181: what is the iterate inc 1

20:34 danlei: yes, (range 1 21)

20:34 its all numbers starting from 1

20:34 also a range, but an open interval

20:35 peregrin181: so it returns to the top

20:35 danlei: so it drops all of those numbers (of the open interval)

20:35 and the first just picks the first available, which will be your result

20:36 drops all for which the (fn [n] ... is true

20:36 peregrin181: thank you. I am still not 100% clear but I think I get it

20:36 the #( means anonymous fn correct?

20:36 danlei: I'm not good at explaining :)

20:36 yes, its sugar for fn, binds % and stuff implicitly

20:37 and to show you how slow it really is:

20:37 "Elapsed time: 985956.807695 msecs"

20:37 :)

20:38 peregrin181: still faster than running forever

20:38 danlei: btw. theres also not-every?

20:39 yes it does the job, eventually ;)

20:39 peregrin181: danlei thanks

20:39 danlei: but it's a very naive approach

20:39 you're welcome

20:40 peregrin181: far less naive then mine

20:40 I'm trying to code in C#/Java in Clojure

20:41 danlei: well, I don't know any C# and almost no Java, so I have it a bit easier ;)

20:41 peregrin181: danlei: did you learn in lisp?

20:41 danlei: yes, I use it almost exclusively, which I can do, because I'm not a professional programmer. I just do stuff I like, and I tend to like lisps

20:42 peregrin181: danlei: cool

20:42 danlei: atm, I'm at university (despite of my age), and that will change soon, but well ...

20:42 peregrin181: why do you think my code takes so long?

20:42 danlei: the good thing is: my university is pretty lisp-friendly :)

20:43 and I don't study cs but computational linguitics, but that's another topic

20:43 peregrin181: I did nearly the same thing you did(with loops)

20:43 danlei: I really didn't understand how you approached it, I didn't spend much time reading your code, to be honest

20:44 a general tip is: always check if it simplifies and terminates

20:45 (i.e.: if your base-case is ever reached)

20:46 tomoj: ok, my prime-factorizing version can do 1-20 in 5ms :)

20:46 danlei: :p

20:46 tomoj: and my factoring algorithm is really dumb

20:46 danlei: I just waited for it, tomoj ;)

20:47 tomoj: how long did it take?

20:47 also, cool re compling, I'm taking an intro compling class now

20:47 I really want to rewrite nltk in clojure because python makes me sad

20:48 danlei: "Elapsed time: 985956.807695 msecs" :)

20:49 I'm just at the start right now, much "traditional" linguistics atm, the basics

20:49 desaussure &al

20:50 tomoj: here's my version (spoiler, of course): http://gist.github.com/214752

20:50 danlei: *de saussure

20:53 tomoj: so the answer is in the hundreds of millions, I can see why the naive way takes so long

20:54 peregrin181: tomoj: my way

20:54 ?

20:56 tomoj: the way that counts upwards and checks for each number whether all the numbers in the list divide it

20:56 all the hard work of my way is prime-factorizing, and though my factorizer seems slow, you only have to factor 2-20, so

20:57 I wonder how long the naive way takes to get 1-30

20:58 or 1-300 :)

20:58 peregrin181: tomoj: mine prolly takes forever

20:59 danlei: would sure be a workout for my fan :)

20:59 tomoj: I can get 1-300 in just over a second

20:59 peregrin181: tomoj: Yea the way of finding the roots is far better

21:00 tomoj: it disturbs me that I don't know how to factor quickly

21:02 danlei: tomoj: do you speak common lisp?

21:03 peregrin181: tomoj: I'm not very good at math

21:03 lol

21:04 tomoj: danlei: a little, not much

21:04 danlei: I haven't done euler for a long time

21:04 but I have alittle factorizer here

21:04 sec

21:05 lisppaste8: danlei pasted "factorization" at http://paste.lisp.org/display/89018

21:06 danlei: it's not stuff I usually do much, but it worked and was fast enough for my needs

21:06 peregrin181: is this cl?

21:06 miltonsilva: hi, does anyone know(has experience) how clojure scale to huge project? (specificly the ones that seem more OO)

21:06 danlei: yes

21:06 I started doing euler in CL, havent come around to do some of it in clojure

21:07 peregrin181: danlei: I wasn't a fan of CL

21:08 danlei: I like it pretty much :)

21:08 clojure, too. I like both of them

21:08 what didn't you like?

21:08 somnium: weblocks is cool

21:08 danlei: never used it, just hunchentoot

21:08 but I heard good things about it

21:08 somnium: I just don't want to try to learn another lisp until I feel like I'm really familiar with all of clojure's dark corners

21:08 peregrin181: danlei: CL seemed poorly documented, too many different implementations, little tool support(outside of emacs)

21:09 danlei: poor libs

21:09 danlei: peregrin181: oh. I'd /very/ strongly disagree about poorly documented

21:09 somnium: and all the 'serious' implementations cost a fortune

21:09 peregrin181: danlei: thats probably true

21:09 somnium: for a hobby programmer anyway, they're supposed to have better libs though

21:10 danlei: well the thing is, cffi is there and it's pretty easy to use

21:10 it's like clojure uses java as it's low-level and implementation language

21:10 tomoj: CLHS is poor documentation?

21:10 danlei: and the things I don't like about clojure are mostly stuff where java sticks out

21:10 so, well

21:10 arbscht: too many implementations? the number of java implementations is in the same order of magnitude

21:11 danlei: I don't know, all this has never been an issue for me

21:11 peregrin181: danlei: thats true. But at least I can use one of the java libs

21:11 danlei: yes, like you can use all C libs from lisp ;)

21:11 The-Kenn1: I really miss clos... method combination and such things.

21:11 somnium: arbscht: sun, openjdk, and ibm? there are more?

21:11 arbscht: somnium: a lot more

21:11 peregrin181: danlei: I really tried to like it :)

21:11 danlei: I know what you mean, but I didn't suffer very much

21:11 tomoj: danlei: that looks like basically what my clojure does

21:11 except I'm using multiplicity representation

21:11 danlei: I like clojure for being a modern lisp, which is moving, living and trying to be "better"

21:12 that's what makes it great (to me)

21:12 peregrin181: danlei: ding ding :)

21:12 arbscht: somnium: SE5, SE6, EE4, EE5 (GlassFish, JBoss, Geronimo, WebLogic ...), ME, FX, OpenJDK, GIJ/GCJ, ECJ, Harmony, Dalvik, JRockI

21:12 t

21:12 peregrin181: arbscht: But real people use JRE :P and Dalvik only runs on android

21:13 arbscht: peregrin181: I'm sure you could make such arguments for some CL implementations

21:13 danlei: tomoj: I had no problems with it's speed ... or was that just hypothetical?

21:13 peregrin181: there are also things that are very nice about cl, like the condition system for example

21:14 peregrin181: it's not black and white, I think both langs have much to offer

21:14 peregrin181: danlei: And I agree I wasn't trying to anger

21:14 tomoj: danlei: e.g. factorizing 53573153 takes 13 seconds for me

21:14 danlei: peregrin181: you don't :)

21:14 tomoj: a sec

21:14 tomoj: because it's got two big prime factors, and searching upwards for the next prime isn't very efficient, I think

21:15 danlei: tomoj: (FACTORIZE 53573153) took 16 milliseconds (0.016 seconds) to run

21:15 with 2 available CPU cores.

21:15 During that period, 16 milliseconds (0.016 seconds) were spent in user mode

21:15 0 milliseconds (0.000 seconds) were spent in system mode

21:15 1,384 bytes of memory allocated.


21:15 ah, sorry for the mess

21:15 tomoj: you know what, though? if you're dividing out all of the smaller factors, you don't even need to care whether the factor is prime

21:15 peregrin181: danlei: how did you get that data?

21:15 tomoj: checking primality is a waste of time

21:15 danlei: tomoj: so, the CL version is pretty fast actually

21:16 peregrin181: thats ccl's TIME

21:16 peregrin181: danlei ah

21:16 tomoj: I wonder why it's so much faster

21:16 peregrin181: tomoj: probably something to do with lazy evaluation

21:16 tomoj: Pure guess

21:16 danlei: I can't tell you :)

21:16 I'm no expert with this, just wrote it some time ago

21:17 tomoj: wow, skipping the primality check sped my code up 32x

21:17 1-20 in 1.5ms now

21:18 danlei: I guess I could even squeeze more performance out of the cl version if I declared types

21:19 tomoj: danlei: why are you checking for primality?

21:19 danlei: (time (factorize 1234321234213243)) -> 141ms

21:19 tomoj: get rid of the prime check, I bet you'll get the same answers and a lot faster

21:19 danlei: a moment

21:20 tomoj: because if you start dividing by 2 and work your way up, any number that's not prime won't divide the accumulator anyway, so no point in checking whether they're prime

21:20 danlei: doesn't really make a difference in runtime, but you're right

21:20 tomoj: wat? that doesn't make any sense

21:21 I got a 32x speedup...

21:21 danlei: well:

21:21 141ms, just like before

21:21 tomoj: oh, I was checking for primality by going from 2 to n-1

21:21 instead of sqrt(n)

21:21 that probably slowed me down a lot :(

21:22 danlei: yes, sounds so

21:23 tomoj: ok, now factorizing 1234321234213243 takes me 739ms, that sounds more reasonable as attributable to naive clojure overhea

21:23 danlei: yes, it does

21:24 I also tried to squeeze some performance out of it with type declarations, but it wasn't worth it

21:24 around 140ms

21:26 but I'm asking myself why I put the primep in there anyway ...

21:26 tomoj: I don't think type hinting would really help me any.. maybe I can avoid boxing though? I dunno how to speed clojure up

21:26 well, I put one in there at first too :)

21:26 danlei: :)

21:27 tomoj: it seems like a waste to check numbers which can't possibly divide the accumulator because you've already factored out all their factors

21:27 but I guess it's actually faster to do this than to make sure you're only checking primes

21:27 danlei: anyway, it's 3:30 over here, and I'll call it a night :)

22:05 Licenser: hrm, I

22:05 v

22:05 argh - sorry

22:05 I've a very odd behaviour with a funciton, it claims to have the wrong number of arguments - but it shouldn't

22:05 http://www.pastebin.cz/24489 <- is the code + example + error.

22:05 Is that a bug or am I just plain stupid

22:06 likely it's the second but well I'm working on it for one houre and don't see what's wrong o.o

22:09 thanks, I am just plain stupid, I found the bug - had a argument too much in an anon function :/

22:18 brweber2: can anyone help me create an exception class that only has a constructor that takes a string parameter?

22:25 liebke: Licenser: remove the formater argument from the anonymous function you're passing to map: (map (fn [row] (table-row row formater)) data)

22:26 Licenser: liebke: thanks, found that a bit ago but I was running nuts - I really really have to get used to reading java exceptions again o.o

22:26 liebke: :)

22:27 Licenser: I was looking at the make-table function thinking I'd passed it the wrong number of arguments o.O

22:30 eyeris: I have code that makes a Swing JFrame. It runs properly when I use clojure.lang.Repl, but when I use vimclojure's Nailgun repl, the function that creates the JFrame returns nil.

22:31 Licenser: eyeris: does the nailgun reply have a display to draw on?

22:31 eyeris: Licenser: it should, because DISPLAY is set.

22:31 I guess maybe it is dropping the environment?

22:31 Licenser: I don

22:31 I don't know it would just be my first guess

22:42 eyeris: I just made NGServer dump it's environment when it starts and when it exits. DISPLAY is set at both times.

22:42 Good idea though :)

22:49 In vimclojure's repl, how do I evaluate what I type?

22:49 When I type in clojure code and hit enter, nothing is printed out

23:25 technomancy: why does test_clojure/logic.clj test to see that (symbol "") is true?

Logging service provided by n01se.net