#clojure logs

2008-04-23

02:23patchworkHi guys. So I'm starting an application in clojure, and I'm wondering how deep to design the granularity of the relationships. In particular, it would be nice to have an agent for each sliver of the behavior, but I am wondering how reasonable having large numbers of agents is. Is there some guidelines as to about how many agents I should have at any given time?
12:41jteowhy isn't there tail call optimization?
12:42rhickeybecause the jvm doesn't support it natively, and Clojure uses native JVM calling
12:43jteoah.
14:42rhickeyChouser: any progress on the destructuring?
15:11Chouserrhickey: yeah, I have my most recent suggestion working.
15:11ChouserI just haven't had time to write it up.
15:11rhickeygreat
15:12ChouserIt's not quite as succinct as the #{} format was, but it feels "cleaner" and is definitely more complete.
15:12rhickeyI agree
15:14Chouserone issue I ran into was defaults when destructuring a set
15:14rhickey?
15:15Chouser'get' takes an optional 3rd arg, but using a map or set as a function does not.
15:15Chouserhttp://n01se.net/paste/0FZ -- Extra features for map destructuring
15:16Chouserso if you provide defaults (which don't make sense for sets anyway), my patch uses 'get', otherwise it uses the map or set as the function.
15:20rhickeyok
15:20Chouserhere are some test cases that are working: http://n01se.net/paste/WNk
15:21wabashDoes clojure code compile to native code via the Java HotSpot server thingy?
15:22rhickeyyup
15:22wabashsweet.
15:22wabashrhickey: You mentioned a wiki for contributing. Were you referring to the wikibook, the wikipedia entry, or a wiki on the Clojure site?
15:23rhickeythe wikibook
15:23wabashok. thanks.
15:24rhickeyhttp://en.wikibooks.org/wiki/Clojure_Programming
16:10vincenzrhickey: I have a questions about macros. How do you make sure that macro-code runs at 'compile'time?
16:15rhickeymacros always run at compile time, but the code they produce runs at runtime
16:25Chouserrhickey: is there anything else you want from me for the destructuring patch?
16:31rhickeyjust looking at it - looks fine, although the original was written before variadic assoc/dissoc, this could be cleaner with them (e.g. apply merge ... apply hash-map...
16:32Chouserok. I can look at that tonight if you want.
16:33Chouseror you can do it; I don't care.
16:34rhickeyI appreciate what you've done, I can take it from here unless you want the exercise :)
16:34ChouserI've got other things I can do.
16:35rhickeyok :)
16:35ChouserOn the other hand if you want to do something I *can't*, that'd be fine too.
16:35rhickeythanks
16:35Chouserhey, thanks for letting me help. :-)
16:35rhickeyI'm working on Java-less Java integration
16:36rhickeyNo RT.init
16:36rhickeyDefining named classes right into bytecode
16:36rhickeyaceess to protected members and super
16:36rhickeyclasses can have agent or ref state
16:36rhickeyruntime redefinition of methods
16:37rhickeyauto-load of user.clj from classpath
16:37Chousersee, you shoudl do that and let me monkey around with refactoring apply hash-maps
16:38Chouserwould all that help someone derive from PersistentHash in order to, for example, provide a default value that would be returned instead of nil?
16:38rhickeythat's on the todo list anyway, but probably
16:39rhickeyright now there are a lot of cases in which you have to write a little Java
16:39rhickeyfor main()
16:39rhickeyservlets
16:39rhickeyworking in a framework like Netbeans or Eclipse
16:39ChouserBanishing that last 20% is probably hard.
16:40rhickeyI think I've got it figured out, and half-implemented
16:40rhickeyfor instance RT.init() is no longer needed
16:40rhickeyand Clojure loads user.clj from the classpath at boot time
16:41rhickeymuch of the proxy stuff will be reused
16:43Chouser"classes can have agent or ref state"! cool.
16:44rhickeyBasically they'll have final state, so if you want mutation you'll have to do it the Clojure way
16:44vincenzrhickey: how do you make sure that compiletime code doesn't do "runtimey" things?
16:44rhickeyvincenz: I don't
16:44Chouservincenz: it *can* do runtimey things. That's what's so cool.
16:45rhickeybut it does require care and self-discipline
16:45rhickeyyou can make a mess with macros
16:45ChouserI guess you don't want a blocking network call during macro expansion.
16:45vincenzrhickey: what about a macro requiring code from a file that has usage of macros/
16:45rhickeyChouser: :)
16:46rhickeyvincenz: Clojure generally has a define-before-use policy, same applies to macros
16:46rhickeyChouser: anyway, re: destructure reduce/apply/merge/dissoc/apply/hash-map/mapcat can become reduce/apply/assoc/dissoc/map - remember you can assoc pairs onto a map
16:48Chouserok
19:18leafwhi all
19:19rhickeywelcome
19:19vincenzrhickey: what did you use as paper for your stm implementation?
19:19rhickeyI read a _lot_ of papers
19:19leafwquestion: is there an equivalent class to jython's PythonInterpreter, to which one can handle code as String objects and evaluate them within the context of a specific interpreter instance?
19:19leafwif there is, it's not evident to me ...
19:20rhickeyleafw: Clojure is compiled, so there isn't exactly a notion of interpreter instance
19:20leafw!
19:20leafwand the REPL.java class?
19:21rhickeyBut Compiler.eval() is a full compiler/evaluator that takes Clojure data structures
19:21rhickeyyou can get from Strings to Clojure data structures using LispReader.read()
19:21leafwthank you
19:21rhickeyor build the data structures directly using the Clojure Java library
19:23rhickeyvincenz: Clojure's STM is not exactly like any one I read about
19:23leafwthanks for the tips. I have somewhere to start now.
19:23rhickeyIt has no global lock
19:23vincenzrhickey: I think haskell is lockfree as wel
19:23rhickeybut is not lock-free either
19:23vincenzoh
19:23vincenzdistributed locking?
19:24rhickeyI don't believe that lock-free is efficient, there are good papers that indicate it's not
19:24vincenzIIRC, lock-free only works well for optimistic lazy stm
19:24rhickeySome locking is better than spinning optimistic retries in my book
19:25vincenzdo you do eager or lazy?
19:25rhickeyLocks are eager, but there is barging
19:25rhickeyalso timeouts
19:26rhickeywaking up from a lock before released
19:26rhickeybased upon a time
19:26vincenzTrying to find out what an easy system would be
19:26rhickeySTM is not easy
19:26vincenzwell everything is an axis
19:26vincenzthere's gradations
19:27rhickeyThe easiest is to number your resources, work optimistically, then grab the locks in order to commit
19:27vincenzso that would be lazy then
19:28rhickeyright
19:28rhickeybut there are so many variations and tradeoffs
19:28vincenzI wonder if you could work with a distributed clock
19:29rhickey?
19:29vincenze.g. if you have a generational GC, use one clockc per generation
19:29rhickeyI don't see the interaction with GC
19:29vincenzwell you have more clocks
19:30vincenzso less conflicts on those clocks
19:30rhickeywhat's a clock?
19:30vincenzI thought lock-free worked with a clock
19:30vincenzyou check the data you're writing to after a lazy eager system is still the same clock time for the values you are modifying
19:30rhickeylock-free uses any CAS-based mechanism
19:31rhickeybut there are many different policies for timestamping the world
19:31vincenzin essence you're trading locks for clocks?
19:32vincenzrhickey: is there a reason you chose not to support orElse/
19:32rhickeyno, they are 2 different things - you can use CAS to toggle flags that effectively 'lock' a resource for one transaction without using a blocking lock - you have to distinguish lock-free from non-
19:32rhickeyblocking
19:33rhickeyi.e. soft locks don;t
19:33rhickeyblock threads
19:33rhickeyvincenz: no orElse because I don't think it's a good idea
19:34vincenzrhickey: why is that?
19:34vincenz(out of curiousity)
19:34rhickeywell, it requires read-tracking for one
19:34rhickeyI don't like mixing the coordination with the transaction
19:34vincenzbtw, just a side question
19:35vincenz(let ((a @ref)) (sync (update ref ...))
19:35vincenzand
19:35vincenz(sync (let ((a @ref)) (update ref ...))
19:35vincenzare different, right?
19:35vincenzthe second guarantees that it occurs in the same timeslice/
19:35rhickeyyes, the first is a wild-read
19:37vincenzalright, thanks
19:39ooxwoHi everybody. I'm starting on a clojure application and I am wondering how fine-grained to make the abstraction. In particular, for my domain it would be nice to make an agent for each atomic element, but I am wondering how feasible it is to use large numbers of agents. Is there a guideline as to about how many agents I should have running at any given time? Is there a way to unite several agents on a single thread? Thanks for your
19:39ooxwohelp.
19:40rhickeywhat are large numbers?
19:40ooxwolike 10-100 thousand
19:41rhickeyno problem. each agent doesn't get its own thread
19:41ooxwoor more possibly, depending
19:41ooxwoReally? Ah okay
19:41rhickeythe actions run in a thread pool, idle agents use no cpu at all
19:41ooxwoThat is good news, in my trial runs there seemed to be a one to one mapping between threads spawned and the number of agents I had created
19:43ooxwoHave you stress tested the limit of number of agents? Just curious if there is a general ceiling.
19:43rhickeyyou should be limited only by memory, but make sure you use send and not send-off or you will run into thread consumption problems
19:45ooxwoAh okay thanks for the tip. I was using send-off so maybe that is why there was a thread for each agent.
21:41Chouserhttp://n01se.net/paste/IiF -- Tighter implementation of map destructuring features.
21:41Chouserrhickey: I don't think that's exactly what you had in mind, but I think it's good.
21:42ChouserDo what you want: take it, advise me, or do it your own way.
22:26rhickeyChouser: that looks great - thanks!
22:34Chousernp, thanks for letting me help.
23:29Chouser(get #{:a} :a :dflt) ==> :dflt
23:30Chouserhm. maybe that does make sense.
23:30Chouseroh, yeah, ok. I'm fine now.
23:31landonfLisp's propensity for mind-boggling density still throws me for a loop.
23:31landonfFeels like there a character drought and we're all conserving. Save a tree, type fewer characters.
23:32Chouserheh