2009-10-20
| 00:00 | steiger | bye guys |
| 00: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 |
| 00:13 | technomancy | jruby probably doesn't care about that kind of compatibility |
| 00:14 | technomancy | neither do _I_ for that matter |
| 00:15 | technomancy | 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. |
| 00:17 | technomancy | ,(.getContextClassLoader (Thread/currentThread)) |
| 00:17 | clojurebot | java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader) |
| 00:18 | technomancy | that's a #<DynamicClassLoader clojure.lang.DynamicClassLoader@84cc09> |
| 00:18 | technomancy | maybe there's a way to use that to load a given class |
| 00:23 | technomancy | nope; looks like even classes explicitly loaded with the DynamicClassLoader do not honor its dynamic classpath. |
| 00:23 | technomancy | that's a shame |
| 00:31 | eyeris | My god I hate the classpath. |
| 00:34 | mikehinchey | add-classpath doesn't do what you need? |
| 00:34 | eyeris | I hate that my code has to be in the same classpath as my tools |
| 00:35 | eyeris | e.g. vimclojure's nailgun server's classpath has to be able to access both my code and it's own |
| 00:35 | eyeris | which means that my code and vimclojure both have to be compatible with specific versions of clojure and libs |
| 00:36 | eyeris | But in general, I shouldn't have to have a different script to launch each tool |
| 00:36 | mikehinchey | how would it execute your code if it couldn't access them? |
| 00:36 | eyeris | that all just manipulate CLASSPATH a little differently |
| 00:36 | eyeris | I am not trying to solve the problem |
| 00:37 | eyeris | I am just bitching that it suck |
| 00:37 | eyeris | s |
| 00:37 | technomancy | mikehinchey: add-classpath only alters the current instance of clojure.lang.DynamicClassLoader |
| 00:38 | technomancy | in many instances that's not enough |
| 00:38 | technomancy | not that I know why |
| 00:40 | riddochc | This is weird... |
| 00:40 | riddochc | clojurebot: (str "\" "/") ") |
| 00:40 | clojurebot | Titim gan éirí ort. |
| 00:41 | riddochc | Woah. Even weirder. |
| 00:41 | mikehinchey | oh, maybe your onerous library is on the system classloader, so a child cl won't work |
| 00:41 | riddochc | For me, it gives: "\" clojure.core$_SLASH___4461@18c3679) " |
| 00:41 | riddochc | This is out of an effort to get (str "\" "/") => "\/" |
| 00:42 | riddochc | Which was brought about by trying to do something like (println (re-gsub #"/" "\\\/" "one/two/three")) |
| 00:43 | mikehinchey | ,(str "\\" "/") |
| 00:43 | clojurebot | "\\/" |
| 00: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. |
| 00:43 | technomancy | but it's some other classloader that isn't honoring my changes |
| 00:59 | riddochc | Now, *that's* what I wanted: |
| 01:00 | riddochc | clojurebot: (println (re-gsub #"/" ,(str "\\\\" "/") "one/two/three")) |
| 01:00 | clojurebot | It's greek to me. |
| 01:00 | riddochc | ,(println (re-gsub #"/" ,(str "\\\\" "/") "one/two/three")) |
| 01:00 | clojurebot | java.lang.Exception: Unable to resolve symbol: re-gsub in this context |
| 01:01 | riddochc | Well, okay. It prints "one\/two\/three" - leaning toothpick syndrome, for sure. |
| 01:02 | tomoj | what's the point of (str "\\\\" "/") ? |
| 01:08 | riddochc | A situation of genuine double-escape need... Clojure's producing a string that will get interpreted by another program as code. |
| 01:13 | riddochc | 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. |
| 01:13 | riddochc | And yes, it deserves a few lines of comments. |
| 01:33 | hiredman | java.lang.ClassFormatError: Duplicate method name&signature in class file hiredman/reader/StringReader |
| 01:33 | hiredman | what a drag |
| 01:33 | hiredman | the java part compiles fine but compile-clojure pukes |
| 02:14 | Atif | ping |
| 02:14 | arbscht | pong |
| 02:15 | aatifh | arbscht, i have this float value 38.20000076 and just 38.20 how to do that? |
| 02:18 | aatifh | ping |
| 02:35 | aatifh | ping |
| 03:10 | yason | aatifh: assumedly you want to print the floating point number into a string? |
| 03:10 | aatifh | yason, yes |
| 03:11 | yason | aatifh: see the format function |
| 03:11 | aatifh | yason, hmm |
| 03:11 | yason | it's akin to printf() in C |
| 03:17 | aatifh | yason, so, thats it (format "%.2f" (Float/parseFloat "-12.1021")) |
| 03:17 | aatifh | yason, I hope its a better way |
| 06:43 | mikem` | date |
| 07:39 | serp_ | platt katt |
| 08:55 | AWizzArd | ~max people |
| 08:55 | clojurebot | max people is 185 |
| 08:56 | licoresse | ~what's for dinner? |
| 08:56 | clojurebot | for is a loop...in Java |
| 08:57 | licoresse | ,*clojure-version* |
| 08:57 | clojurebot | {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"} |
| 08:58 | snowwhite | What is the best to get the datetime object of a month before the current datetime? |
| 08:58 | snowwhite | *way |
| 08:58 | AWizzArd | What is a datetime object? |
| 09:00 | snowwhite | AWizzArd, Java datetime object |
| 09:01 | AWizzArd | i heared of java.util.Date |
| 09:01 | AWizzArd | ,(.format (java.text.SimpleDateFormat. "yyyy-MM-dd_HH-mm-ss") (java.util.Date.)) |
| 09:01 | clojurebot | "2009-10-20_06-08-37" |
| 09:02 | AWizzArd | maybe this is what you want |
| 09: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 |
| 09:03 | liwp | if you have to do complex date/time stuff, look into yoda (?) which is an advanced date/time java lib |
| 09:04 | liwp | ahh, joda: http://joda-time.sourceforge.net/ |
| 09:04 | licoresse | (dec (.getMonth (java.util.Date.))) |
| 09:04 | liwp | licoresse: and now turn that into a date again ;) |
| 09:05 | licoresse | :D |
| 09:05 | chouser | It's just too horrible: |
| 09:05 | chouser | ,(.getTime (doto (java.util.Calendar/getInstance) (.add java.util.Calendar/MONTH -1))) |
| 09:05 | clojurebot | #<Date Sun Sep 20 06:12:33 PDT 2009> |
| 09: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. |
| 09:12 | liwp | looking at the joda api (I've never used it myself) it seems that (new Instant()).minus(Months.ONE) could work |
| 09:13 | liwp | there's probably some other, more idiomatic way of doing it, which would avoid the Instant instantiation... |
| 09:16 | snowwhite | chouser, Thank you so much. |
| 09: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 |
| 09:19 | mikem` | I think it's the laziness biting me |
| 09: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? |
| 09:22 | tomoj | that's... odd |
| 09:22 | Chousuke | try (println (doall specs)) |
| 09:22 | Chousuke | to see if it has something to do with laziness |
| 09:24 | mikem` | Chousuke: ah, you're right. I needed to doall the sequence |
| 09:24 | Chousuke | that's weird though |
| 09:25 | Chousuke | it should work even without doall :/ |
| 09:25 | mikem` | hm, maybe I should get the hang of things first before using lazy functions |
| 09:26 | chouser | what is get-package-specs ? |
| 09:27 | mikem` | Chousuke: get-package-specs is: http://paste.lisp.org/display/88978#4 |
| 09:28 | Chousuke | mikem`: that doesn't return a vector though :) |
| 09:28 | Chousuke | I don't think that should explode though. |
| 09:28 | mikem` | ah, my docs are out of sync :) |
| 09:28 | tomoj | that shouldn't cause a Character->ISeq error, should it? |
| 09:28 | Chousuke | unless read-lines does something silly. |
| 09:29 | chouser | read-lines is a bit dangerous, but I don't see how it could cause that error |
| 09: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 |
| 09:31 | Chousuke | read-lines is not a core function though. |
| 09:31 | Chousuke | mikem`: is it from contrib or did you write it yourself? |
| 09:31 | mikem` | read-lines? it's from contrib.duck-streams |
| 09:32 | Chousuke | 'k. I guess it should be fine. |
| 09:32 | chouser | read-lines will tend to leak the file handle rather than close too early. |
| 09:32 | chouser | mikem`: I can't reproduce it here -- can you paste the whole stack trace? |
| 09:33 | mikem` | chouser: i'm having troubles reproducing it too, now |
| 09:34 | mikem` | are these lazy seqs cached somehow? |
| 09:34 | rhickey_ | mikem`: have you rebuilt Clojure while running? |
| 09: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. |
| 09: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 |
| 09:36 | mikem` | chouser: ah, i see. I thought source would show me the function as it is currently defined in memory |
| 09:36 | rhickey_ | mikem`: are you using Slime? |
| 09:36 | mikem` | rhickey_: no, vimclojure |
| 09: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. |
| 09:37 | rhickey_ | a stack trace would help |
| 09:38 | mikem` | in that case, it might be an issue with the function as defined in the source vs being executed |
| 09:38 | mikem` | if i get this exception again, I'll get the stack trace :) thanks for the help |
| 09:40 | chouser | rhickey_: all the dispatch-fns in a multiprotocol should have the same range even if their domain is different? |
| 09:40 | chouser | I guess that's essentially what you say in the first sentence. |
| 09:41 | tomoj | I wonder why compile errors in slime show up in *inferior-lisp* instead of popping up debugger buffers |
| 09:42 | The-Kenny | tomoj: They trigger a debugger-buffer here. |
| 09:43 | tomoj | The-Kenny: orly? what versions of emacs, clojure-mode, and swank-clojure? |
| 09:44 | The-Kenny | tomoj: http://img4.abload.de/img/screenshot2009-10-20at1aii.png |
| 09:44 | The-Kenny | tomoj: A very recent slime from cvs, clojure-mode etc. fresh from github. |
| 09:44 | tomoj | is that aquamacs? |
| 09:44 | The-Kenny | Yes |
| 09: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 |
| 09:45 | eevar2 | and now the people in #emacs don't shun me any more ;) |
| 09:45 | rhickey_ | chouser: no, just that the mapping of the set of methods must be to a single dispatch value |
| 09:46 | Chousuke | emacs.app 23.1 works fine |
| 09:46 | tomoj | I get a "Compilation failed: ..." in the minibuffer and the stacktrace in *inferior-lisp* |
| 09:46 | Chousuke | though it's a bit slow |
| 09:46 | rhickey_ | chouser: but one mapping could be to [:a :b] and another to 42 |
| 09: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 |
| 09:49 | Chousuke | I wish they'd use git or something though. having to apply patches manually is a pain. |
| 09:50 | tomoj | does anyone using gnu emacs get compilation errors in a debugger buffer? |
| 09:56 | cgrand | rhickey_: have you any plan to suppoty primitive types (for args or return value) in protocols fns? |
| 09:56 | rhickey_ | cgrand: not other than the ones to support them in general for fns |
| 09:56 | rhickey_ | since protocol fns are merely fns |
| 09:57 | rhickey_ | I guess the dispatch arg cannot be primitive in any case |
| 09:57 | tomoj | is there somewhere I can read about protocol fns? |
| 09:58 | rhickey_ | http://www.assembla.com/wiki/show/clojure/Datatypes |
| 09:58 | rhickey_ | http://www.assembla.com/wiki/show/clojure/Protocols |
| 09:58 | tomoj | thanks |
| 09: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 | rhickey_ | 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 | rhickey_ | sine longs cover all integer primitives and doubles cover floats |
| 10:01 | rhickey_ | 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 | chouser | [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 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | 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 | chouser | 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 | rhickey_ | perf-wise I expect protocols to be competitive if they don't get laden with more dynamicity :) |
| 10:47 | rhickey_ | dataypes are raw Java classes |
| 10:47 | rhickey_ | smae perf |
| 10:47 | rhickey_ | same |
| 10:47 | RomanRoe | rhickey: thanks. would it work if I create a macro the wraps the binding macro? |
| 10:48 | RomanRoe | 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 | rhickey_ | 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 | rhickey_ | and there (proxy), closures make sense |
| 10:52 | rhickey_ | then datatypes might get interface impl only, no superclasses, no closure |
| 10:53 | rhickey_ | proxies remain anonymous, datatypes have useful explicit names |
| 10:53 | rhickey_ | proxies have limitations of interfaces, datatypes don't |
| 10:54 | rhickey_ | so good coverage of space |
| 10:55 | rhickey_ | 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 | rhickey_ | yet be high-enough perf to define the language itself in |
| 10:58 | rhickey_ | 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 | rhickey_ | 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 | patricius_ | 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 | chouser | 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 | patricius_ | 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 | patricius_ | chouser: perhaps the clojure tutorial here will do: http://java.ociweb.com/mark/clojure/article.html |
| 11:26 | patricius_ | 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 | rhickey_ | I'd really like to avoid plain "holes" in datatypes |
| 11:35 | rhickey_ | 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 | rhickey_ | 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 | Licenser | 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 | Chousuke | after adding a hideous hack to RT.java, the reader actually works |
| 12:06 | Chousuke | 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 | AWizzArd | I mean, not just writing a new .clj file, but editing the Clojure files themselves. |
| 12:08 | Chousuke | yes. |
| 12:09 | Chousuke | 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 | Chousuke | 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 | Chousuke | 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 | mattc58 | i'll be writing a Clojure library to another app that has a well defined protocol specification |
| 13:51 | mattc58 | 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 | mattc58 | apis |
| 14:13 | mattc58 | 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 | rhickey_ | he |
| 14:13 | rhickey_ | 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 | rhickey_ | with dynamic update of method defs without reload |
| 14:28 | cemerick | chouser: very, very true. |
| 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 | rhickey_ | 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 | chouser | 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 | rhickey_ | those fns could be closures, doesn't matter, but I don't imagine deftypes at other than the top level too often |
| 14:38 | rhickey_ | 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 | rhickey_ | so put the fns in static fields |
| 14:39 | rhickey_ | 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 | rhickey_ | 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:43 | chouser | but still no access to protected fields |
| 14:43 | chouser | 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 | rhickey_ | right - what protected fields? :) |
| 14:44 | rhickey_ | since no lookup, can inline right into fn bodies |
| 14:46 | chouser | (.invoke @MyClass/methodFn this arg1 arg2) |
| 14:46 | chouser | ? |
| 14:47 | rhickey_ | right, no @ |
| 14:47 | chouser | oh ... not an atom? |
| 14:48 | chouser | lock? |
| 14:48 | rhickey_ | no, volatile |
| 14:48 | rhickey_ | last-one-in-wins replacement |
| 14:50 | rhickey_ | 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: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 | rhickey_ | 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 | rhickey_ | 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 | cemerick | 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 | Licenser | 'just works' Sorry sully return key |
| 15:07 | chouser | Licenser: http://nullstyle.com/2008/11/09/ann-clojure-textmate-bundle-01/ |
| 15:08 | chouser | dunno anything about textmate, but google does. :-) |
| 15:08 | chouser | 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 | 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 | Chousuke | cemerick: JVM has a 64k limit on class files |
| 15:12 | Chousuke | 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 | cemerick | 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 | Chousuke | 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 | Licenser | 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 | lpetit | 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 | lpetit | 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: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 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | making it easy to port to C is a non-objective |
| 15:34 | rhickey_ | C being bereft of facilities |
| 15:34 | drewr | ok, so C was a bad example |
| 15:35 | drewr | 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 | drewr | 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 | rhickey_ | the whole point of moving to a different host is to leverage that host |
| 15:37 | rhickey_ | wrapping all hosts defeats a purpose of Clojure |
| 15:37 | rhickey_ | 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 | hiredman | which will face a lot of .toUpperCase kind of stuff |
| 15:40 | hiredman | 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 | rhickey_ | 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 | hiredman | said |
| 15:48 | rhickey_ | right, there was talk of that, but it may be hard to generalize |
| 15:49 | rhickey_ | 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 | hiredman | (I ran into some too when I was messing with it) |
| 15:53 | hiredman | 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 | rhickey_ | 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 | rhickey_ | it may be the case that you only need to statically analyze one half (the Java bit) |
| 16:06 | rhickey_ | 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 | rhickey_ | 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 | cemerick | 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 | cemerick | 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 | chouser | 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 | chouser | 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 | mwoelker | that would be me I guess |
| 16:23 | cemerick | doesn't ruby have explicit this? |
| 16:23 | cemerick | obviously, python does, and people manage |
| 16:23 | chouser | python does |
| 16:23 | chouser | 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 | cemerick | (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 | rhickey_ | 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 | Chousuke | turns out duplicating every object with line metadata added was kind of... bloating the whole thing |
| 16:26 | Chousuke | however now I have another error :P |
| 16:27 | Chousuke | 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 | Chousuke | 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 | rhickey_ | 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 | cemerick | 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 | cgrand | and I prefer explicit auto-hinted this (no surprise) |
| 16:31 | lpetit | "explicit auto-hinted first arg" |
| 16:32 | lpetit | yes really, KISS |
| 16:32 | lpetit | 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 | lisppaste8 | 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: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 | danlei | 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 | chouser | 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 | danlei | 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 | rhickey_ | 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 | rhickey_ | 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 | cemerick | 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 | rhickey_ | 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 | rhickey_ | trailing symbol meta?? name^{:tag String :alias :foaf:name} |
| 17:05 | rhickey_ | 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 | lpetit | 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 | chouser | 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 | danlei | 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 | lpetit | 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 | rhickey_ | 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 | hiredman | er |
| 17:18 | hiredman | 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 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | I guess you'd never have nested :ignore, and nested :identity might be rare as well |
| 17:26 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | certainly an interop mightmare |
| 17:31 | rhickey_ | 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 | rhickey_ | 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 | rhickey_ | 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 | lpetit | 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 | rhickey_ | you wouldn't be able to reach into any Clojure composite like that either |
| 17:49 | lpetit | rhickey_: Arrays.deepEquals(Object[]) |
| 17:50 | lpetit | 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 | rhickey_ | 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 | Chousuke | 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 | hiredman | 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 | Chousuke | but the thing is, it won't recompile clojure.core or clojure.lang.reader because they're already loaded :P |
| 18:06 | Chousuke | 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 | Chousuke | 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 | Licenser | 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 | rhickey_ | 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 | Licenser | I |
| 18:32 | Licenser | 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 | Licenser | 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 | travisbrady | 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 | travisbrady | 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 | travisbrady | 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 | danlei | and with abcl even on the jvm |
| 18:45 | danlei | 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 | licoresse | (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 | Chousuke | 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 | Chousuke | 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 | hiredman | http://tapestryjava.blogspot.com/2009/10/cascade-exception-reporting.html |
| 18:57 | hiredman | hlship |
| 19:04 | somnium | it looks like a slime stacktrace with css |
| 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 | danlei | 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 | peregrine81 | 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 | technomancy | 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 | peregrine81 | oops sorry I will be back in 20 |
| 20:07 | peregrin181 | alright I am back |
| 20:10 | peregrin181 | 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 | peregrin181 | 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 | danlei | (which might be spoilery) |
| 20:15 | danlei | (defn find-divisible [r] |
| 20:15 | danlei | (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 | danlei | but how fast must it be? |
| 20:16 | danlei | it solves the task fine |
| 20:16 | tomoj | oh, euler doesn't care |
| 20:17 | danlei | "Elapsed time: 128.06173 msecs" |
| 20:17 | danlei | not fastest, but fast enough for my neurons .) |
| 20:17 | tomoj | much faster than I thought |
| 20:17 | danlei | 1-10 |
| 20:18 | danlei | 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 | tomoj | 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 | peregrin181 | 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 | tomoj | I still have no idea what your code is trying to do, sorry :( |
| 20:29 | tomoj | 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 | tomoj | 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 | danlei | (first (drop-while (fn [n] (not (every? #(zero? (rem n %)) r))) (iterate inc 1)))) |
| 20:32 | danlei | start from the every? |
| 20:32 | danlei | every? returns true if a given predicate holds for all elements of a seq |
| 20:33 | danlei | so the every? will return true, if all (rem n %) are true for the values in r, which is a range |
| 20:33 | danlei | (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 | danlei | you get the picture? |
| 20:34 | peregrin181 | what is the iterate inc 1 |
| 20:34 | danlei | yes, (range 1 21) |
| 20:34 | danlei | its all numbers starting from 1 |
| 20:34 | danlei | 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 | danlei | and the first just picks the first available, which will be your result |
| 20:36 | danlei | 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 | peregrin181 | the #( means anonymous fn correct? |
| 20:36 | danlei | I'm not good at explaining :) |
| 20:36 | danlei | yes, its sugar for fn, binds % and stuff implicitly |
| 20:37 | danlei | and to show you how slow it really is: |
| 20:37 | danlei | "Elapsed time: 985956.807695 msecs" |
| 20:37 | danlei | :) |
| 20:38 | peregrin181 | still faster than running forever |
| 20:38 | danlei | btw. theres also not-every? |
| 20:39 | danlei | yes it does the job, eventually ;) |
| 20:39 | peregrin181 | danlei thanks |
| 20:39 | danlei | but it's a very naive approach |
| 20:39 | danlei | you're welcome |
| 20:40 | peregrin181 | far less naive then mine |
| 20:40 | peregrin181 | 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 | danlei | 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 | danlei | a general tip is: always check if it simplifies and terminates |
| 20:45 | danlei | (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 | tomoj | also, cool re compling, I'm taking an intro compling class now |
| 20:47 | tomoj | I really want to rewrite nltk in clojure because python makes me sad |
| 20:48 | danlei | "Elapsed time: 985956.807695 msecs" :) |
| 20:49 | danlei | I'm just at the start right now, much "traditional" linguistics atm, the basics |
| 20:49 | danlei | 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 | peregrin181 | ? |
| 20:56 | tomoj | the way that counts upwards and checks for each number whether all the numbers in the list divide it |
| 20:56 | tomoj | 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 | tomoj | I wonder how long the naive way takes to get 1-30 |
| 20:58 | tomoj | 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 | peregrin181 | lol |
| 21:04 | tomoj | danlei: a little, not much |
| 21:04 | danlei | I haven't done euler for a long time |
| 21:04 | danlei | but I have alittle factorizer here |
| 21:04 | danlei | 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 | danlei | 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 | danlei | clojure, too. I like both of them |
| 21:08 | danlei | what didn't you like? |
| 21:08 | somnium | weblocks is cool |
| 21:08 | danlei | never used it, just hunchentoot |
| 21:08 | danlei | 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 | peregrin181 | 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 | danlei | 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 | danlei | 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 | tomoj | 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 | danlei | 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 | arbscht | 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 | danlei | peregrin181: there are also things that are very nice about cl, like the condition system for example |
| 21:14 | danlei | 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 | danlei | 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 | danlei | with 2 available CPU cores. |
| 21:15 | danlei | During that period, 16 milliseconds (0.016 seconds) were spent in user mode |
| 21:15 | danlei | 0 milliseconds (0.000 seconds) were spent in system mode |
| 21:15 | danlei | 1,384 bytes of memory allocated. |
| 21:15 | danlei | |
| 21:15 | danlei | 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 | danlei | 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 | peregrin181 | tomoj: Pure guess |
| 21:16 | danlei | I can't tell you :) |
| 21:16 | danlei | 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 | tomoj | 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 | tomoj | I got a 32x speedup... |
| 21:21 | danlei | well: |
| 21:21 | danlei | 141ms, just like before |
| 21:21 | tomoj | oh, I was checking for primality by going from 2 to n-1 |
| 21:21 | tomoj | instead of sqrt(n) |
| 21:21 | tomoj | 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 | danlei | I also tried to squeeze some performance out of it with type declarations, but it wasn't worth it |
| 21:24 | danlei | around 140ms |
| 21:26 | danlei | 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 | tomoj | 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 | tomoj | 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 | Licenser | v |
| 22:05 | Licenser | argh - sorry |
| 22:05 | Licenser | I've a very odd behaviour with a funciton, it claims to have the wrong number of arguments - but it shouldn't |
| 22:05 | Licenser | http://www.pastebin.cz/24489 <- is the code + example + error. |
| 22:05 | Licenser | Is that a bug or am I just plain stupid |
| 22:06 | Licenser | 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 | Licenser | 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 | eyeris | I guess maybe it is dropping the environment? |
| 22:31 | Licenser | I don |
| 22:31 | Licenser | 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 | eyeris | Good idea though :) |
| 22:49 | eyeris | In vimclojure's repl, how do I evaluate what I type? |
| 22:49 | eyeris | 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? |