#clojure logs

2009-10-20

00:00steigerbye guys
00:13technomancy"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:13technomancyjruby probably doesn't care about that kind of compatibility
00:14technomancyneither do _I_ for that matter
00:15technomancyI 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:17technomancy,(.getContextClassLoader (Thread/currentThread))
00:17clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader)
00:18technomancythat's a #<DynamicClassLoader clojure.lang.DynamicClassLoader@84cc09>
00:18technomancymaybe there's a way to use that to load a given class
00:23technomancynope; looks like even classes explicitly loaded with the DynamicClassLoader do not honor its dynamic classpath.
00:23technomancythat's a shame
00:31eyerisMy god I hate the classpath.
00:34mikehincheyadd-classpath doesn't do what you need?
00:34eyerisI hate that my code has to be in the same classpath as my tools
00:35eyerise.g. vimclojure's nailgun server's classpath has to be able to access both my code and it's own
00:35eyeriswhich means that my code and vimclojure both have to be compatible with specific versions of clojure and libs
00:36eyerisBut in general, I shouldn't have to have a different script to launch each tool
00:36mikehincheyhow would it execute your code if it couldn't access them?
00:36eyeristhat all just manipulate CLASSPATH a little differently
00:36eyerisI am not trying to solve the problem
00:37eyerisI am just bitching that it suck
00:37eyeriss
00:37technomancymikehinchey: add-classpath only alters the current instance of clojure.lang.DynamicClassLoader
00:38technomancyin many instances that's not enough
00:38technomancynot that I know why
00:40riddochcThis is weird...
00:40riddochcclojurebot: (str "\" "/") ")
00:40clojurebotTitim gan éirí ort.
00:41riddochcWoah. Even weirder.
00:41mikehincheyoh, maybe your onerous library is on the system classloader, so a child cl won't work
00:41riddochcFor me, it gives: "\" clojure.core$_SLASH___4461@18c3679) "
00:41riddochcThis is out of an effort to get (str "\" "/") => "\/"
00:42riddochcWhich was brought about by trying to do something like (println (re-gsub #"/" "\\\/" "one/two/three"))
00:43mikehinchey,(str "\\" "/")
00:43clojurebot"\\/"
00:43technomancymikehinchey: 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:43technomancybut it's some other classloader that isn't honoring my changes
00:59riddochcNow, *that's* what I wanted:
01:00riddochcclojurebot: (println (re-gsub #"/" ,(str "\\\\" "/") "one/two/three"))
01:00clojurebotIt's greek to me.
01:00riddochc,(println (re-gsub #"/" ,(str "\\\\" "/") "one/two/three"))
01:00clojurebotjava.lang.Exception: Unable to resolve symbol: re-gsub in this context
01:01riddochcWell, okay. It prints "one\/two\/three" - leaning toothpick syndrome, for sure.
01:02tomojwhat's the point of (str "\\\\" "/") ?
01:08riddochcA situation of genuine double-escape need... Clojure's producing a string that will get interpreted by another program as code.
01:13riddochcMade 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:13riddochcAnd yes, it deserves a few lines of comments.
01:33hiredmanjava.lang.ClassFormatError: Duplicate method name&signature in class file hiredman/reader/StringReader
01:33hiredmanwhat a drag
01:33hiredmanthe java part compiles fine but compile-clojure pukes
02:14Atifping
02:14arbschtpong
02:15aatifharbscht, i have this float value 38.20000076 and just 38.20 how to do that?
02:18aatifhping
02:35aatifhping
03:10yasonaatifh: assumedly you want to print the floating point number into a string?
03:10aatifhyason, yes
03:11yasonaatifh: see the format function
03:11aatifhyason, hmm
03:11yasonit's akin to printf() in C
03:17aatifhyason, so, thats it (format "%.2f" (Float/parseFloat "-12.1021"))
03:17aatifhyason, I hope its a better way
06:43mikem`date
07:39serp_platt katt
08:55AWizzArd~max people
08:55clojurebotmax people is 185
08:56licoresse~what's for dinner?
08:56clojurebotfor is a loop...in Java
08:57licoresse,*clojure-version*
08:57clojurebot{:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}
08:58snowwhiteWhat is the best to get the datetime object of a month before the current datetime?
08:58snowwhite*way
08:58AWizzArdWhat is a datetime object?
09:00snowwhiteAWizzArd, Java datetime object
09:01AWizzArdi heared of java.util.Date
09:01AWizzArd,(.format (java.text.SimpleDateFormat. "yyyy-MM-dd_HH-mm-ss") (java.util.Date.))
09:01clojurebot"2009-10-20_06-08-37"
09:02AWizzArdmaybe this is what you want
09:02liwpI 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:03liwpif you have to do complex date/time stuff, look into yoda (?) which is an advanced date/time java lib
09:04liwpahh, joda: http://joda-time.sourceforge.net/
09:04licoresse(dec (.getMonth (java.util.Date.)))
09:04liwplicoresse: and now turn that into a date again ;)
09:05licoresse:D
09:05chouserIt's just too horrible:
09:05chouser,(.getTime (doto (java.util.Calendar/getInstance) (.add java.util.Calendar/MONTH -1)))
09:05clojurebot#<Date Sun Sep 20 06:12:33 PDT 2009>
09:06chousersnowwhite: 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:12liwplooking at the joda api (I've never used it myself) it seems that (new Instant()).minus(Months.ONE) could work
09:13liwpthere's probably some other, more idiomatic way of doing it, which would avoid the Instant instantiation...
09:16snowwhitechouser, Thank you so much.
09:16mikem`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:19mikem`I think it's the laziness biting me
09:21tomojyou defined process-spec-list to just be the identity, and (get-package-specs ..) worked, but (process-spec-list (get-package-specs ..)) didn't?
09:22tomojthat's... odd
09:22Chousuketry (println (doall specs))
09:22Chousuketo see if it has something to do with laziness
09:24mikem`Chousuke: ah, you're right. I needed to doall the sequence
09:24Chousukethat's weird though
09:25Chousukeit should work even without doall :/
09:25mikem`hm, maybe I should get the hang of things first before using lazy functions
09:26chouserwhat is get-package-specs ?
09:27mikem`Chousuke: get-package-specs is: http://paste.lisp.org/display/88978#4
09:28Chousukemikem`: that doesn't return a vector though :)
09:28ChousukeI don't think that should explode though.
09:28mikem`ah, my docs are out of sync :)
09:28tomojthat shouldn't cause a Character->ISeq error, should it?
09:28Chousukeunless read-lines does something silly.
09:29chouserread-lines is a bit dangerous, but I don't see how it could cause that error
09:30rhickey_if you realize the lazy seq after the file is closed you will have problems. Look through the stack trace for the cause
09:31Chousukeread-lines is not a core function though.
09:31Chousukemikem`: is it from contrib or did you write it yourself?
09:31mikem`read-lines? it's from contrib.duck-streams
09:32Chousuke'k. I guess it should be fine.
09:32chouserread-lines will tend to leak the file handle rather than close too early.
09:32chousermikem`: I can't reproduce it here -- can you paste the whole stack trace?
09:33mikem`chouser: i'm having troubles reproducing it too, now
09:34mikem`are these lazy seqs cached somehow?
09:34rhickey_mikem`: have you rebuilt Clojure while running?
09:34chouserI 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:36mikem`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:36mikem`chouser: ah, i see. I thought source would show me the function as it is currently defined in memory
09:36rhickey_mikem`: are you using Slime?
09:36mikem`rhickey_: no, vimclojure
09:37chouserlazy-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:37rhickey_a stack trace would help
09:38mikem`in that case, it might be an issue with the function as defined in the source vs being executed
09:38mikem`if i get this exception again, I'll get the stack trace :) thanks for the help
09:40chouserrhickey_: all the dispatch-fns in a multiprotocol should have the same range even if their domain is different?
09:40chouserI guess that's essentially what you say in the first sentence.
09:41tomojI wonder why compile errors in slime show up in *inferior-lisp* instead of popping up debugger buffers
09:42The-Kennytomoj: They trigger a debugger-buffer here.
09:43tomojThe-Kenny: orly? what versions of emacs, clojure-mode, and swank-clojure?
09:44The-Kennytomoj: http://img4.abload.de/img/screenshot2009-10-20at1aii.png
09:44The-Kennytomoj: A very recent slime from cvs, clojure-mode etc. fresh from github.
09:44tomojis that aquamacs?
09:44The-KennyYes
09:45tomojhmm.. 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:45eevar2and now the people in #emacs don't shun me any more ;)
09:45rhickey_chouser: no, just that the mapping of the set of methods must be to a single dispatch value
09:46Chousukeemacs.app 23.1 works fine
09:46tomojI get a "Compilation failed: ..." in the minibuffer and the stacktrace in *inferior-lisp*
09:46Chousukethough it's a bit slow
09:46rhickey_chouser: but one mapping could be to [:a :b] and another to 42
09:48ChousukeI 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:49ChousukeI wish they'd use git or something though. having to apply patches manually is a pain.
09:50tomojdoes anyone using gnu emacs get compilation errors in a debugger buffer?
09:56cgrandrhickey_: have you any plan to suppoty primitive types (for args or return value) in protocols fns?
09:56rhickey_cgrand: not other than the ones to support them in general for fns
09:56rhickey_since protocol fns are merely fns
09:57rhickey_I guess the dispatch arg cannot be primitive in any case
09:57tomojis there somewhere I can read about protocol fns?
09:58rhickey_http://www.assembla.com/wiki/show/clojure/Datatypes
09:58rhickey_http://www.assembla.com/wiki/show/clojure/Protocols
09:58tomojthanks
09:58cgrandok, then what are you plans for primitives support in fns?
10:00rhickey_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:01rhickey_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:01rhickey_sine longs cover all integer primitives and doubles cover floats
10:01rhickey_since
10:03cgrandok, thanks
10:04rhickey_so compiler seeing (foo x) used as an arg taking long, or #^long (foo x) will convert foo to ILongFn and then invoke
10:05Chousukeis 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:05cgrandwith protocols and datatypes, PersistentVector (for example) would be still be implemented with reify to support java Interfaces (and IFn?)?
10:05chouserthis is probably beyond 1.1?
10:06chouser[rephrasing] primitive support in fns will probably be after 1.1?
10:07rhickey_chouser: definitely, probably after cinc so we can use macros for the vast boilerplate :)
10:08rhickey_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:09chouserah, yes. I used a couple macros in finger trees for reify boilerplate. Turned out well there I think.
10:09rhickey_supporting interface implementation in datatypes definitely complicates things, but I have looked at it
10:10tmountainjust curious... how soon should we realistically expect to see cinc?
10:10rhickey_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:12rhickey_if I bring interface implementation support to datatypes it will be strictly curtailed to interfaces only, none of this abstract/super/protected junk
10:12rhickey_implementation inheritance is truly a mess
10:14samlis it easy to replace some java classes with clojure without letting the team know?
10:18Chousukesaml: if everything uses interfaces, maybe... otherwise, maybe not :P
10:19samlthis code makes me want to go home
10:21rhickey_tmountain: not until after the mechanisms are in place to avoid Java - reify, protocols and datatypes are about that.
10:24tmountainrhickey_: just perusing the Datatypes wiki page... it's very cool to see even more performance enhancements coming down the pipe
10:28AWizzArdrhickey_: will you implement datatypes using newnew?
10:29rhickey_AWizzArd: no, they represent a different approach to the same issues, more finely sliced even than new new.
10:38RomanRoeIs it possible to store the vector used in a binding in a var for reuse? E.g. (def myb '[*a* 1]) & (binding myb ...) ?
10:42rhickey_RomanRoe: no
10:43rhickey_compile time is about forms, and runtime about their values
10:44chousersaml: 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:45chouserrhickey_: protocols+datatypes could replace reify, couldn't they? But that's not the plan because reify will still perform better?
10:46rhickey_chouser: what protocols + datatypes are missing is a bridge back to Java interfaces, esp. consumption from Java
10:46rhickey_perf-wise I expect protocols to be competitive if they don't get laden with more dynamicity :)
10:47rhickey_dataypes are raw Java classes
10:47rhickey_smae perf
10:47rhickey_same
10:47RomanRoerhickey: thanks. would it work if I create a macro the wraps the binding macro?
10:48RomanRoerhickey: guess I simply have to try ;-)
10:48chouserrhickey_: so might reify be cut yet?
10:51rhickey_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:52rhickey_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:52rhickey_and there (proxy), closures make sense
10:52rhickey_then datatypes might get interface impl only, no superclasses, no closure
10:53rhickey_proxies remain anonymous, datatypes have useful explicit names
10:53rhickey_proxies have limitations of interfaces, datatypes don't
10:54rhickey_so good coverage of space
10:55rhickey_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:55chouserok, 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:56rhickey_chouser: yes, I'd really like for Clojure's extensibility/abstraction story to not suffer the expression problem
10:57rhickey_yet be high-enough perf to define the language itself in
10:58rhickey_so you need raw, accessible, data, Clojure is already fast at manipulating that
10:58chouserright, you just need a way to define it: datatypes
10:58rhickey_primitive args will be needed to allow high-perf code to cross function boundaries
10:59rhickey_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:02cgrandand with protocols that would be fn > protocol dispatch > fn. Right?
11:02patricius_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:02patricius_I think the documentation is a little vague.
11:03chouserpatricius_: send is for actions that are CPU-bound. send-off is for actions that might block such as on IO
11:03patricius_ah, thanks!
11:04RomanRoepatricius_: http://java.ociweb.com/mark/clojure/article.html#Concurrency scroll down to section "Agents". Helped me a lot!
11:04patricius_RomanRoe: thanks
11:05Chousukethis bootstrap stuff is giving me a headache
11:05rhickey_cgrand: yes, protocol dispatch built into first fn
11:06chouserpatricius_, 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:08RomanRoechouser: to put it in other words: when in doubt, check the source, right? ;-)
11:09chouserRomanRoe: 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:09ChousukeI 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:10cgrandrhickey_: ah ok, so fn > fn with the protocol built into the first fn for perfs.
11:10Chousukeand I have no idea what it's doing :(
11:10chouserfor 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:10chouserWhat will remain true is that send will be appropriate for non-blocking actions, and send-off for blocking ones.
11:12RomanRoechouser: yep, makes sense
11:13cgrandrhickey_: another question (sorry to bother you), what about volatile and mutable fields? They are required for reference types, lazyseqs and transients.
11:15patricius_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:17chouserpatricius_: needs to be a published article, like in a real journal?
11:18patricius_Not necessarily.
11:19patricius_chouser: We've had a tutorial on SmallTalk presented, which never apperead in a journal or something like that.
11:20chouserpatricius_: 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:22patricius_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:26patricius_chouser: perhaps the clojure tutorial here will do: http://java.ociweb.com/mark/clojure/article.html
11:26patricius_chouser: but it maybe too long
11:26chouseryeah, maybe.
11:29patricius_chouser: anyhow, thanks for your help
11:34rhickey_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:34rhickey_I'd really like to avoid plain "holes" in datatypes
11:35rhickey_with reify they would have been bottled up pretty well, with datatypes not at all
11:36cgrandok so better push them in host-dependent code than pollute datatypes
11:37rhickey_cgrand: exactly
11:38rhickey_but there may be cases where the extra alloc is prohibitive
11:41cgrandrhickey_: thanks, things begin to fall into place
11:43Licenserhmm hmm hmmm
11:43Licenseryou are discussing thins that sound interesting :)
11:57AWizzArdCan (load my-path) accept compiled .class files, or only .clj files (or both)?
12:05Chousukeooh
12:06Chousukeafter adding a hideous hack to RT.java, the reader actually works
12:06Chousukethough, it throws an exception reading core.clj
12:07AWizzArdChousuke: to get your own reader you had to change existing code yes?
12:07AWizzArdI mean, not just writing a new .clj file, but editing the Clojure files themselves.
12:08Chousukeyes.
12:09ChousukeI have a hideous hack in RT.java involving using *warn-on-reflection* as a switch to force recompiling classes *but* not all classes ;(
12:10Chousukeit turns out that when I want to recompile clojure.core using my reader, it goes and recompiles my reader as well, and... boom.
12:10AWizzArdIs 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:10Chousukedefonce
12:11AWizzArdgood
13:33Chousukehm, interesting
13:34ChousukeI 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:39hiredman:(
13:50mattc58hey 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:51mattc58i'll be writing a Clojure library to another app that has a well defined protocol specification
13:51mattc58btw, hello everyone
14:05kmurph79the current clojure doesn't seem to be compiling -- anyone else have this problem?
14:06tmountainmattc58: have you looked at clojure.contrib.server-socket ?
14:06Chousukekmurph79: works for me
14:06mattc58tmountain: 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:07rhickey_kmurph79: ok here
14:07tmountainmattc58: something like apache MINA?
14:08kmurph79thanks, maybe i have a bad ant or java
14:10mattc58tmountain: is there a clojure library for it? i'm unfamiliar with it but looking at the site now.
14:10cemerickmattc58: are you looking for something like python's twisted?
14:11mattc58cemerick: 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:12tmountainmattc58: 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:12cemerickmongo doesn't have a REST or thrift api?
14:13mattc58there is a REST API in dev, but the normal way of using it is through native apids
14:13mattc58apis
14:13mattc58there's a java, for example that i could just wrap
14:13rhickey_mattc58: usually the easiest way to go is to wrap the Java API
14:13rhickey_he
14:13rhickey_heh
14:14cemerickmore than easiest -- code reuse and all that is a good thing :-)
14:15rhickey_http://github.com/geir/mongo-java-driver/blob/master/src/examples/clojure/mongo.clj
14:16mattc58yeah i saw that actually
14:16rhickey_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:19cemerickrhickey_: 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:20adityo,(Float/parseFloat "59641879")
14:20clojurebot5.964188E7
14:20rhickey_cemerick: sure just put up a patch
14:20cemerickrhickey_: great, thanks.
14:21mattc58as 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:21adityohow do i get the entire representation i.e 59641879.00
14:22mattc58as I use Mongo more for a project I'll determine if that actually works well in practice (it should in this case)
14:23cemerickmattc58: 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:24rhickey_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:24cemerickIf the API in question isn't clojure-friendly in some way, then it's definitely a judgement call.
14:25rhickey_so, it's rarely worth reinventing the lib's heavy lifting, just a question of wrap or use directly
14:26mattc58yeah, this all makes sense to me. ok thanks, exactly what I was looking for.
14:27cemerickI *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:27chousercemerick: there's a big difference between java code that others are voluntarily maintaining, and maintaining your own .java code.
14:28rhickey_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:28rhickey_with dynamic update of method defs without reload
14:28cemerickchouser: very, very true.
14:29chouserrhickey_: how more efficient than proxy?
14:30rhickey_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:31rhickey_since fns would be once for entire class, and coud be stored in static fields of class, so no map lookup on call
14:32cemerickrhickey_, the biggest tease on freenode ;-)
14:32liebkeadityo: do you want to change the number representation for the purposes of printing? (format "%.2f" (Float/parseFloat "59641879"))
14:32rhickey_but still could be dynamic, since deftype will just generate (set! DefTypeClass/methodfnfield (fn [this]...))
14:33adityoliebke: exactly what i wanted..thanks :)
14:33rhickey_as long as you don't change fields or interfaces, no reload required
14:33liebkeadityo: you're welcome :)
14:34rhickey_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:36chouserdoes no construction-time closure mean no closures at all for deftype?
14:36chouserand yet method fns?
14:37rhickey_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:38rhickey_those fns could be closures, doesn't matter, but I don't imagine deftypes at other than the top level too often
14:38rhickey_but first-class fn per method, just shared for all instances
14:38chouserah.. I see. by splitting def and ctor you can of course reduce ctor-time work.
14:39rhickey_right, deftype isn't about creating an instance at all, where proxy gave each instance its own set of fns
14:39rhickey_so put the fns in static fields
14:39rhickey_no lookup, still swappable
14:40chouserso interesting. by bundling the data in the object (like normal java objects after all) you remove the use case for instance closures
14:40rhickey_proxy will still be a better fit when you want closures, for handlers etc
14:40rhickey_also proxy had per-instance swappability, rarely used
14:41chouserand by making the methods swappable (for all instances simultaneously, right?) you remove the staticness of java classes (or even hypothetical named reify classes)
14:41rhickey_right
14:43chouserbut still no access to protected fields
14:43chouseroh, but this is for datatypes -- native clojure, not interop
14:43rhickey_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:43rhickey_right - what protected fields? :)
14:44rhickey_since no lookup, can inline right into fn bodies
14:46chouser(.invoke @MyClass/methodFn this arg1 arg2)
14:46chouser?
14:47rhickey_right, no @
14:47chouseroh ... not an atom?
14:48chouserlock?
14:48rhickey_no, volatile
14:48rhickey_last-one-in-wins replacement
14:50rhickey_never read-then-write
14:50chouserok
14:52rhickey_this seems to fit together well now
14:54lisppaste8rhickey pasted "deftype with interface support" at http://paste.lisp.org/display/88999
14:54neotyk~logs
14:54clojurebotlogs is http://clojure-log.n01se.net/
14:58lisppaste8rhickey annotated #88999 "deftype with interface no this" at http://paste.lisp.org/display/88999#1
14:58rhickey_cgrand: this can be autohinted, without it you're left with this first pass ^^
14:59liebkeI like that better, explicitly passing 'this
15:00rhickey_liebke: and writing both 'this' and that hint over and over?
15:00rhickey_In proxy I agree could be more of an issue due to potential nesting, less of an issue here at top level
15:01liebkeI wouldn't like to write the hint over and over, but writing 'this' over and over is fine with me :)
15:02rhickey_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:02rhickey_but ok, 2 for explicit this, any other views?
15:03liebketrue, the fundamental problem with programming language design is people :)
15:03danleiI agree that it should be implicit
15:03chouserthere's middle ground -- [(equals [this that] ...)] would still allow for auto-hinted this
15:04rhickey_chouser: yes, the macro could retrofit the hint
15:04chouseron the other hand, if the map in the second example were eval'd, that would make merging in some implementations pretty easy.
15:04cemerickyeah, some good old-fashioned tree-walking :-P
15:05cemerickI'll generally lean towards explicit this, FWIW.
15:05rhickey_chouser: yes, that second example was following the newer approach of protocols aimed at easier reuse of impls
15:06LicenserYou know what is one thing that clojure misses, a good Textmate integration :/
15:06rhickey_of course, with the map approach adding hints is not possible
15:06chouserright
15:06danleifor 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:07LicenserI know it sounds stupid but in the OS X world a lot stands or falls with this :(
15:07danleibesides being ... well ... explicit
15:07cemerickLicenser: you mean TM integration?
15:07Licensercemerick: a good bundle that is easy to install / use. something that
15:07Licenser'just works' Sorry sully return key
15:07chouserLicenser: http://nullstyle.com/2008/11/09/ann-clojure-textmate-bundle-01/
15:08chouserdunno anything about textmate, but google does. :-)
15:08chouserThat's almost a year old -- is that a good sign, or bad?
15:08Chousukehm
15:08Licenserchouser: a bad sign
15:08arsatikiGetBundles installs the wrong clojure bundle by default
15:08Licenserthe bundle you can get with GetBundles is horribly broken
15:09arsatikithe more recent version from github works so much better
15:09ChousukeI wonder what's causing core__init.class to become 265kB in size :(
15:10cemerickI'm really surprised that anyone uses TM for clojure.
15:10LicenserThe 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:10cemerick'course, there's vi folk here, so....
15:10ChousukeI don't know nearly enough about the JVM to debug this...
15:10Licensercemerick: You get used to TM once you start, I didn't belived it myself
15:10cemerickLicenser: I use it for one-off editing, but never for sustained development.
15:10Licensercemerick: 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:11arsatikiI've generally found myself more and more dissatisfied with TM lately
15:11cemerickChousuke: what's the error?
15:11rhickey_it seems to me that forgetting 'this' is a common bug for users of gen-class
15:11arsatikiProbably has to do with the fact that TM crashes for me almost daily now.
15:11Licensercemerick: what are you using for long term things?
15:11Chousukecemerick: the class is too big, simply
15:11Chousukecemerick: JVM has a 64k limit on class files
15:12Chousukecemerick: and I go 201kB over that.
15:12LicenserI used Aptana (Eclipse) for a while but I had some very annoying things with it which made me keep my hands of it
15:12Chousukethe verbose decompilation dump is *3.5MB*
15:12LicenserChousuke: heh I had this problem with JRuby once - was very frustrating
15:13cemerickChousuke: hrm, my core__init.class is 220K...but I'm not getting any errors.
15:13cemerickLicenser: Netbeans + enclojure.
15:13Licensercemerick: I'll try that one then - gladly I'm not the person that refuses to try new things :P
15:13bballantinecemerick, Licenser - sorry to butt in -- I think the clojure eclipse plugin (counterclockwise, I think it's called) is young but good.
15:14Chousukecemerick: ah, right, it was just "invalid method code length"
15:14Chousukeit looks like it's ~20k over the limit :/
15:14Licenserbballantine: I've no clue, I used eclipse with Ruby not clojure
15:14cemerickWe use NetBeans RCP, so eclipse is irrelevant for us.
15:14bballantineLicenser, 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:15cemerickGood luck to 'em though.
15:15Licenserbballantine: it looked like a good choice since in the project half the team (or most of it) were poor windows users
15:15bballantinei now mostly use VI for small stuff and ruby, I use eclipse for java and big python.
15:15ChousukeI think I'll check how big the regular clojure class file is
15:16The-KennyNacht
15:16Chousukehmm, right. 216kB for me
15:16The-Kennysorry.. wrong window
15:16LicenserNacht The-Kenny schlaf gut
15:16The-KennyLicenser: heh, I'll stay. A friend of me will go to bed now ;)
15:17bballantineLicenser - also, eclipse works much better on Linux than OS X for whatever reason.
15:17LicenserAh well even better :)
15:17Licenserbballantine: yes that is something we found out too
15:17Chousukeany ideas on how to make it smaller?
15:17LicenserChousuke: remove comments? *hides*
15:18rhickey_Chousuke: have you got some huge data literals in there?
15:19lpetitcounterclockwise 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:19lpetitno, it's an easter egg, of course :-)
15:19Licenserso the SOTA for editing clojour is the enclojure plugin and netbeans?
15:20lpetitWhat's great about clojure IDEs is that there is room for everybody
15:20lpetitYou can just keep using your preferred IDE
15:20LicenserI'd preffare TM since I got used to it and like how it functions
15:20samlnotepad + clojure.jar
15:21Licensersaml: when I try to run notpad.exe it tells me it isn't a executable
15:21lpetitIf 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:21lisppaste8rhickey annotated #88999 "deftype with interface explicit this" at http://paste.lisp.org/display/88999#2
15:21samlit's because you missed e for excellence
15:21lpetitBut if eclipse is your IDE, counterclockwise is good enough for you, already, and will improve over time
15:22Chousukerhickey_: well, it's core.clj, just compiled using my reader...
15:22samli installed cljoure plugin for eclopse
15:22Chousukerhickey_: it seems the init method is doing a Symbol.create and Symbol.intern for pretty much every symbol. :/
15:24rhickey_Chousuke: why would it be different than the Clojure reader?
15:25Licenserlets see now netbeans works
15:25Chousukerhickey_: 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:26liebkerhickey: I think I like the map version better just because you pass it an actual fn, and not the 'proxy'-like method specification
15:27rhickey_liebke: I think the manual hinting that will require will be unbearable for many people
15:27Chousukerhickey_: I had to convince it to compile a namespace that's already loaded :/
15:27liebkethat is probably true
15:27mwoelkerHi 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:29rhickey_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:30lpetitThat's a joy to see so much interesting stuff in the pipe !
15:30Chousukehttp://gensoukyou.net/core.dump.gz <- here's the disassembly of it, if someone feels like taking a look at it
15:30jlillyrhickey_: 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:30mwoelkerrhickey_: but it should be possible to replace the reflection with some asm equivalent?
15:31rhickey_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:32rhickey_mwoelker: yes, something that looks at jars
15:32jlillyrhickey_: I suppose it doens't introduce performance concerns b/c its compiled.
15:32rhickey_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:33rhickey_so it is driving this protocols/datatypes design, which will be a great enhancement to Clojure
15:33drewrrhickey_: wouldn't I still have a hard time writing clojure in C because the interop is so Java-centric?
15:33jlillymy 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:33drewror maybe implementing the language would be feasible, but using it would be quite a different experience
15:34rhickey_drewr: the design presumes some object system a la Java/CLR but JavaScript and Obj-C are also doable
15:34rhickey_making it easy to port to C is a non-objective
15:34rhickey_C being bereft of facilities
15:34drewrok, so C was a bad example
15:35drewrwouldn't the interop on obj-c make it a very different language?
15:35cemerickdrewr: chicken scheme could probably get you to a native executable
15:35rhickey_it really requires very little, and deftype/protocols make it clear how little
15:35cemericknative + cross platform, that is
15:35drewras a trivial example, clojure would need to provide a wrapper around .toUpperCase, right?
15:36drewrnot that it wouldn't be nice to have a clojure string lib
15:36rhickey_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:37rhickey_the whole point of moving to a different host is to leverage that host
15:37rhickey_wrapping all hosts defeats a purpose of Clojure
15:37rhickey_so some core facilities and libs will port, other than that each app should/will touch the platform directly
15:38drewrmakes sense
15:38rhickey_but say a consultant wouldn't have to switch language to move to different client targets
15:39hiredmandmiller is looking at porting contrib to clojureclr
15:39hiredmanwhich will face a lot of .toUpperCase kind of stuff
15:40hiredmanhttp://www.thelastcitadel.com/images/contrib.svg
15:46rhickey_hiredman: comparable facilities are definitely there (especially on CLR) so it's just a matter of encapsulation
15:46hiredmansure
15:47mwoelkerrhickey_: 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:47rhickey_he end result will be core + a substantial portion of contrib will be portable
15:48rhickey_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:48hiredmanheadius there was talk of a "super compiler" at the jvm lang summit
15:48hiredmansaid
15:48rhickey_right, there was talk of that, but it may be hard to generalize
15:49rhickey_especially to any combination of langs
15:50hiredman:/
15:51mwoelkerwhat 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:52hiredmanI know Chousuke was/is running to issues with bootstrapping his cinc reader into clojure
15:52hiredman(I ran into some too when I was messing with it)
15:53hiredmanbut metacicularity makes my head hurt
15:53rhickey_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:54rhickey_there are disciplined ways to ease the pain, rigorous use of interfaces, splitting gen-interfaces into their own files etc
15:55mwoelkerrhickey_: as a newcomer to lisps, I guess I still haven't quite wrapped my head around how powerful macros really are...
15:55rhickey_but the general case is unsolveable as (gen-framework foo) could read a database and expand into anything
15:55cemerickwow, contrib is up to 3.2MB, compiled :-|
15:58mwoelkerrhickey_: 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:59hiredmanthere is a lot in contrib
16:01rhickey_mwoelker: that's not the way a Lisp works.
16:02cemerickindeed. The diagram you linked to earlier is a little staggering. Has anyone put together a linker yet? (for lack of a better term)
16:02stuartsierrarhickey_: And I've written some gen-framework's :)
16:02hiredmancemerick: package manager?
16:02mwoelkerrhickey_: I feared as much. So what else is there? Iterative compilation until a fixed point is reached?
16:03cemerickhiredman: no -- given a top-level, determine ns dependencies, and only package those into the jar, etc.
16:03hiredmanoh
16:04cemerickmwoelker: are you knocking up against layered language dependencies?
16:04rhickey_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:06rhickey_it may be the case that you only need to statically analyze one half (the Java bit)
16:06rhickey_that would ensure Clojure compilation could proceed
16:06technomancywhy does defn support metadata maps in two positions? (before the name vs after the body)
16:06rhickey_then patch and finish Java compilation
16:07rhickey_technomancy: before the name doesn't have anything to do with the syntax of defn, that's just adorning the name
16:07mwoelkerrhickey_: Coming from a more "static" background, I am just afraid this lack of joint compilation might hinder wider acceptance and adoption
16:07technomancyoh, right that's a read-time thing.
16:08rhickey_mwoelker: quite a bit of useful things can be built without circularity
16:08mwoelkerrhickey_: well it wouldn't even have to be circular, just lots of layers of clojure/java/... code
16:09cemerickmwoelker: it's pretty rare for joint compilation to be a hard requirement. The workarounds are generally very straightforward.
16:10mwoelkercemerick: 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:11cemerickmwoelker: 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:12cemerickBeyond 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:12mwoelkerThat 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:13rhickey_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:13cemerickAll 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:14cemerickhybrid*
16:16mwoelkerOkay, that should work. Thanks a lot for your insights and the discussion (and last not least patience). It is much appreciated.
16:16chouserWe 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:17chouserthis is all using cmake which I would not, by the way, recommend. At all.
16:17mwoelkerchouser: wow that sounds like a boatload of fun
16:18chouserheh. yeah.
16:18rhickey_so, no consensus on these: ? http://paste.lisp.org/display/88999
16:18mwoelkerchouser: 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:18chouserI don't think we have any C++ that depends on anything JVM, or anything that depends on the python or jruby.
16:19cemerickchouser: Ouch. Like, ouch. :-/
16:19chouserbut all the rest is pretty mixed up -- jruby that needs java that needs clojure that needs more java and c++
16:19hiredmanreally, I liked datatypes as just containers with no attached methods
16:19rhickey_hiredman: the methods are only if you need to implement interfaces - you can't define any other methods
16:19cemerickhiredman: I think the method impls are totally optional, right rhickey_ ?
16:20rhickey_cemerick: right
16:20cemerickI prefer #3, with the type hinting done automagically.
16:20rhickey_strictly for interfaces, equals/hashCode customization, which must be in class
16:20mwoelkerrhickey_: FWIW I prefer the "autohinted this" version
16:21chouserI guess I have a slight preference for autohinted explicit this.
16:22chouserI 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:22rhickey_geez, you guys have been doing FP for too long :)
16:22hiredmansounds like a quorum
16:23rhickey_think about the poor folks coming from Java, never had to declare this before...
16:23mwoelkerthat would be me I guess
16:23cemerickdoesn't ruby have explicit this?
16:23cemerickobviously, python does, and people manage
16:23chouserpython does
16:23chouseryeah
16:24wtetzneris there a way to give type hints in code that's generated by macros?
16:24hiredmanwell, if python does it, lets do the opposite
16:24cemerickI'm surprised there's no into!
16:24cemerick(yet)
16:24rhickey_ut this is a bridge/interop thing where the interfaces are declared in Java as taking x, not this,x
16:24rhickey_but
16:25cemerickof course, that's just so much sugar :-)
16:25rhickey_into! ?
16:25Chousukehoh
16:25KjellskiHi there =)
16:25Chousukenow I got the size reduced
16:26Chousuketurns out duplicating every object with line metadata added was kind of... bloating the whole thing
16:26Chousukehowever now I have another error :P
16:27Chousukeit'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:27Chousukeand... what? :|
16:28rhickey_how about - if you don't supply this, and call it 'this', then the macro will supply it?
16:28rhickey_user preference
16:29mwoelkermight make it harder to read other people's code...
16:29cemerickjust think of the poor fellow who calls the first argument 'me', but binds 'this' to something else in the impl
16:29cemerickrhickey_: sure, something like (defn into! [tc coll] (reduce conj! tc coll)))
16:30rhickey_cemerick: oh, for transients, but into uses a transient inside already
16:30lpetitI think I also slightly prefer "deftype with interface explicit this".
16:31cgrandrhickey_: how do you know that this is missing when methods are overloaded?
16:31cgrandand I prefer explicit auto-hinted this (no surprise)
16:31lpetit"explicit auto-hinted first arg"
16:32lpetityes really, KISS
16:32lpetitis it me saying that ? :-)
16:33hiredmanChousuke: how did you end up getting around the load being undefined thing
16:33rhickey_cgrand: overloaded by arity will have this in each sig
16:34cemerickrhickey_: oh, I see what's going on. I guess I'll just have to internalize that persistent! and transient are O(1)?
16:35rhickey_cemerick: yes, that's the beautiful thing
16:36hiredmanlisppaste8: url
16:36lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
16:38lisppaste8hiredman pasted "incremental reader replacement" at http://paste.lisp.org/display/89006
16:39hiredmanso 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:44chouserI think I dislike the optional "this" more than I dislike the implicit "this"
16:44danleiyes, I don't like that either
16:45danleia bit too much magic for my taste
16:45chouserI'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:46chouserThere have been a few of each -- I don't think overwhelming either way.
16:46lpetithaving explicit arguments everywhere would seem more FPy and consistent with the rest.
16:47hiredmangen-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:47chouserhiredman: heh. yeah.
16:47lisppaste8rhickey annotated #88999 "deftype explicit this, leaner, cleaner?" at http://paste.lisp.org/display/88999#3
16:48hiredmanlooks like new new
16:49rhickey_with this, a simple struct-like thing can just be (deftype my.Struct a b c)
16:49danleigetting rid of one nesting level ready more clojury for me, at first impression
16:49danleis/ready/reads
16:50chouserrequire all fields before any methods?
16:50danleiI like it
16:51rhickey_chouser: dunno, the way this works it's keying of symbol/seq/key, could be intermixed
16:51rhickey_It present extensibility issues, but the key is an escape hatch for more verbose things
16:51hiredmanI know protocols vs. multimethods was hashed over a lot yesterday, what bout deftype vs. new new
16:52technomancy,((fn [& args] args))
16:52clojurebotnil
16:52technomancyshouldn't that be an empty seq?
16:52hiredman,(empty? nikl)
16:52clojurebotjava.lang.Exception: Unable to resolve symbol: nikl in this context
16:52hiredman,(empty? nil)
16:52clojurebottrue
16:52chousertechnomancy: & is next, not rest
16:52technomancyhiredman: smells like CL to me. =)
16:53rhickey_hiredman: imagine new new becomes a better proxy, access to supers, protected etc, and faster
16:53technomancyI guess I'm just not used to being able to use nil in seq-ish contexts
16:53chouser,[(first nil) (rest nil) (next nil) (filter true? nil) (map inc nil)]
16:53clojurebot[nil () nil () ()]
16:54rhickey_I'd very much like to avoid the verbosity of gen-class with deftype
16:54hiredmanso new new would have the verbosity of gen-class?
16:54rhickey_hiredman: not related
16:54hiredmanhmmm
16:54rhickey_I was referring back to leaner/cleaner
16:54chouserrhickey_: I guess you expect :implements to be less common than an empty [] for interfaces?
16:55rhickey_chouser: I guess
16:55chouserhm, nm. Even if more common I think I like the explicitness
16:55rhickey_of coure then implementing a protocol should get a different name
16:55rhickey_course
16:56chouserconsidering when used in pure native clojure code, you won't need interfaces -- protocols go on top of deftype, not the other way around.
16:56lpetitrhickey: 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:56rhickey_chouser: right
16:56chouserso yes, I think leaner explicit this is the best yet
16:57liebkerhickey_: I like the explicitness of :implements, but my code uses keywords everywhere, so I'm biased :)
16:57chouserIt would be nice if field names were less obscured by their metadata, but I don't know what to do about that.
16:57rhickey_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:58cemerickrhickey_: it would be nice to be able to say (-> [] transient some-fn other-fn (into (get-data)) last-fn persistent!), etc.
16:58cemerickmake that into!, of course
16:59rhickey_cemerick: I'm not opposed
17:00cemerickOK, I'll tinker some more and see if it's really warranted. I'll file a ticket w/ patch based on that.
17:02rhickey_chouser: yes, we'd talked here about ethel^int in the past, post deprecating ^
17:03rhickey_actually that wouldn't have to wait, presuming no one depends upon ^ being non-constituent
17:04danleirhickey_: if something is a field or method implementation would be decided by whether it's a symbol vs. seq in leaner deftype, right?
17:04rhickey_danlei: yes
17:05rhickey_trailing symbol meta?? name^{:tag String :alias :foaf:name}
17:05rhickey_ethel^int, foo^String
17:06liebkeI like the trailing metadata, it's seems clearer to me
17:07lpetitrhickey: 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:08lpetityes, first introducing the thing, then the metadata to the thing, sounds good
17:08chouserleaner explicit this combined with trailing symbol meta would look quite nice indeed.
17:09chouserall the member names would line up along the left, starting with a paren for methods.
17:09rhickey_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:11lisppaste8rhickey annotated #88999 "deftype explicit this, leaner, meta trailing" at http://paste.lisp.org/display/88999#4
17:11danleihow about allowing symbols and lists as fields, like this (deftype foo [bar int] ...)?
17:11danleis/list/vector
17:11lpetitrhickey_: 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:11lpetitto add an attribute, I meant
17:12rhickey_danlei: metadata on symbols has a lot of advantages for flowing through macros, and is used everywhere else
17:12chousera bit OT, but evaluation order of things in {} and #{} are undefined, right?
17:13rhickey_chouser: probably unspecified
17:13rhickey_lpetit: it's interesting
17:15lpetitrhickey_: 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:18hiredmanare def'ed types going to implement one of the meta interfaces by default?
17:18hiredmaner
17:18hiredmandatatypes
17:18rhickey_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:19rhickey_hiredman: yes, will get auto meta and with-meta support
17:21lpetitrhickey_: 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:21rhickey_lpetit: I think it could work, and could inform both equals and hashCode - good idea!
17:22lpetitrhickey_: 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:22rhickey_there's System/identityHashCode
17:23rhickey_arrays are tricky, since you might need to further specify for their contents...
17:24lpetitrhickey: yes, I see java.utils.Array has hashCode functions for arrays of primitive types, and a deepHashcode for arrays of Object types
17:25rhickey_^{:equals :identity|:ignore|[]}, with [] possibly containing nested spec?
17:26rhickey_I guess you'd never have nested :ignore, and nested :identity might be rare as well
17:26rhickey_so many broken equals in the world though
17:27lpetitrhickey_: but for arrays the problem seems to still be symmetric for equals and hashCode in java.utils.Arrays : deepHashcode()/deepEquals(), hashCode()/equals()
17:27rhickey_could have nested arrays
17:27rhickey_lpetit: right, but we have overrides and will need them for array contents too
17:28lpetitrhickey_: "we have overrides" ? I'm not following you here
17:29rhickey_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:29serp_java supports method overloading where the arguments determine what method to call... does clojure?
17:29rhickey_deep* hardwire defaults
17:30rhickey_serp_: Clojure has multimethods for such overloading
17:30serp_I see
17:30rhickey_serp_: but not type overloading within fn
17:30hiredman~multimethods
17:30clojurebotmultimethods is what separates the boys from the men.
17:30rhickey_generally considered evil
17:30hiredmanclojurebot: cute, but not useful
17:30clojurebotTitim gan éirí ort.
17:30rhickey_(type overloading)
17:31rhickey_certainly an interop mightmare
17:31rhickey_nightmare
17:31serp_I don't know what multimethods are =(
17:32hiredmanhttp://clojure.org/multimethods
17:33serp_hiredman: thx
17:36lpetitrhickey_: ^{:equals :identity|:ignore|[]} with [] only relevant for arrays I guess (not a way to a la carte redefine equality semantics of arbitrary datatypes ;-) ? )
17:37rhickey_lpetit: right [] for arrays, useful in that it can contain another [] or :identity
17:39lpetitrhickey_: 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:40rhickey_defaulting to deepEquals for arrays would be a break with = for arrays, which right now is identity as is anyarray.equals
17:40rhickey_but I want deftype to be "right" for immutable by default, so maybe could do deepEquals for arrays
17:41lpetitrhickey_: java.utils.Arrays has both Arrays.equals() and Arrays.deepEquals(), even for Object[]
17:41rhickey_I agree about equals/hash, but they are supposed to agree
17:42lpetitrhickey_: yes, forget, :equals does the job well
17:43rhickey_lpetit: deep just handles nesting, which you would want
17:43rhickey_if the default was deepEquals for arrays, I think we could just do with :ignore and :identity
17:44lpetitrhickey_ : 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:44rhickey_lpetit: then they will flag the array field with :identity
17:45lpetitrhickey_ : oh yes you're right :)
17:47lpetitrhickey_: 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:48rhickey_lpetit: no, they differ only for nested AFAICT, and I can't see equals for nested
17:49rhickey_you wouldn't be able to reach into any Clojure composite like that either
17:49lpetitrhickey_: Arrays.deepEquals(Object[])
17:50lpetitrhickey_: ok I've reached my incompetence level here, but I think we've almost closed the deal, haven't we ? :)
17:51rhickey_http://java.sun.com/j2se/1.5.0/docs/api/java/util/Arrays.html#deepEquals(java.lang.Object[],%20java.lang.Object[])
17:52rhickey_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:54lpetitrhickey_: 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:55Chousuke*sigh*
17:55rhickey_lpetit: thanks for the input!
17:55lpetitChousuke : grmlml :)
17:56ChousukeI'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:56ChousukeI can't convince Clojure to recompile them even though they're already loaded :/
17:58hiredman:(
17:58divrhickey_: I assume that any :equals annotations would be overridden when an actual equals implementation is provided ?
17:58Chousukeand 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:58hiredmanI have the urge to go home and traipse through src/clojure/lang for the rest of the day
18:00ChousukeI think I will need to rip open RT.java and add some kind of a "recompile" function to it.
18:00rhickey_div: yes, just ignored
18:00divok, makes sense
18:00hiredmanChousuke: have you, uh, touch'ed the files you want to recompile?
18:01hiredmanhttp://ant.apache.org/manual/CoreTasks/touch.html
18:01lpetitdiv: so that IDE devs can add a layer of warnings not provided by the compiler :-p
18:02divlpetit: yes, a simple warning can go a long way :)
18:02lpetitI hope ccw was so advanced that I could start doing such added value stuff. Alas ...
18:03Chousukehiredman: I can't do that, since then it won't load the class files before trying to recompile them :P
18:03hiredmanhmmmmmm
18:04Chousukehiredman: 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:05Chousukebut the thing is, it won't recompile clojure.core or clojure.lang.reader because they're already loaded :P
18:06Chousukeand if I override that check, it'll *always* recompile all the dependencies... and my head hurts
18:08hiredmannice
18:09Chousukeoh, and there's more.
18:10ChousukeI 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:10Licenserhmm hmm, I
18:11LicenserI've alist like (([1 2] [1 2]) ([1 2] [1 2])) how can I 'flatten' that?
18:11hiredman,(doc flatten)
18:11clojurebot"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:12Licenserthat is too easy darn
18:15travisbradyDoes anyone have thoughts on what concerns would govern the decision to learn Clojure over Scala or vice versa?
18:16Chousukesyntax. :)
18:16somnium~scala
18:17hiredman~tell me about scala
18:17clojurebot{((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}
18:18hiredman~scala {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}
18:18clojurebotAny = 1
18:28rhickey_updated to reflect today's discussion: http://www.assembla.com/wiki/show/clojure/Datatypes
18:28rhickey_need a new name for implement in protocols?
18:31LicenserI'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:31LicenserI
18:32LicenserI'm sure there is some super easy and cool way to do that which I don't know about
18:32Chousukeapply
18:32liebkeLicenser: (apply fun '([1 2] [3 4]))
18:32Licenseryou are my heros!
18:33Licenserthank you a lot
18:33travisbradyhiredman: haha, ok, fair enough. I'm thinking more like "Clojure is really good at X" types of things
18:34travisbradybut thank you still, i agree Scala syntax can be really ugly
18:34danleirhickey_: what does the "under any name?" wrt this mean? whether other designators may be chosen?
18:36technomancytravisbrady: 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:36travisbradytechnomancy: ahh, that's helpful actually.
18:37travisbradyI've never used a lisp previously, so I'm leaning toward Clojure
18:37technomancytravisbrady: also keep in mind that you can read the entire implementation of Clojure in a day or two.
18:37danleitravisbrady: I don't know anything about scale, but are data = code and vice versa? if not, I'd consider it a drawback.
18:37ambientthis 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:42danleitravisbrady: 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:43travisbradywow, 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:44travisbradyis there anything like sbt for clojure to simplify building and such?
18:44danleiyou could also write imperative code very well with common-lisp
18:44danleiand with abcl even on the jvm
18:45danleiif you *want* to write imperative code, of course
18:46Chousuketechnomancy: entire implementation excluding the icky java parts, right? :P
18:47cgrandambient: you must fully hint aset
18:47hiredmanof course
18:47cgrandambient: (aset #^doubles a (int i) (double j))
18:47hiredmanI don't think the java parts are that horrible
18:47ambientcgrand sorry, i just figured out i was giving the function wrong parameters
18:48technomancyChousuke: if you leave out Java it's hours, not days. =)
18:48Chousukehiredman: it's not horrible, for java code :P
18:51hiredmanit's kind of intimidating, but once you start fitzing with it, it starts to look like clojure code with a lot of noise
18:52ChousukeLispReader is a good example
18:52hiredmanyeah, all those AFns
18:53Chousukeit's got the same basic idea as my clojure reader... only, it's in java and mine is in clojure :P
18:53licoresseis someone working on proper error output from clojure compile messages?
18:53licoresse(slime)
18:53Chousukeprobably not.
18:53licoressehm
18:53technomancysomeone was talking about hooking it into the rubinius-style backtrace lib
18:54ChousukeI don't think anyone wants to work on the compiler too much at this point.
18:54Chousukebecause it'll eventually get redone anyway
18:54licoresseany thoughts on how?
18:54Chousukesome simple things could be done though
18:55Chousukefor example, the no matching method errors should print the expected parameter types too :P
18:56hiredmanthe tapestry guy (hslip?) hade some kind of clojure stacktrace thing
18:56hiredmanhttp://tapestryjava.blogspot.com/2009/10/cascade-exception-reporting.html
18:57hiredmanhlship
19:04somniumit looks like a slime stacktrace with css
19:05hiredmanI assumed you where complaining about the pages of java exceptions
19:07somniumah, the second picture is nice, slime doesn't do that yet (obfuscate the java internals)
19:07technomancyit does dim them though
19:13rhickey_danlei: yes, arbitrary name for this
19:15danleirhickey_: well, when using explicit this, why would one not allow arbitrary designators?
19:16rhickey_danlei: right, just wanted to be clear you have to add an arg for 'this', whatever you call it
19:16danleirhickey_: ok, thanks (just wasn't clear to me)
19:17rhickey_danlei: well, it might not yet be clear :) those are just notes, not docs
19:17danleirhickey_: yeah, I'm aware of that :)
19:18danleiit was just the formulation which confused me
19:30mikehincheyI submitted a patch to clojure.stacktrace to get it closer to clj syntax
19:32peregrine81Hey all I am doing eulers project again and I
19:32technomancyone of these days I'm going to go through the submitted patches, try them out, and +1 the ones that look good
19:32peregrine81m trying to find the Least Common demonator for 1-20. and it seemingly runs forever.. here is the gist
19:32peregrine81http://gist.github.com/214717
19:32technomancysince it sounds more productive than complaining that my patches take too long to get applied. =)
19:33danlei:)
19:33peregrine81I had a really elegant solution with regular recursion but kept getting stack overflows
19:36mikehincheytechnomancy: 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:37technomancymikehinchey: I'll vote for your patches if you vote for mine. =)
19:38technomancyI think it's more about just QAing them so when rich does get to them the problematic ones are already sorted out.
19:44The-Kennyperegrine81: 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:44mikehincheytechnomancy: yes, I might create a branch with a bunch of patches to make sure they apply cleanly and tests pass
19:44technomancyeven patches that were once good can succumb to bitrot.
19:44peregrine81The-Kenny: this solution runs without stack issues, but it just never finds an answer
19:46tomojyour current solution doesn't make any sense at all to me
19:46mikehincheyexactly
19:49peregrine81tomoj: why not?
19:49peregrine81oops sorry I will be back in 20
20:07peregrin181alright I am back
20:10peregrin181alright 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:13peregrin181I 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:15danleiwithout any mathematical knowledge on my side, I'd write something like this:
20:15danlei(which might be spoilery)
20:15danlei(defn find-divisible [r]
20:15danlei (first (drop-while (fn [n] (not (every? #(zero? (rem n %)) r))) (iterate inc 1))))
20:16tomojthat's probably very slow
20:16danleiwell possible, yes
20:16danleibut how fast must it be?
20:16danleiit solves the task fine
20:16tomojoh, euler doesn't care
20:17danlei"Elapsed time: 128.06173 msecs"
20:17danleinot fastest, but fast enough for my neurons .)
20:17tomojmuch faster than I thought
20:17danlei1-10
20:18danleishould explode
20:19tomojah, yes, 1-20 is not so fast :)
20:19danleiyes, I'm waiting :D
20:19tomojI think when I did that one I prime-factorized
20:20tomoji.e. factor each of 1-20 into a map of primes->multiplicities, and then merge with max, and then multiply the result up
20:27peregrin181tomoj: I'm sorry I don't understand
20:28peregrin181tomoj: I will need to study this closer
20:28tomojwait, I think what I described was something else
20:28peregrin181tomoj: Why doesn't mine work?
20:28tomojno, no it wasn't
20:28tomojI still have no idea what your code is trying to do, sorry :(
20:29tomojI mean I know what it's trying to do, but I have no idea how it's trying to do it
20:29peregrin181I 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:30tomojah, I see
20:30tomojyes, this takes a very long time because it's a big number, I think
20:30danleicombinatorical explosion, just like my snippet
20:30tomoj1-10 is easy so you haven't saved much work
20:30peregrin181danlei: I mean I don't understand yours :)
20:31danleiperegrin181: what exactly don't you understand?
20:31peregrin181danlei: Any of it. I am very green in the world of Clojure/lisps
20:31danleiperegrin181: I'll explain, but it's slow, as tomoj said
20:32peregrin181danlei: other then anonymous function and functions
20:32danlei(defn find-divisible [r]
20:32danlei (first (drop-while (fn [n] (not (every? #(zero? (rem n %)) r))) (iterate inc 1))))
20:32danleistart from the every?
20:32danleievery? returns true if a given predicate holds for all elements of a seq
20:33danleiso the every? will return true, if all (rem n %) are true for the values in r, which is a range
20:33danlei(the range ist the argument to find-divisible)
20:33peregrin181so [1-20]
20:34danleidrop while drops everything while a predicate is true
20:34danleiyou get the picture?
20:34peregrin181what is the iterate inc 1
20:34danleiyes, (range 1 21)
20:34danleiits all numbers starting from 1
20:34danleialso a range, but an open interval
20:35peregrin181so it returns to the top
20:35danleiso it drops all of those numbers (of the open interval)
20:35danleiand the first just picks the first available, which will be your result
20:36danleidrops all for which the (fn [n] ... is true
20:36peregrin181thank you. I am still not 100% clear but I think I get it
20:36peregrin181the #( means anonymous fn correct?
20:36danleiI'm not good at explaining :)
20:36danleiyes, its sugar for fn, binds % and stuff implicitly
20:37danleiand to show you how slow it really is:
20:37danlei"Elapsed time: 985956.807695 msecs"
20:37danlei:)
20:38peregrin181still faster than running forever
20:38danleibtw. theres also not-every?
20:39danleiyes it does the job, eventually ;)
20:39peregrin181danlei thanks
20:39danleibut it's a very naive approach
20:39danleiyou're welcome
20:40peregrin181far less naive then mine
20:40peregrin181I'm trying to code in C#/Java in Clojure
20:41danleiwell, I don't know any C# and almost no Java, so I have it a bit easier ;)
20:41peregrin181danlei: did you learn in lisp?
20:41danleiyes, 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:42peregrin181danlei: cool
20:42danleiatm, I'm at university (despite of my age), and that will change soon, but well ...
20:42peregrin181why do you think my code takes so long?
20:42danleithe good thing is: my university is pretty lisp-friendly :)
20:43danleiand I don't study cs but computational linguitics, but that's another topic
20:43peregrin181I did nearly the same thing you did(with loops)
20:43danleiI really didn't understand how you approached it, I didn't spend much time reading your code, to be honest
20:44danleia general tip is: always check if it simplifies and terminates
20:45danlei(i.e.: if your base-case is ever reached)
20:46tomojok, my prime-factorizing version can do 1-20 in 5ms :)
20:46danlei:p
20:46tomojand my factoring algorithm is really dumb
20:46danleiI just waited for it, tomoj ;)
20:47tomojhow long did it take?
20:47tomojalso, cool re compling, I'm taking an intro compling class now
20:47tomojI really want to rewrite nltk in clojure because python makes me sad
20:48danlei"Elapsed time: 985956.807695 msecs" :)
20:49danleiI'm just at the start right now, much "traditional" linguistics atm, the basics
20:49danleidesaussure &al
20:50tomojhere's my version (spoiler, of course): http://gist.github.com/214752
20:50danlei*de saussure
20:53tomojso the answer is in the hundreds of millions, I can see why the naive way takes so long
20:54peregrin181tomoj: my way
20:54peregrin181?
20:56tomojthe way that counts upwards and checks for each number whether all the numbers in the list divide it
20:56tomojall the hard work of my way is prime-factorizing, and though my factorizer seems slow, you only have to factor 2-20, so
20:57tomojI wonder how long the naive way takes to get 1-30
20:58tomojor 1-300 :)
20:58peregrin181tomoj: mine prolly takes forever
20:59danleiwould sure be a workout for my fan :)
20:59tomojI can get 1-300 in just over a second
20:59peregrin181tomoj: Yea the way of finding the roots is far better
21:00tomojit disturbs me that I don't know how to factor quickly
21:02danleitomoj: do you speak common lisp?
21:03peregrin181tomoj: I'm not very good at math
21:03peregrin181lol
21:04tomojdanlei: a little, not much
21:04danleiI haven't done euler for a long time
21:04danleibut I have alittle factorizer here
21:04danleisec
21:05lisppaste8danlei pasted "factorization" at http://paste.lisp.org/display/89018
21:06danleiit's not stuff I usually do much, but it worked and was fast enough for my needs
21:06peregrin181is this cl?
21:06miltonsilvahi, does anyone know(has experience) how clojure scale to huge project? (specificly the ones that seem more OO)
21:06danleiyes
21:06danleiI started doing euler in CL, havent come around to do some of it in clojure
21:07peregrin181danlei: I wasn't a fan of CL
21:08danleiI like it pretty much :)
21:08danleiclojure, too. I like both of them
21:08danleiwhat didn't you like?
21:08somniumweblocks is cool
21:08danleinever used it, just hunchentoot
21:08danleibut I heard good things about it
21:08somniumI 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:08peregrin181danlei: CL seemed poorly documented, too many different implementations, little tool support(outside of emacs)
21:09peregrin181danlei: poor libs
21:09danleiperegrin181: oh. I'd /very/ strongly disagree about poorly documented
21:09somniumand all the 'serious' implementations cost a fortune
21:09peregrin181danlei: thats probably true
21:09somniumfor a hobby programmer anyway, they're supposed to have better libs though
21:10danleiwell the thing is, cffi is there and it's pretty easy to use
21:10danleiit's like clojure uses java as it's low-level and implementation language
21:10tomojCLHS is poor documentation?
21:10danleiand the things I don't like about clojure are mostly stuff where java sticks out
21:10danleiso, well
21:10arbschttoo many implementations? the number of java implementations is in the same order of magnitude
21:11danleiI don't know, all this has never been an issue for me
21:11peregrin181danlei: thats true. But at least I can use one of the java libs
21:11danleiyes, like you can use all C libs from lisp ;)
21:11The-Kenn1I really miss clos... method combination and such things.
21:11somniumarbscht: sun, openjdk, and ibm? there are more?
21:11arbschtsomnium: a lot more
21:11peregrin181danlei: I really tried to like it :)
21:11danleiI know what you mean, but I didn't suffer very much
21:11tomojdanlei: that looks like basically what my clojure does
21:11tomojexcept I'm using multiplicity representation
21:11danleiI like clojure for being a modern lisp, which is moving, living and trying to be "better"
21:12danleithat's what makes it great (to me)
21:12peregrin181danlei: ding ding :)
21:12arbschtsomnium: SE5, SE6, EE4, EE5 (GlassFish, JBoss, Geronimo, WebLogic ...), ME, FX, OpenJDK, GIJ/GCJ, ECJ, Harmony, Dalvik, JRockI
21:12arbschtt
21:12peregrin181arbscht: But real people use JRE :P and Dalvik only runs on android
21:13arbschtperegrin181: I'm sure you could make such arguments for some CL implementations
21:13danleitomoj: I had no problems with it's speed ... or was that just hypothetical?
21:13danleiperegrin181: there are also things that are very nice about cl, like the condition system for example
21:14danleiperegrin181: it's not black and white, I think both langs have much to offer
21:14peregrin181danlei: And I agree I wasn't trying to anger
21:14tomojdanlei: e.g. factorizing 53573153 takes 13 seconds for me
21:14danleiperegrin181: you don't :)
21:14danleitomoj: a sec
21:14tomojbecause it's got two big prime factors, and searching upwards for the next prime isn't very efficient, I think
21:15danleitomoj: (FACTORIZE 53573153) took 16 milliseconds (0.016 seconds) to run
21:15danlei with 2 available CPU cores.
21:15danleiDuring that period, 16 milliseconds (0.016 seconds) were spent in user mode
21:15danlei 0 milliseconds (0.000 seconds) were spent in system mode
21:15danlei 1,384 bytes of memory allocated.
21:15danlei
21:15danleiah, sorry for the mess
21:15tomojyou 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:15peregrin181danlei: how did you get that data?
21:15tomojchecking primality is a waste of time
21:15danleitomoj: so, the CL version is pretty fast actually
21:16danleiperegrin181: thats ccl's TIME
21:16peregrin181danlei ah
21:16tomojI wonder why it's so much faster
21:16peregrin181tomoj: probably something to do with lazy evaluation
21:16peregrin181tomoj: Pure guess
21:16danleiI can't tell you :)
21:16danleiI'm no expert with this, just wrote it some time ago
21:17tomojwow, skipping the primality check sped my code up 32x
21:17tomoj1-20 in 1.5ms now
21:18danleiI guess I could even squeeze more performance out of the cl version if I declared types
21:19tomojdanlei: why are you checking for primality?
21:19danlei(time (factorize 1234321234213243)) -> 141ms
21:19tomojget rid of the prime check, I bet you'll get the same answers and a lot faster
21:19danleia moment
21:20tomojbecause 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:20danleidoesn't really make a difference in runtime, but you're right
21:20tomojwat? that doesn't make any sense
21:21tomojI got a 32x speedup...
21:21danleiwell:
21:21danlei141ms, just like before
21:21tomojoh, I was checking for primality by going from 2 to n-1
21:21tomojinstead of sqrt(n)
21:21tomojthat probably slowed me down a lot :(
21:22danleiyes, sounds so
21:23tomojok, now factorizing 1234321234213243 takes me 739ms, that sounds more reasonable as attributable to naive clojure overhea
21:23danleiyes, it does
21:24danleiI also tried to squeeze some performance out of it with type declarations, but it wasn't worth it
21:24danleiaround 140ms
21:26danleibut I'm asking myself why I put the primep in there anyway ...
21:26tomojI don't think type hinting would really help me any.. maybe I can avoid boxing though? I dunno how to speed clojure up
21:26tomojwell, I put one in there at first too :)
21:26danlei:)
21:27tomojit seems like a waste to check numbers which can't possibly divide the accumulator because you've already factored out all their factors
21:27tomojbut I guess it's actually faster to do this than to make sure you're only checking primes
21:27danleianyway, it's 3:30 over here, and I'll call it a night :)
22:05Licenserhrm, I
22:05Licenserv
22:05Licenserargh - sorry
22:05LicenserI've a very odd behaviour with a funciton, it claims to have the wrong number of arguments - but it shouldn't
22:05Licenserhttp://www.pastebin.cz/24489 <- is the code + example + error.
22:05LicenserIs that a bug or am I just plain stupid
22:06Licenserlikely it's the second but well I'm working on it for one houre and don't see what's wrong o.o
22:09Licenserthanks, I am just plain stupid, I found the bug - had a argument too much in an anon function :/
22:18brweber2can anyone help me create an exception class that only has a constructor that takes a string parameter?
22:25liebkeLicenser: remove the formater argument from the anonymous function you're passing to map: (map (fn [row] (table-row row formater)) data)
22:26Licenserliebke: 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:26liebke:)
22:27LicenserI was looking at the make-table function thinking I'd passed it the wrong number of arguments o.O
22:30eyerisI 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:31Licensereyeris: does the nailgun reply have a display to draw on?
22:31eyerisLicenser: it should, because DISPLAY is set.
22:31eyerisI guess maybe it is dropping the environment?
22:31LicenserI don
22:31LicenserI don't know it would just be my first guess
22:42eyerisI just made NGServer dump it's environment when it starts and when it exits. DISPLAY is set at both times.
22:42eyerisGood idea though :)
22:49eyerisIn vimclojure's repl, how do I evaluate what I type?
22:49eyerisWhen I type in clojure code and hit enter, nothing is printed out
23:25technomancywhy does test_clojure/logic.clj test to see that (symbol "") is true?