#clojure logs

2008-11-09

00:12albinoHas anyone created a duplicate of the api page with examples of each thing listed?
00:13duck1123can anyone point to any code that makes heavy use of regex?
00:13duck1123albino: afaik, no
00:14albinoI do so much better with examples
00:14albinoand grepping the code for them isn't as fast
00:39_skhi all, is let equivalent to binding?
04:21bagglessave me
06:02Lau_of_DKIs anyone here in possion of some basic Jetty skills ?
06:03Lau_of_DKLets say Im located in /x/y/z/jetty and wish to make /x/y/z/jetty/webapps/proj1 the default page to be displayed when my IP is accessed, I would imagine that I launch Jetty with this command 'java -Djetty.home=/x/y/z/jetty/webapps/proj1 -jar start.jar', but this does not seem to be the case
06:03tWipDo you mean Jetty spesific or servlet skills?
06:03Lau_of_DKWhere do I go wrong ?=
06:04tWipno I think jetty home must be the root of jetty, it does not denote a "default" web app to run
06:05Lau_of_DKUnderstood
06:07tWipyou need to put your app with name root.war or a directory called root
06:08tWipthat should deploy it to / context path
06:08tWipat least that's what my webapps/README.TXT says
06:10leafwback
06:10Lau_of_DKYes you are quite right. I did not gain that same understanding from the README, but thank you, its working now
06:10baggleshas anyone had much success making applets with clojure?
06:11bagglesi had a search through the mailing list subjects ... but the only message i found was mine in ... march or february
06:11leafwbaggles: what is the problem? Can see why it shouldn't work just fine
06:11bagglescreateClassLoader permissions.
06:11leafwbaggles: sorry, no idea about that method.
06:12bagglesmaybe i'll go back and try again
06:12tWipI think you will need the AllPermission for your codebase
06:12tWipto create class loaders
06:13baggleswell, afaik clojure needs that, and making just a random applet for the web, you don't get those permissions
06:14bagglesbut it's been a while since i've tried, so i might just be blathering
06:14tWipthe client needs to grant that policy, or you need to sign your applet jar
06:15Lau_of_DKAre there any blogs available, which talk about Clojure webapps, servlets, Comets, etc. ?
06:16bagglesheh
06:16baggleswhen i put "clojure applet" into google, i just get a link to a post i made on the mailing list
06:17tWipAOT compilation should solve your classloader problems, but that's not done yet I think
06:17bagglesaot?
06:17tWipahead of time
06:17Lau_of_DKtWip, there is so much talk about AOT nowadays, do you have a link whereby I can educate myself on AOT and its relation to Clojure?
06:18bagglesoh. as in: removing the compiler from clojure and just having byte code.
06:18bagglesto be honest, i just want a language that is fairly close to java that i can write macros for.
06:19tWipI don't really know enough about the AOT spesifics in Clojure to say more on the matter :P
06:27FandaRich is currently working on AOT
06:27Fandahttp://richhickey.backpackit.com/pub/1597914
06:27Fandathere is a relation with genclass, which is not resolved yet, I guess
06:27Fandait could simplify things
06:28baggleshm.
06:29bagglesi have some vague notion with respect to java about having a thread with different permissions
06:33bagglesi wonder how long it would take me to write a set of common lisp macros that just dumped java source code out.
06:36tWipbaggles, like linj?
06:36baggleslike that
06:37bagglesi was thinking of something closer to java syntax itself, but that looks good
06:37bagglesi mean not syntax, but nomenclature
06:37bagglesjava, lispified
06:37bagglesoh wait the website is broken
06:38baggles:(
07:22Lau_of_DKCan anybody here provide some insight, into how I will make Jetty load a Clojure-file when presenting pages?
07:24tWipLau_of_DK: so are you doing from scratch?
07:24tWipnot using webjure or compojure that is
07:24Lau_of_DKYes, I've just installed Jetty and is looking to integrate Clojure from scratch - If there is much to be gained from forking those projects, I'll be happy to do so
07:25Lau_of_DKI would just like to begin with some understanding of the underlying logic
07:25tWipyou need to make a servlet
07:25tWipthat is the basic unit of java web programming
07:26tWipon the other hand, if you are comfortable with being married to jetty, you can use its embedding system directly and define handlers
07:27Lau_of_DKAssuming that I dont fork any existing project?
07:27tWipI don't know why you would need to fork anything just to use it
07:28tWipbut you are ofcourse welcome to do so
07:30Lau_of_DKI will probably need to extend certain features to match the needs of my projects, thus effectively making it a fork, at least as I have understood the term
07:32tWipwell if they are good features, you could contribute them back
07:32tWipbut gotta go now
07:33Lau_of_DKOk, thank you for your input
07:37duck1123Lau_of_DK: if you are starting from scratch, you might want to look into using Tomcat or something similar as opposed to Jetty
07:38Lau_of_DKFor what reason ?
07:38duck1123Jetty's good if you want something lightweight, but Tomcat will give you more features
07:38Lau_of_DKAlright, I'll have to look into it
07:38Lau_of_DKduck1123, how much have you accomplished on your compojure project ?
07:39duck1123also, I'm secretly hoping you solve the tomcat/clojure issue so I can steal it for my own use :)
07:39Lau_of_DKHaha
07:39Lau_of_DKThe secrets out my friend
07:39duck1123not much. The wife and I played Guitar Hero last night, and I don't get much time durring the week
07:40duck1123I was about to make some coffee and get back to work
07:40Lau_of_DKI'll rephrase. If I adopted your project, what features would that give me to start out with ?
07:42Lau_of_DK(I'm gittin' it as we speak)
07:43duck1123unless you want exactly what I'm doing, go with weavejester's instead
07:43Lau_of_DKAlright
07:44duck1123although I have basic RESTful interaction with a mysql database, OpenID authentication, registration, and operations on a RDF model with Jena
07:45duck1123if you want any of those, you could steal them from my project
07:45Lau_of_DKWell I thank you for the invitation, I'd like to look into your Mysql Interop actually
07:48duck1123also, if you want, there's a Compojure group on google groups
07:50Lau_of_DKGreat, I'll sign up
08:09Lau_of_DKIf I remember correctly, I used to be able to use this approach (in-ns 'myutils :uses 'clojure), but this has been removed. Is anybody aware of how I would do this nowadays?
08:23kotarakLau_of_DK: (ns myutils :refer-clojure :use (some.stuff a b) :require [clojure.zip :as zip] :import (some.other Class)), rough summary (:refer-clojure is optional)
08:23Lau_of_DKThanks alto
08:23Lau_of_DKalot
08:24kotarakoops. () missing around :use ... and :require ... and :import ...
08:24kotarakand :refer-clojure also.
08:25kotarakLau_of_DK: (ns myutils (:refer-clojure) (:use (some.stuff a b)) (:require [clojure.zip :as zip]) (:import (some.other Class))), corrected
08:26Lau_of_DKThanks
08:38Lau_of_DKIn working with Compojure it seems that when you update a .clj file, in order to see the change you need to restart the server - Is this correct?
09:43cpc26anyone having trouble with this mornings build?
09:45duck1123I think the build is still unstable
09:45duck1123Rich is working on AOT
09:46duck1123the past few commits have been labeled "DO NOT USE"
09:47cpc26thanks!
09:48duck1123np
09:52duck1123Does anyone know if java regex supports lookaround?
09:53duck1123I'm thinking it doesn't but I haven't been able to find anything that says one way or another
10:06Chousukeduck1123: the doc for Pattern says it does
10:06Chousukehttp://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html and search for lookahead
10:09duck1123thanks
10:10duck1123I don't know why my query didn't work before, but it does now
10:24MattBowenHi all. I'm trying to use Clojure from svn, but I'm getting an exception. I did a checkout of r1092, ran mvn install, and added clojure-lang-1.0-SNAPSHOT.jar to my classpath, but I get this when I try "java clojure.lang.Repl": http://paste.lisp.org/display/70014
10:24Chousukeuse r1088
10:25duck1123svn clojure is unstable atm
10:25duck1123does anyone know what this might mean? cannot load '/view/entry/entry.clj' again while it is loading
10:26MattBowenChousuke: thank you much
11:41Carkhum ...how to get a sequence from a java Enumeration ?
11:42kotarakDoes it implement Iterable? Then (seq ...)
11:42Carklooks like it doesn't =/
11:43Carkdamn that's almost the same interface Iterable and Enumeration
11:46Carkah : (enumeration-seq enum)
11:57Chouserkotarak: if you specify no options to (:refer-clojure) you can just leave it out.
11:57kotarakChouser: I think I wrote, that it's optional.
11:58Chouseroh, ok. sorry.
11:58kotaraknp
11:58kotarakChouser: I should have mentioned the options, though...
12:09AWizzArdMoin
12:24Chouserwriting is hard. I've started writing a blog entry on how to write a somewhat complicated macro. Does anyone think that's worth finishing?
12:25kotarakChouser: I think so. I understand that this is some kind of step-by-step guide how you created the macro? Something like that is certainly interesting for someone new to macros.
12:26kotarakChouser: I tried to give something like this on the wiki. But well... It's a rather cheesy chapter.
12:26Chouseryeah, that's what it is. ok, I'll keep at it. Thanks for the encouragement. :-)
12:27kotarakChouser: pure egoism. It's always good to look for some new technique for the own toolbox. ;)
12:27AWizzArdlet us know when it is done
12:30Chouserwell, me asking for encouragement is a bit egoist as well. Or something -- insecurity.
12:32ChousukeI think macro writing is still somewhat of an wizardly skill.
12:33Chousukethere's not that much material on it and whatever we have is not exactly easy...
12:33leafwChousuke: ?? macro writing is just abstracting a function
12:33leafwChousuke: see this example, which walks you through it: http://pacific.mpi-cbg.de/cgi-bin/gitweb.cgi?p=fiji.git;a=blob;f=plugins/Examples/Multithreaded_Image_Processing.clj;hb=HEAD
12:33Chousukeyeah but what are good techniques to use when writing a macro? how to choose when to write a macro? etc.
12:34leafw(or see it linked here: http://pacific.mpi-cbg.de/wiki/index.php/Clojure_Scripting#Example_Clojure_plugins_included_in_Fiji )
12:34leafwin my experience, one writes a macro when in need of abstracting a common set of similar functions. The same way that a function abstracts a common set of code blocks.
12:35kotarakChouser: do you need control over the evaluation of the arguments => macro, otherwise => function is a rough guideline.
12:35kotarakOpps
12:35kotarakI meant Chousuke sorry.
12:36Chousukewell, yeah
12:37kotarakChousuke: http://en.wikibooks.org/wiki/Clojure_Programming#Macros, scroll down a bit, the example with with-open-file is pattern, which I find reoccurring.
12:38ChousukeI know macros can be used to abstract away patterns, but that still doesn't tell much about what are good, general techniques to use when *writing* macros
12:38Chousukelike, using helper functions that return forms.
12:39leafwChousuke: as many as macro writers ... although general guidelines: use gensym (or name# as shortcut) always!
12:40Chousukeeven if you say that, to a beginner it's not evident *why* one should do that :)
12:40Chouserthis is helpful, guys. Keep it up.
12:41leafwChousuke: gigamonkeys lisp tutorial has some advice to give on macro writing. Same for every other lisp book out there.
12:41leafwChouser: ?
12:41kotarakChousuke: I tried to explain the effects of not using gensym with a bad example in the wiki link above.
12:41Chousukeit avoids capturing names, but it's easy to get confused with macros about when you want a symbol and when you want the value named by that symbol
12:42kotarakChousuke: it the same with ref and @ref. When do I want the ref and when the deref'd value?
12:42Chousukekotarak: I think that's much easier to reason about
12:43Chouserleafw: by having people describe what they find hardest to understand about writing macros I may be able to make my blog post more relevant to more people.
12:45leafwChouser: great. Where is such blog post?
12:45ChouserI'm working on it.
12:47leafwalways something good is cooking around clojure ..
12:47Chousukefor example, when you do (let [foo (gensym)] ... then, in a macro, the value of foo is some random symbol and in your macro, instead of binding into the name "foo", you need to use the *value* of foo as the naming symbol. worse yet, inside a syntax-quoted form "foo" is actually treated different from the "foo" outside of the syntax-quote. For simple examples, it's easy to keep track of them, but when it gets more complex I know *I* have problems
12:48kotarakIf you loose track, then this is a sign, the macro is too complicated and better split up into some helpers.
12:49Chousukeyeah. but I find documentation about such macro writing techniques rather scarce
12:52AWizzArdChousuke: in principle a macro is always then useful, when you don't want to put code into #(..)
12:52Chousukefor example map'ing a form-generating function over the arguments of a macro and then using ~@ to "splice" the result into the macro
12:53Chousukeno doubt common when writing macros but not exactly obvious.
12:53AWizzArdyou never need macros, you can do everything exclusively with functional programming as well
12:53AWizzArdit just looks not always as beautiful
12:54Chousukeoh, I'm not arguing against macros :)
12:54AWizzArda macro is there to remove a ' or #(..) from your code
12:54Chousukethey're great. I just want to hear more about what tricks and techniques people use when writing macros.
12:54AWizzArdand all macros can be written in one line of code
12:55AWizzArdtheir purpose is to introduce lazyness
12:55AWizzArdwhen you have code that you don't want to be evaluated in some cases
12:55Chousukethey reduce repetition in code, yeah.
12:56AWizzArdwhat they reduce is the use of ' and #(..)
12:56ChousukeI view macros as basically code transformations.
12:56ChousukeI want to know, what are good techniques for doing code transformation :)
12:56AWizzArdyes, they can also be seen as some mini-compiler :-)
12:58gnuvince_Does anybody know a Java (or Clojure) library that would perform the same tasks as Python's BeautifulSoup?
13:00AWizzArdChousuke: well yeah, that's a bit general.. but anyway, you should consider to read in this book: http://www.paulgraham.com/onlisp.html There is a download link for downloading it legally and free from the authors website.
13:00AWizzArdThis is more or less *the* book about macros.
13:06Chousergnuvince_: http://home.ccil.org/~cowan/XML/tagsoup/
13:06Chouseronlisp is great.
13:06gnuvince_Chouser: he doesn't seem to have any documentation though.
13:17Chouseryeah, it's just a sax-compatible parser. you can drop it into clojure.xml/parse or clojure.contrib.lazy-xml to parse HTML instead of XML
13:20sohailanyone have an example of gen-and-load-class?
13:22sohailhm, does clojure not have any tests? I can't seem to find any..
13:23sohailLau_of_DK just the man I'm looking for
13:23Lau_of_DKsohail, :)
13:23sohailhow did you do the anonymous function for the slot thing?
13:23Lau_of_DKYes, if you want to test if i = 1, you can test like this (= i 2)
13:23sohailI'm thinking you need a gen-and-load-class
13:23Lau_of_DKIs pretty advanced, but you'll pick it up
13:23sohailLau_of_DK :-P
13:23Lau_of_DKYes you need gen-and-load-class
13:24sohailcan you paste what you did for me?
13:24Lau_of_DKI can do one better, but lets go black-ops
14:33jgracinis there a function which checks whether a sequence contains an element?
14:33Chouser(some #{item} sequence)
14:35jgracinChouser: thanks. I guess it's short enough. I've been bitten twice by (contains? [1 2] 1), though.
14:36Chouseryep, contains? is for key/value (a.k.a. associative) collections, not sequences.
14:36jgracinI keep forgetting that. Hopefully, two times will be enough to remember. :-)
14:38ChouserThe idea of renaming it has been shot down before. I wonder if "has-key?" as considered.
14:43Chouserhttp://groups.google.com/group/clojure/msg/b26d88598b14254c
14:43Chouser"I don't think contains-key? works for sets or vectors very well, and
14:43Chouseram not inclined to change this much-used name"
14:57bradbevIs there an idiomatic way to spawn a thread in Clojure? It seems like it would be such a common thing to do that there should be, but apart from using Java interop I can't see it.
14:57AWizzArdbradbev: send / send-off
14:57bradbevOr agents, but that seems like a slightly different thing to me
14:57Chouserbradbev: you can either use and agent of Java's Executor framework.
14:58bradbevso for a server handling connections, I'd use send-off to do the work?
14:58AWizzArdor send
14:58AWizzArdif you have enough cpus :-)
14:58bradbevand the agent is effectively my thread handle
14:58AWizzArdsend-off has the disadvantage that it grows your thread pool.. that could be not so nice when your server gets attacked
14:59AWizzArdsend uses a thread pool of, I believe 2*number-of-cores threads
14:59bradbevAWizzArd: but sent cannot perform blocking ops, which I may need
14:59bradbevsorry send & there should have been a ? in there :)
15:00AWizzArdsend will put your tasks in a queue and work them off
15:00Chouserfor blocking operations, you should use send-off, yes.
15:00AWizzArdsend-off does the same, only that it will extend your queue if at call time there is no thread available in the pool
15:01AWizzArdin priniple send-off should be the choice if you don't expect anyone to hammer your server with many requests
15:01bradbevRight, so Agents are kind of like thread handles, but with a built in thread-safe RPC facility?
15:02AWizzArdbut if you have 300 cpus available anyway then send should work fine, as your default pool would consist of around 600 threads or so
15:02Chouseragents aren't tied to a particular thread -- when an agent's action is complete, the thread returns to a pool to be used by another agent action later.
15:02rhickeybradbev: agents work off thread pools
15:03rhickeyAWizzArd: the choice should really be made based on blocking or not - both use pools
15:04AWizzArdI see. I looked at the Java sources and understood it in that way, that send-off is doing the same, but only extends the pool if needed.
15:04AWizzArdbut I am not a Java guy, so...
15:06bradbevthanks guys, have to dash.
15:16AWizzArdSo what is send-off doing else? I understand that send puts all tasks in a queue and a fixed number of threads works these tasks off. And send-off is doing the same, only that there is not a queue - when a new tasks comes in and the pool is empty, then a new thread will come into the pool and begin it's work.
15:17rhickeyAWizzArd: yes, they are different kinds of pools
15:17Chousukehmm
15:19AWizzArdIf humans are involved then send-off has the advantage of not letting someone wait. But when I do for example work with my Genetic Programming engine then I could accept the blocking behaviour. I don't want 80k threads running at the same time, but instead let my 80k programs run, using all cores available.
15:20AWizzArdBut having more threads running would cause more scheduling overhead, so in the end it would take even more time to do all calculations. Is that +/- right?
15:22rhickeyif you are doing calculations you should use send, there's no reason to have more than #cores threads
15:22AWizzArdyes oki, thx
15:24Chousukethere are examples on the wiki for parsing integers that use (. Integer parseInt ...). Any objections for converting these to use /?
15:25rhickeyChousuke: no that would be preferable
15:26Chousukeokay. Thought so :)
15:27AWizzArdBtw, in his book about Clojure Stuart Halloway says in the preface that "Wherever you need it, you can get the exact same performance that you could get from hand-written Java code.". Is that definitly correct or more or less advertisement? ;-)
15:29rhickeyAWizzArd: you can get direct calls to Java methods (no reflection or other overhead), and direct primitive math
15:29AWizzArdI see
15:31AWizzArdapropos math... a function expt could be nice as (.pow ...) requires explicit "casting" to bigint
15:35Lau_of_DKrhickey, I can see that you falling a bit behind the group in terms of contributions to clojure-euler.wikispaces.com - it'd be great if you could provide the solutions between 192-210, thanks
15:47Chousukehmm, there are still few uses of . for method calls in the wikibook page, but as those are non-static access I guess I'll let them be. readers probably should become acquaintainted with it anyway :/
16:32RadioApeShotDoes clojure provide some what of hooking into the printer so I can customize how certain objects are printed at the REPL?
16:32RadioApeShotIs there a multi-method I can extend or something?
16:33Chouseryep, print-method
16:33RadioApeShotThanks
16:34Chouseruser=> (defmethod print-method String [obj w] (.write w (str "I'm a string: " obj)))
16:34Chouseruser=> "hello"
16:34ChouserI'm a string: hello
16:36RadioApeShotWhat is the dispatch function for the method?
16:36Chouserclass of the obj
16:36Chousercheck boot.clj for the actual definition.
16:37RadioApeShotHm
16:37RadioApeShotThe java-class?
16:37RadioApeShotSo it is not possible to extend this to print a particular kind of map, say
16:39RadioApeShotOr it seems you can set the meta-data of thing to give it a "class"
16:40RadioApeShotLooking at boot.clj, anyway
16:40danlarkinChouser: is . syntax for method calls deprecated?
16:40Chouserthat's really an rhickey question. My best recollection is that it is not deprecated for instance calls.
16:42danlarkinwhat would be the alternative, doto?
16:43Chouser(.method instance arg1 arg2)
16:43RadioApeShotChouser: Looking at boot.clj more carefully it seems like the custom printer only dispatches on the Java class of clojure values, so there is no simple way to define a custom printed "class" in pure Clojure. Is this right?
16:44danlarkinChouser: ah.
16:45ChouserRadioApeShot: No, I don't think that's right.
16:45RadioApeShotWell, the dispatch method is class
16:46RadioApeShotAnd class just returns the Java class of the item passed in
16:46RadioApeShotSo, for instance, all clojure PersistentHashMaps are clojure.lang.PersistentHashMap
16:46RadioApeShotBut suppose I want a PersistentHashMap to represent a "class"
16:47RadioApeShotthe function class isn't a multi-method, so I can't customize it to dispatch different for certain kinds of things.
16:47Chouseroh, I see what you're saying.
16:48RadioApeShotSay I want to print every PersistentHashMap with a {:polynomial true} association in a particular way.
16:48RadioApeShotThat is, in fact, the case in point.
16:48RadioApeShotI have a polynomial algebra library I am porting from Scheme
16:48RadioApeShotPLT Scheme, in fact.
16:48RadioApeShotAnd I had a nice custom printer that printed out polynomials in a 3x^2 + 2x - 4 style.
16:49RadioApeShotPLT Scheme has a nice implementation of CLOS with a custom printer (although I think it stopped working in PLT 4).
16:49RadioApeShotI just as soon move all my code over to Clojure anyway.
16:50Chouserwell, let's see. you could dynamically rebind class to your own function...
16:50RadioApeShotHm
16:50RadioApeShotLike "around" the REPL?
16:50ChouserThat's probably not the best solution, though. hm...
16:51RadioApeShotMaybe class should have a custom behavior for maps.
16:51RadioApeShotObviously I am not in a position to make that change, though
16:52RadioApeShotOr maybe I need to implement the very basic polynomial type as a Java class
16:52RadioApeShotThat might be the "Clojure Way"
16:52Chouseror perhaps print-method should use something a bit more complicated than "class"
16:53RadioApeShotOtherwise you are pushing towards having a within-clojure object system in addition to the Java object system.
16:53Chouserwell, we're already quite a ways down that road with the multi-taxonomy heirarchy system used by multimethods
16:54RadioApeShotIt just seems like there is not a good way of meshing a full object system with a Lisp style with Java.
16:54Chousukehmm :/
16:54RadioApeShotWhich is what this is getting at.
16:55RadioApeShotLooks like there are already polynomial libraries in Java
16:55ChouserI wonder if rhickey'd be open to having print-method dispatch on (:print-type ^obj) instead of class (if such a meta-key exists).
16:55RadioApeShotProbably best to write a thin wrapper
16:56ChousukeChouser: some solution based on metadata is probably the cleanest option.
16:56RadioApeShotI am just partial to my implementation because I was learning to work with foldl when I was writing it and some of the code is "clever"
16:57RadioApeShotWell
16:57RadioApeShotThanks for the advice
16:57ChouserI pretty sure he'd reject a single :type key, but maybe a specific :print-type would be ok.
16:57RadioApeShotHopefully a better solution will come out of the discussion
17:08brillDoes anyone here use Emacs as IDE for clojure?
17:08Hunfor certain values of I
17:17AWizzArdbrill: I use Emacs+Slime+Clojure
17:20brillAWizzArd: Do you use brill clementsons setup or the setup at clojure?
17:21abrooksChouser: Is there some existing Java interface for printables? That seems the more Java + duck-type-y thing to do.
17:21AWizzArdbrill: no, I set up my emacs before I saw his postings. You can check out this post one possible .emacs config: http://paste.lisp.org/display/68867
17:22Chouserabrooks: .toString ?
17:23abrooksChouser: For example...
17:23brillAWizzArd: Thanks. I just noticed that there's a lot of different ways of settings things up.
17:23abrooksChouser: Is that part of an interface or merely a convention across classes?
17:24Chouserabrooks: I believe it's provided by Object.
17:24AWizzArdbrill: in emacs try also M-x customize-group swank-clojure
17:24abrooksChouser: I guess it's still testable from Clojure.
17:24abrooksChouser: Hm. Is .toString more like __str__ or __repr__?
17:24AWizzArdit will pop up a "graphical UI" to set some settings of Clojure, as soon you have set up the right files
17:25Chouserabrooks: __str__ I think. Java doesn't provide a __repr__ which is why readable printing in Clojure is useful and also such a big task.
17:26abrooksChouser: Most __repr__ strings aren't readable either.
17:26Chouseroh
17:27brillAWizzArd: I'll try that.
17:27abrooksChouser: >>> open("/etc/hosts").__repr__()
17:28abrooks"<open file '/etc/hosts', mode 'r' at 0x7f2afd57faf8>"
17:28abrooksChouser: __repr__()s mostly useful for human debug. Often it is the same as __str__().
18:32AWizzArdrhickey: in one of your videos you mentioned that Clojures STM is semi-optimistic. Can you outline in a few words the difference to fully optimistic? I tried to google that but couldn't find anything.
18:34rhickeyAWizzArd: a fully optimistic STM might let transactions run to their end, only to find out they can't succeed and retry - when Clojure's STM finds a ref conflict it will block, subject to deadlock detection. This causes less churn
18:37AWizzArdI see thanks.
18:39AWizzArdAnd is it guaranteed that if 100 threads are trying to update a ref at the same time one of them will definitly always win? Or could it happen from time to time that they all need to retry?
18:40rhickeyAWizzArd: livelock is possible, although there are retry limits that will kick in
18:43AWizzArdSo can one say: the more updates/reads happen inside a dosync, the higher the chance that it will take more and more time until one transaction succeeds?
18:44bradbevI would like to write a little server that listens on a thread & spawns workers to handle connections. From a previous conversation, agents and send-off is the idiomatic clojure way to do this. How would I terminate the main listening loop? Send a message to the agent, change a global var?
18:45rhickeyAWizzArd: all transaction issues involve the degree of contention - 2 transactions that have no overlapping refs can both succeed. Long writing transactions contending for the same refs as short writing transactions will have problems. But MVCC reads-don't-impede characteristics and commute both work towards reducing the contention footprint substantially
18:45bradbevand, I guess, what initial states (if any) should the agent have?
18:46AWizzArdand if really needed.. one could still lock the transactions I guess.. Clojure does nothing to prevent an explicit lock as I see it
18:47rhickeybradbev: initial state is completely application specific, but yes, you could send an action for termination. Don't neglect java.util.concurrent for workflow issues, like queues or latches
18:47rhickeyAWizzArd: manual locking and transactions are a bad combination
18:48AWizzArdhmm
18:48bradbevrhickey: that's the thing that is confusing me. An agent doesn't quite feel right here & I wonder if it is me misusing the concept, or if agents don't fit my use-caes
18:49rhickeybradbev: 'spawn workers' certainly sounds like a good fit for agents
18:49AWizzArdbradbev: can't you run the listener in its own agent in a loop that checks if a global var is set to true and as soon someone connects this listener will send-off some worker?
18:50rhickeyAWizzArd: you'd want to uses queues or latches, not spin loops and flags
18:50bradbevAWizzArd: yes, that's what I'm thinking. Just have never used Agents before :)
18:50AWizzArdrhickey: in your ant example you used this running flag in an endless loop
18:51bradbevsend & send-off messages from the same thread - will they be executed in the order they were sent?
18:51rhickeyAWizzArd: that flag is a hack for repl control during testing, the loop is the core activity loop, the ants do real work in the loop
18:53rhickeybradbev: yes
18:54bradbevare agent messages executed concurrently, or strictly in sequence?
18:54rhickeybradbev: any single agent is only doing one action at a time, but multiple agents act concurently
18:55bradbevright, ok. I can view an agent as a single threaded message processor then.
18:55AWizzArdbradbev: and it is not guaranteed that they will run exactly in the order you sent them off
18:55rhickeyAWizzArd: not true, if sent from the same thread or agent, will execute in order
18:56AWizzArdyou can do a little experiment with printing a number and see that it won't always go from 1 to 10
18:56rhickeyAWizzArd: ?
18:56bradbevI presume that there is a queue that is thread safe, how stuff gets put on that queue might be non-ordered, but the queue is processes in order
18:57rhickeybradbev: if put on from multiple threads, order between threads is non-rodered, but still ordered within each thread
18:58bradbevthat makes sense too
19:03bradbevSo I could set my server agent up so the listen function will listen with a timeout, and reschedule itself with a send-off. At the start of the function, inspect the agent & if it is not running, abort. Then I can stop the server by sending the agent a message from another thread
19:05rhickeybradbev: right
19:05bradbevthat sounds like a plan then :) Thanks!
19:05rhickeysure
19:19AWizzArdrhickey: I don't rememeber exactly what I did when I was playing around with agents for the first time some weeks ago. I remember that I was printing out numbers and they were not showing up in order. From that experiment I still knew only that stuff and incorrectly assumed that agents don't run in order.
19:20AWizzArdso good to have this update, thanks :-)
19:22AWizzArdbut the behaviour is different when using send-off yes?
19:23AWizzArdso if we have (def x (map agent (range 30))) and then do (doseq a x (send-off a #(println %))) we really do get some random order
19:24AWizzArdso I just remembered that I did an experiment, but not that I used send-off, so that was the source of my confusion.
19:27Chouserboth send and send-off should behave the same in this regard, which is that the actions will be in indeterminite order because they're on *different* agents.
19:28Chouserorder is only guaranteed when the actions are coming from one thread (or agent) and going to one agent.
19:29AWizzArdChouser: now I am confused again
19:29Chousergreat, happy to help. :-)
19:29bradbevAWizzArd: an agent executes functions off a queue, in the order they were added to the queue
19:29AWizzArdbradbev: yes
19:29bradbevif you only add from one thread, then your order is determined
19:29AWizzArdyes
19:30AWizzArdbut why does my send-off example from above produce random looking output?
19:31AWizzArdis it not the repl thread that sends them all off?
19:31rhickeyAWizzArd: because you have 30 different agents
19:31rhickeythey act in parallel
19:31bradbevso each agent gets one task
19:31AWizzArdah okay, then I misunderstood bradbev's question from above
19:32AWizzArdall clear now
19:34AWizzArdalthough it's funny that when I use send instead of send-off in my example above I get the right order ;-)
19:35bradbeva smaller threadpool may restrict the ordering so it looks right
19:35AWizzArdI tried it with 50 agents a few times
19:35AWizzArdwhen using send-off 10 agents are enough to regularily get a random order
19:36ChouserAWizzArd: how many cores on the computer you tried that on?
19:36AWizzArd2 cores here
19:37AWizzArdbut even on a single core machine there should be at least two threads running, as I think the source initializes the threadpool which is used by send with 2*available-cores
19:38Chouserlooks like 2 + availableProcessors
19:38AWizzArdor that way, ok
19:38AWizzArdso, 4 threads here
19:38Chouserwhich is just another way to get to 4
19:38Chouser:-)
19:39AWizzArd(def x (map agent (range 100))) (doseq a x (send a #(println %)))
19:41AWizzArdbut try (range 10) and send-off
19:41bradbevsend runs the function for an agent on existing threads, right? So that means you will only have 2-4 existing threads to run the funcs. If the funcs all run at the same speed, then you're quite likely to get the correct order. Send-off will expand the thread pool, causing new threads to get created (slow). So lets say threads 1-4 are used up, so (print 5) gets a new thread, which is slow to start. In the mean time (print 6) is now
19:41bradbevso you might see 1 2 3 4 6 5
19:44AWizzArdbradbev: yes, sounds good
19:45AWizzArdeven when I try it with 1000 agents it is the correct order
19:45bradbevyeah, if you added a small random sleep in the function it would differ
19:45AWizzArdonly in areas of about 10k agents the order gets a little bit out of sync
19:45gnuvince_Quick question, is OpenJDK just the name Sun gave to their JDK when they GPL'ed it or is it something different?
19:46bradbevhmm, maybe not actually
19:47Chousukegnuvince_: yes... and no.
19:47Chousukegnuvince_: OpenJDK is not completely equal to the sun JDK; Sun was unable to open source everything.
19:49ChousukeI think most of the encumbered parts have since been replaced with free implementations though.
19:50ChousukeAs far as I know sun's JDK isn't based on OpenJDK yet, but might be in the future.
19:54gnuvince_ok
19:54gnuvince_I was reading about this G1 Garbage Collector
19:54gnuvince_quite interesting
20:47blackdog_danlarkin, a useful addition to the json encoder would be an option to encode keywords as strings
20:48blackdog_so (name keyword) somewhere
20:48blackdog_for json keys
20:48danlarkinkeywords are encoded as strings currently
20:48danlarkinoh, but you mean without the colon?
20:48blackdog_ah you're there :)
20:48blackdog_yes
20:49blackdog_i'm just returning data from a db
20:49blackdog_and it's great except the keys have :
20:50danlarkinyeah I wavered back and forth on keeping the colon or not
20:51blackdog_so maybe an option like :indent, :keepColon
20:53danlarkinMmmmmm, I'd have to pass it through encode-coll and encode-map-entry
20:54blackdog_i'm not sure if I've ever seen json keys with : in the key
20:54blackdog_kind of confusing with the : separator too
20:55danlarkinyeah... perhaps I should just always use (name keyword)
20:55blackdog_IMO it's less suprising
20:56danlarkinof course that'll drop the hint that they were keywords and when I write the decoder (json->clojure) I'll have to make all keys as strings or keywords
20:57blackdog_yea, hence optional is maybe best
20:57blackdog_good point
20:58danlarkinI'm leaning towards dropping the colon and making all keys be keywords when I decode
20:58danlarkinhow does that strike you
20:59blackdog_yes, sounds fine, and the user can always make them strings if required
21:00blackdog_i guess except for "x y" keys
21:01blackdog_nevermind
21:03danlarkinalright I've made the change
21:03blackdog_w00t
21:06blackdog_i think you left the reflection flag on I just got lot's of interesting messages
21:06blackdog_apart from that works for me!
21:06blackdog_thanks
21:07danlarkinoh, oops... yes I did
21:08danlarkinthere, fixed that too
21:08blackdog_thanks!
21:11danlarkinyou should watch out for reflection though, it'll slow ya down a lot in the wrong places
21:11blackdog_true
21:22danlarkinheh, I'm glad someone's finding it useful
21:22blackdog_yea, i'm a web developer mostly so servlets returning json is bread and butter
21:23blackdog_and this is perfect for returning db records
21:23danlarkinit should be quite fast, I spent a bit of time tweaking things to that effect
21:24blackdog_coolio
21:24danlarkinhopefully soon I'll have a decoder... I want to use kotarak's parser combinator library but right now it's in a state of flux
21:25blackdog_looking forward to it
21:28lisppaste8bradbev pasted "Agents sending to themselves?" at http://paste.lisp.org/display/70056
21:29bradbevAre agent's allowed to send to themselves?
21:29bradbevIf so, what am I doing wrong?
21:33Chouserbradbev: java.lang.Exception: Agent has errors (NO_SOURCE_FILE:0)
21:33bradbevhmm, I don't see that...
21:33Chouseryeah, that's the squirrely thing about agents. The exceptions hide inside them
21:34bradbevick.
21:34ChouserSo try (def ag (agent nil)) then (send ag at 3)
21:34bradbevoh, you called agent-errors
21:34Chouserthen @ag or right, (agent-errors ag)
21:35bradbevbut no real clue as to the error itself...
21:35Chouser(.printStackTrace (first (agent-errors ag)))
21:37bradbevoh, I see - I'm trying to send to the agent-state, not the agent
21:37bradbevdamnit
21:37Chouserah, good -- I hadn't spotted it yet
21:37Chouseryou can use *agent*
21:37bradbevawesome, thanks
21:38bradbevok, got it now, thanks much
21:39Chousergreat