Re: Why is MVCC history managed manually?
Hi Rich, maybe this is a better way of looking at it. When you create a transaction, you get a new UnitOfTime object that has the sequential timestamp in it. The Transaction object keeps a reference to the UnitOfTime object for the rest of the Transaction objects life. private static final AtomicReference timeLineHead = new AtomicReference(new UnitOfTime(0)); public static UnitOfTime getNewUnitOfTime() { UnitOfTime current = timeLineHead.get(); final UnitOfTime future = new UnitOfTime(current.time + 1); while (!timeLineHead.compareAndSet(current, future)) { current = timeLineHead.get(); future.time = current.time + 1; } current.future = future; return future; } UnitOfTime objects are kept in a singly linked list to make a time line. The sole purpose of this list is to guarantee garbage collection order. The first UnitOfTime object created will also be the first one GC'd. Now we have a guaranteed order objects will be GC'd - great for a Ref history list. The UnitOfTime object also has a set of objects you want it to keep alive. This set is only written to, never read. It exists only to tell the GC what you don't want GC'd too early. (It probably doesn't have to be concurrent.) public class UnitOfTime { public UnitOfTime future; public long time; private final ConcurrentLinkedQueue keepAliveSet = new ConcurrentLinkedQueue(); public void keepAlive(Object obj) { keepAliveSet.add(obj); } public UnitOfTime(long time) { this.time = time; } } So we now have Transaction objects referencing the UnitOfTime they were created. This holds that UnitOfTime object in memory (and consequently all later UnitOfTime objects) until the Transaction object has been forgotten and GC'd. I think you are using the using the latest time in your commits, so your commit would getNewUnitOfTime(). So when you update your Refs with new Values, you put the old value on the Ref's history list, you also use the commit's UnitOfTime object and do commitUnitOfTime.keepAlive(prevValue). This then guarantees the value your replaced on the Ref will live up to the commit's UnitOfTime. Any transaction starting before the commit is now guaranteed to be able to find that old Value as the commitUnitOfTime will not GC until alll previous UnitOfTime objects have GC'd. Which means all previous Transaction objects have been GC'd. You will need to keep a history list in Ref, but that history list used WeakReference instead of a strong reference. I hope this is a clearer explaination. -Peter -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: weird repl + classloader behavior
On 25 Mai, 08:03, Brent Millare wrote: > Erik, what you said seems to make sense. So the question now is, since > a new classloader is started during each eval at the repl, does that > mean that it is closed after each repl statement? This seems to be the > case because after requiring a namespace in a previous command at the > repl, I can no longer reload that namespace with (require > 'foo :reload). However, because I am holding on to that namespace (as > I can access anything in that namespace I required), I feel that it > isn't completely unloaded. The natural follow up question would be, > does unloading the namespace required earlier then unload the > classloader? And, how does one test this? How does one obtain the > hierarchy of classloaders given you don't have references to the > children. Don't know for sure, I think the ClassLoader and all classes loaded with it will be GC'ed if there are no more references to the old classes and the loader itself. Is there even a way to "close" a classloader? What do you mean by "can not longer reload that namespace"? To inspect objects of a running jvm, you can either use a debugger, or patch the clojure.lang.DynamicClassLoader code so that it puts reference into a static Var on each ctor call or such. The java debug interface alsow allows you to get a list of all classes/ objects currently available in the running vm, see http://java.sun.com/javase/6/docs/jdk/api/jpda/jdi/index.html BTW, are you aware that clojure haa aa "add-classpath" (marked as deprecated) function, wich will be removed in future versions, due to the problems it introduced wich java-dependencies? -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Question on bound-fn source
(defmacro bound-fn [& fntail] `(bound-fn* (fn ~...@fntail))) Shouldn't it be: (fn [] ~...@fntail) ? If you try to use this function by passing more than one function as arguments to it, you'll get an exception. e.g. (bound-fn f1 f2) I'm a newbie to clojure and I'm not quite sure if this is a bug. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Stockholm Clojure User Group
Hi! There is now a Clojure user group in Stockholm, Sweden (via http://twitter.com/peter_hultgren/status/14648902541). Join us at http://groups.google.com/group/stockholm-clojure-user-group /Patrik -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Question on bound-fn source
Hi, On May 26, 12:41 pm, YD wrote: > (defmacro bound-fn > [& fntail] > `(bound-fn* (fn ~...@fntail))) > > Shouldn't it be: (fn [] ~...@fntail) ? > > If you try to use this function by passing more than one function as > arguments to it, you'll get an exception. e.g. (bound-fn f1 f2) > > I'm a newbie to clojure and I'm not quite sure if this is a bug. It's not a bug. The idea of bound-fn is to *define* a bound function. So instead of saying (fn [a b c] (do-things)) you say (bound-fn [a b c] (do-things)). If you already have a function, which you want to turn into a bound function use bound-fn*: (bound-fn* f1) (bound-fn* f2). Sincerely Meikel -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why is MVCC history managed manually?
On May 25, 11:29 am, Peter wrote: > Hi Rich, > > If you set up your object dependencies correctly then the objects you > want will stay in memory. Your history list would be a list of > WeakReference so it could be GC'd. > > This is nothing about read tracking, more about setting the correct > object dependencies so that the GC doesn't remove objects you aren't > quite finished with yet. > > I been writing up a description here. It's a simplified version of > what I've been playing > with.http://creativereality.com.au/notes/concurrency/54-mvcc-stm-gcd-ref-h... > > I kept the Transaction objects on the list, but you could consider > keeping a smaller object with just has a collection in it; associated > with the transaction. > > I took a look at your notes. I have a few problems with it: First, and foremost, it creates interaction relationships between transactions that otherwise have no overlap. You see this in the memory blowup during overlapping transactions. This rubs against a design objective in Clojure's STM to absolutely minimize transactional overlap and interaction. Second, you do a lot of work in createNewTransaction (get a new timestamp, modify existing head, make new transaction the head). How is that made consistent? You really need a lock, and at that point have moved to a much heavier contention point than in the current Clojure STM. Third, I'm wary of such extensive use of WeakReferences. That may just be conservatism on my part. I had considered and implemented similar designs in the early stages of developing Clojure's STM, and, while they have some appeal, I think these 3 points will eventually cause pain in practice. Rich -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Macro expand time
Hi, As a newbie to lisp/clojure one thing I am having real trouble with is understanding macro expand time (now having discovered the difference between quote and backquote I was hoping I was on the way to nirvana but still trip up) Some newbie questions: If the macro is run at compile time how can it call functions - or can it only call functions that you can guarantee will already have been compiled - so if you have macros calling functions in each other's namespaces would the compiler have to compile part of one namespace file, then part of the other, then back to the first? If there is any error in your file below the macro, will the macro have been expanded before the compiler discovers this? Or is there a first pass for syntax before the main compile time. So what exactly is compile time? Is there a newbie friendly reference to all this? -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Macro expand time
Hi, 2010/5/26 Quzanti > Hi, > > As a newbie to lisp/clojure one thing I am having real trouble with is > understanding macro expand time (now having discovered the difference > between quote and backquote I was hoping I was on the way to nirvana > but still trip up) > > Some newbie questions: > > If the macro is run at compile time how can it call functions - or can > it only call functions that you can guarantee will already have been > compiled Yes. > - so if you have macros calling functions in each other's > namespaces would the compiler have to compile part of one namespace > file, then part of the other, then back to the first? > No, the compiler will not even be as smart as you describe. It's the (:use) (:require) (:load) declarations which will have taken place before the macro is invoked (generally inside an (ns) declaration) that would have made the required other functions / macros available. > If there is any error in your file below the macro, will the macro > have been expanded before the compiler discovers this? Or is there a > first pass for syntax before the main compile time. So what exactly is > compile time? > The compiler will take each "top level form" one after the other : * read one form from the "input stream" (it will then get the famous "code-as-data"), * evaluate it: if the "code-as-data" starts with a list, we face a function call, so first resolve the function; if it is a real function, then first evaluate its arguments then pass them to the function; if it is a macro, then pass the arguments non-evaluated to the macro definition and substitute the whole macro call with the "code-as-data" returned by the macro ; if it is a special form, then execute the special form behaviour ('def has a side effect of creating a new var in the current namespace, 'fn has a side effect of compiling in memory (and on disk if *compile* is true) the function it defines, etc. This is certainly not accurate, but hopefully it gives you an overall view of the mechanisms. So the "first pass" is getting just enough information for evaluating the next "form" in the stream. HTH, -- Laurent -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Macro expand time
Thanks Laurent. It does give me an overall view, but more importantly it gives me the impression that there are some subtleties, so I am not feeling so bad about the fact some of the behaviour hasn't been what I had predicted. On May 26, 1:55 pm, Laurent PETIT wrote: > Hi, > > 2010/5/26 Quzanti > > > Hi, > > > As a newbie to lisp/clojure one thing I am having real trouble with is > > understanding macro expand time (now having discovered the difference > > between quote and backquote I was hoping I was on the way to nirvana > > but still trip up) > > > Some newbie questions: > > > If the macro is run at compile time how can it call functions - or can > > it only call functions that you can guarantee will already have been > > compiled > > Yes. > > > - so if you have macros calling functions in each other's > > namespaces would the compiler have to compile part of one namespace > > file, then part of the other, then back to the first? > > No, the compiler will not even be as smart as you describe. It's the (:use) > (:require) (:load) declarations which will have taken place before the macro > is invoked (generally inside an (ns) declaration) that would have made the > required other functions / macros available. > > > If there is any error in your file below the macro, will the macro > > have been expanded before the compiler discovers this? Or is there a > > first pass for syntax before the main compile time. So what exactly is > > compile time? > > The compiler will take each "top level form" one after the other : > * read one form from the "input stream" (it will then get the famous > "code-as-data"), > * evaluate it: if the "code-as-data" starts with a list, we face a > function call, so first resolve the function; if it is a real function, then > first evaluate its arguments then pass them to the function; if it is a > macro, then pass the arguments non-evaluated to the macro definition and > substitute the whole macro call with the "code-as-data" returned by the > macro ; if it is a special form, then execute the special form behaviour > ('def has a side effect of creating a new var in the current namespace, 'fn > has a side effect of compiling in memory (and on disk if *compile* is true) > the function it defines, etc. > > This is certainly not accurate, but hopefully it gives you an overall view > of the mechanisms. > > So the "first pass" is getting just enough information for evaluating the > next "form" in the stream. > > HTH, > > -- > Laurent -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Anyone experienced in using clojure as a "database"
I'd love to see a persistent "table" type together with some common primitives (select, join, union) and optimization capabilities. Currently a "set of maps" does something like that but I have no idea how to, for example, add an "index" to some particular field and use it in other operations. Another thing is tying such a database to some on-disk storage. Is there any database backend that doesn't internally mutate data? Even if not, such a data type could still be useful as a read-only view for other databases. Andrzej On Wed, May 26, 2010 at 3:36 AM, Sean Devlin wrote: > You might want to look at FleetDB > > http://fleetdb.org/ > http://github.com/mmcgrana/fleetdb > > On May 25, 2:08 pm, Fabio Kaminski wrote: >> Folks, >> >> i would like advice, >> cause since im starting something that will be eventually big data >> intensive, from scratch >> and i really like the options already built in in clojure like STM, >> parallelizing data and concurrency logic implemented on it >> i think its wonderfully tuned to use as database... and you can achieve >> different strategies, like graphs or balanced trees for different data >> >> my worries are about the efficiency in serializing it and recovering from/to >> the disk, >> java VM as a hungry heap VM, >> (and with immutable strategies, more heap needed) >> >> the benefits are control of sharding mechanism's and parallelizing not only >> in the unit's cores but between nodes of a cluster.. >> >> anyone using clojure not just as database middleware(wich is perfect for) >> but as database backend too? >> >> Thanks all, >> >> Fabio Kaminski >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group >> athttp://groups.google.com/group/clojure?hl=en > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: weird repl + classloader behavior
Hi Erik, >From what I understand, to close a classloader, you would need to also remove all references to it or set the references to it to nil/null. In the case of an eval in the repl, again I'm assuming we do lose that reference once we are out of the scope of the eval. While I said not reloading a namespace, I really meant not being able to reload a file that was on the new path added by the new classloader. So for example, if I added a swank-clojure.jar to the classpath, and I did a (require 'swank.core), then I went out of scope of the eval, did a (require 'swank.core :reload), I would get an error saying it doesn't exist. That JDI seems incredibly powerful, thanks for the tip. I was aware of add-classpath but I saw that it was deprecated, and I wanted to overcome its limitations. Unloading the classloader is an example of something not possible with add-classpath. On May 26, 4:31 am, Erik Söhnel wrote: > On 25 Mai, 08:03, Brent Millare wrote: > > > Erik, what you said seems to make sense. So the question now is, since > > a new classloader is started during each eval at the repl, does that > > mean that it is closed after each repl statement? This seems to be the > > case because after requiring a namespace in a previous command at the > > repl, I can no longer reload that namespace with (require > > 'foo :reload). However, because I am holding on to that namespace (as > > I can access anything in that namespace I required), I feel that it > > isn't completely unloaded. The natural follow up question would be, > > does unloading the namespace required earlier then unload the > > classloader? And, how does one test this? How does one obtain the > > hierarchy of classloaders given you don't have references to the > > children. > > Don't know for sure, I think the ClassLoader and all classes loaded > with it will be GC'ed if there are no more references to the old > classes and the loader itself. Is there even a way to "close" a > classloader? What do you mean by "can not longer reload that > namespace"? > To inspect objects of a running jvm, you can either use a debugger, or > patch the clojure.lang.DynamicClassLoader code so that it puts > reference into a static Var on each ctor call or such. > The java debug interface alsow allows you to get a list of all classes/ > objects currently available in the running vm, > seehttp://java.sun.com/javase/6/docs/jdk/api/jpda/jdi/index.html > BTW, are you aware that clojure haa aa "add-classpath" (marked as > deprecated) function, wich will be removed in future versions, due to > the problems it introduced wich java-dependencies? -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
promoting contrib.string to clojure, feedback requested
If you are a user of clojure.contrib.string, please take a look at the proposed promotion to clojure [1]. Feedback welcome! It is my hope that this promotion has enough "batteries included" that many libs can end their dependency on contrib for string functions. Cheers, Stu [1] https://www.assembla.com/spaces/clojure/tickets/359-promote-contrib-string -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
Stu, What happened to *not* promoting string? http://groups.google.com/group/clojure-dev/browse_thread/thread/e294cd444227 Also, is there an actual patch/diff to review? I didn't see one in Assembla. Sean On May 26, 11:16 am, Stuart Halloway wrote: > If you are a user of clojure.contrib.string, please take a look at the > proposed promotion to clojure [1]. Feedback welcome! It is my hope > that this promotion has enough "batteries included" that many libs can > end their dependency on contrib for string functions. > > Cheers, > Stu > > [1]https://www.assembla.com/spaces/clojure/tickets/359-promote-contrib-s... -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
non-monolithic contrib build, starting with matchure
Based on the discussion of release granularity that started with the proposed move of matchure to contrib [1], we are going to start doing granular builds of Clojure. Matchure can be the first: It can be part of the full contrib build, but also released as a standalone library with its own version numbering. Drew: If you want to modify the maven build to support this, I wont' stop you. :-) But you don't have to -- if you just want to add the source code and ping me, I will take care of implementing the build bits. There is an issue for this in the Contrib Assembla [2]. Discussion/ suggestions/feedback welcome! Thanks! Stu [1] http://groups.google.com/group/clojure/browse_thread/thread/58e32801489ef92f/d3f8b7c230e0330a [2] https://www.assembla.com/spaces/clojure-contrib/tickets/85-build-and-release-sublibraries -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Question on bound-fn source
Thank you, now I see the point. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why is MVCC history managed manually?
Hi Rich, > > First, and foremost, it creates interaction relationships between > transactions that otherwise have no overlap. You see this in the > memory blowup during overlapping transactions. This rubs against a > design objective in Clojure's STM to absolutely minimize transactional > overlap and interaction. Fair enough. > > Second, you do a lot of work in createNewTransaction (get a new > timestamp, modify existing head, make new transaction the head). How > is that made consistent? You really need a lock, and at that point > have moved to a much heavier contention point than in the current > Clojure STM. I don't think that's right. I can do most of it with CAS. I need to the list pointer afterwards but only 1 thread ever sets it and it's never read. Well, it's been running tests an i7 without showing any issues so far. > > Third, I'm wary of such extensive use of WeakReferences. That may just > be conservatism on my part. It's a fair point, you have to be careful with WeakReferences, they have a habit of disappearing between uses. > > I had considered and implemented similar designs in the early stages > of developing Clojure's STM, and, while they have some appeal, I think > these 3 points will eventually cause pain in practice. Thanks, I thought you would have considered it but wasn't sure why you went the direction you did. I think it just shows how lazy I am in not wanting to write the code to manage the lists. I appreciate your response. Regards, Peter -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
Stu, What happened to *not* promoting string? Changed our mind. It helps keep the people with prerelease books busy. ;-) Seriously: I did an audit of several third-party libraries, and concluded that for some libs, the presence of these string functions in core could be the make-or-break difference in needing to depend on contrib. Obviously a slippery-slope argument, but it seemed worth it. http://groups.google.com/group/clojure-dev/browse_thread/thread/e294cd444227 Also, is there an actual patch/diff to review? I didn't see one in Assembla. No -- taking time to get feedback. It will be a simple patch though. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
Are these going to be in their own namespace (clojure.string), or in core? I hope the former, because many of these names (replace, reverse, join, split) are too valuable to be dedicated only to strings. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
Definitely! It will be clojure.string. Ticket updated to reflect this. Are these going to be in their own namespace (clojure.string), or in core? I hope the former, because many of these names (replace, reverse, join, split) are too valuable to be dedicated only to strings. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
Stu Halloway, Changes like this are a nuisance as a documentation guy >:| It makes Beta seem further away, but it's a tough call and someone has to make it. Such is life on the edge. As far as technical feedback goes, it seems like a VERY useful list to promote to core. There are a few things I'd tweak: I'd like to see a specific proposal for replace & replace-first. Stuart Sierra put a lot of effort into getting those fns the way they are in contrib, and we should be careful to not undo any lessons learned in the process. Also, this may beg a few questions about new seq fns existing in core, depending on the implementation. You also mention making the string argument first in some of these fns. I believe Will Smith's catch phrase says it best: "Aw hell no". String fns are like any other seq fn, and they need to be partial'ed, comp'ed and chained appropriately. I can't even begin to count the number of point free string processing routines I have. Overall, this is exciting. We're getting close to making "String Processing Kick Ass in Clojure". Sean On May 26, 11:46 am, Stuart Halloway wrote: > > Stu, > > What happened to *not* promoting string? > > Changed our mind. It helps keep the people with prerelease books > busy. ;-) Seriously: I did an audit of several third-party libraries, > and concluded that for some libs, the presence of these string > functions in core could be the make-or-break difference in needing to > depend on contrib. Obviously a slippery-slope argument, but it seemed > worth it. > > >http://groups.google.com/group/clojure-dev/browse_thread/thread/e294c... > > > Also, is there an actual patch/diff to review? I didn't see one in > > Assembla. > > No -- taking time to get feedback. It will be a simple patch though. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
> Changed our mind. It helps keep the people with prerelease books > busy. ;-) Oh great! I'm going to have to cancel my appearance on "The View" because of this. I have mentioned my gripes in the IRC, but for public view I would love better names for chomp and chop. In isolation those names are meaningless, so I suggest: chomp => rtrim (rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the door open for trim and ltrim functions should the need arise. chop => less (less "foo") => "fo" (less "foo" 2) => "f" With less becoming (defn ^String less "Cuts n characters from the end of a string returning the resulting string. If the number of cuts is greater than the string length, then nothing happens. When the number of cuts is not supplied, then the last character is dropped." ([^String s] (less s 1)) ([^String s n] {:pre [(pos? n)]} (let [cuts (- (count s) n)] (if (neg? cuts) s (subs s 0 cuts) (or http://paste.lisp.org/display/100521 if this is flubbed) :f -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
> chomp => rtrim > (rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the > door open for trim and ltrim functions should the need arise. I like this. And in general I often fine the entire trio useful, and adopting the ltrim/trim/rtrim naming makes it nice and tidy. While I recognize the perl (or whatever the original is) precedent from chomp/chop, there is precedent for trim/left trim/right trim too. What *would* one call trim/ltrim to make them consistent with chomp? -- / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
On May 26, 8:16 am, Stuart Halloway wrote: > If you are a user of clojure.contrib.string, please take a look at the > proposed promotion to clojure [1]. Feedback welcome! It is my hope > that this promotion has enough "batteries included" that many libs can > end their dependency on contrib for string functions. Great to see these bumped into core. But are we now going to have clojure.string, and clojure.contrib.string, with half the string functions in one and half in the other? It's going to be confusing to remember which namespace has which functions (since I often use functions you aren't promoting here), and now I potentially have to depend on two libs instead of just one. split-lines (for example) is something I use constantly. It's also something just annoying/error-prone enough that I don't want to write (split #"\r?\n" s) over and over. I always trip over core's line-seq because it takes a reader instead of a string as I'd expect. It'd be nice to see that one promoted, if split is being promoted too. What's the point of promoting upper-case and lower-case? I thought Clojure generally avoided thin wrappers around Java methods. I always use the Java methods directly, personally. The comments say it's for mapping over a list of strings, but (map #(.toUpperCase %) xs) isn't that much typing. The only use I see for making these a Clojure function is to improve error-handling. (upper-case nil) gives an unhelpful NPE. --Brian -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
On Wed, 26 May 2010 19:47:25 +0200 Peter Schuller wrote: > > chomp => rtrim > > (rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the > > door open for trim and ltrim functions should the need arise. > > I like this. And in general I often fine the entire trio useful, and > adopting the ltrim/trim/rtrim naming makes it nice and tidy. > > While I recognize the perl (or whatever the original is) precedent > from chomp/chop, there is precedent for trim/left trim/right trim too. > What *would* one call trim/ltrim to make them consistent with chomp? Personally, I like the lstrip/strip/rstrip, but that's just because I'm used to them. http://www.mired.org/consulting.html Independent Network/Unix/Perforce consultant, email for more information. O< ascii ribbon campaign - stop html mail - www.asciiribbon.org -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
> Personally, I like the lstrip/strip/rstrip, but that's just because > I'm used to them. strip is fine too IMO; I'm neutral between *strip and *trim. -- / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
On May 26, 10:29 am, Fogus wrote: > I have mentioned my gripes in the IRC, but for public view I would > love better names for chomp and chop. In isolation those names are > meaningless, so I suggest: Almost every name in a programming language is meaningless in isolation. But we don't work in isolation. Look at "slurp". I had to explain that one to a non-programmer colleague the other day. "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell- scripting. "rtrim" in isolation could mean trim newlines, or trim whitespace, or trim some specified characters, or trim arbitrary characters. "less" is so generic it could mean almost anything. But this is largely an aesthetic question and I'm not going to lose sleep if we end up with a word other than "chomp". --Brian -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
> "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell- > scripting. Believe me I can sympathize with this, but just because they are well- known to some doesn't mean that they are good names. On that note, just because rtrim and less make sense to me... you know the rest. :-) :f -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
question about agent implementation
I'm preparing a presentation about asynchronous concurrency in Clojure, and I'm planning on talking a bit about how Clojure's constructs make good, sensible use of Java's concurrency libraries. My question is about clojure.lang.Agent. In the doRun method, I'm missing what prevents a race condition in the updating of the agent's state variable. This code in doRun seems to be a classic read-and-write operation: Object oldval = action.agent.state; Object newval = action.fn.applyTo( RT.cons(action.agent.state, action.args)); action.agent.setState(newval); doRun is not synchronized. As far as I can tell, Executors don't synchronize the execution of runnable objects. What am I missing? BTW, I have to say, it's really fun to read the Java code in src/jvm/ clojure. Cheers, Michael -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
If you're developing a trio, like ltrim, trim, rtrim, wouldn't it be better to call them triml, trim, trimr so that they show up next to each other in the alphabetized documentation? -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
On Wed, 2010-05-26 at 13:57 -0400, Mike Meyer wrote: > On Wed, 26 May 2010 19:47:25 +0200 > Peter Schuller wrote: > > > > chomp => rtrim > > > (rtrim "foo\n") => "foo" is much more clear to me, plus it leaves the > > > door open for trim and ltrim functions should the need arise. > > > > I like this. And in general I often fine the entire trio useful, and > > adopting the ltrim/trim/rtrim naming makes it nice and tidy. > > > > While I recognize the perl (or whatever the original is) precedent > > from chomp/chop, there is precedent for trim/left trim/right trim too. > > What *would* one call trim/ltrim to make them consistent with chomp? > > Personally, I like the lstrip/strip/rstrip, but that's just because > I'm used to them. Why not lpluck, pluck and rpluck then ? (in French, pluck => effeuiller and the name effeuilleuse is one of the synonyms for stripteaser :))) ltrim & co.intents are a bit more precise Luc :))) > -- > Mike Meyerhttp://www.mired.org/consulting.html > Independent Network/Unix/Perforce consultant, email for more information. > > O< ascii ribbon campaign - stop html mail - www.asciiribbon.org > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: question about agent implementation
> question is about clojure.lang.Agent. In the doRun method, I'm missing > what prevents a race condition in the updating of the agent's state > variable. Unless I am misunderstanding the context in which the code runs, I believe it is correct because doRun() is guaranteed never to run concurrently (because agents mutate state by function application in a serialized fashion). If I understand it correctly (and someone correct me if I'm wrong), enqueue() is the initial entry point to execution. It will trigger execution if the agent was not already running and had nothing queued. doRun() itself keeps itself running until it manages to empty the queue, at which point a future enqueue() will once again re-start execution. -- / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: matchure becoming clojure.contrib.match
Good point Ben. That change was obviously ill-conceived. On May 25, 7:16 am, B Smith-Mannschott wrote: > On Mon, May 24, 2010 at 05:41, Drew Colthorp wrote: > > A few weeks ago I announced a pattern matching library called > >matchure. I'm excited to say it's being merged into clojure.contrib as > > clojure.contrib.match. I'd like some feedback on ideas for some > > backward-incompatible changes I'm planning to make before it's > > actually pushed to clojure.contrib. > > > In the discussion below, I'll use "matchure" when I'm speaking of the > > current behavior, and "clojure.contrib.match" when I'm describing > > proposed behavior of the library when it's merged in. See > >http://github.com/dcolthorp/matchure/blob/master/README.mdfor an > > introduction tomatchureand the existing syntax, though I'll describe > > the relevant before and after behaviors below. > > > Change 1: {:foo #"bar"} becomes {#"bar" :foo} > > > Inmatchure, maps test against the values of corresponding keys. I'm > > going to change this so that the pattern is first and the key > > second. This makes the behavior closer to let, makes > > clojure.contrib.match more consistent in that patterns will always be > > to the left of the matched value, and patterns like {even? :foo} read > > better. This seems like an easy decision. > > This strikes me as an odd change. Did you overlook the fact that map > keys have to be unique? > > {even? :foo, > even? :bar} > > Might read nicely, but will it work? > > // Ben > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group > athttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
This thread has potential to be the longest thread of clojure mailing list! personally, I like strip or trim than chomp/chop. On Wed, May 26, 2010 at 2:08 PM, Fogus wrote: > > "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell- > > scripting. > > Believe me I can sympathize with this, but just because they are well- > known to some doesn't mean that they are good names. On that note, > just because rtrim and less make sense to me... you know the > rest. :-) > > :f > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
> personally, I like strip or trim than chomp/chop. > +1 Seeing how Clojure dropped/changed many classic Lisp monikers, there is no reason to use comp/chop which may be familiar to somebody with Perl/Python but confusing to others. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Todo item annotation in Clojure.
Thanks to sids, the project now has lein todo functionality. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
I've done Perl coding and I still mix up chomp and chop. The meaning of trim, ltrim, and rtrim is immediately clear to me. trim, ltrim, and rtrim could take an optional argument for characters to strip: (rtrim foo) ;; strip trailing whitespace (rtrim foo "\r\n") ;; equivalent to chomp If clojure.contrib.string/butlast actually mirrored clojure.core/ butlast, it would do the same as chop (c.c.s/butlast requires an extra arg). Justin On May 26, 2:08 pm, Fogus wrote: > > "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell- > > scripting. > > Believe me I can sympathize with this, but just because they are well- > known to some doesn't mean that they are good names. On that note, > just because rtrim and less make sense to me... you know the > rest. :-) > > :f -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: question about agent implementation
> Unless I am misunderstanding the context in which the code runs, I Which I was. Please ignore my previous post (sorry, think before I post... think before I post...) and consider me joined in the OP's question. -- / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Announcing Clojure/core
Very cool. The website doesn't say... how was/is the Clojure/core team selected? Are they all Relevance employees, or freelance? Do you plan on ever bringing more people on board? Although I'm not quite as qualified as some of the others, that's something I'd potentially be very interested in, particularly since the book Stuart and I wrote is now out... -Luke On May 25, 8:30 am, Rich Hickey wrote: > I'm happy to announce Clojure/core, a joint endeavor between myself > and Relevance, Inc. Clojure/core is a specialized technical practice > within Relevance, focused on Clojure. Featuring myself and Stuart > Halloway as advisors, the team also includes Clojure experts such as > David Liebke (Incanter), Stuart Sierra (clojure-contrib contributor) > and Aaron Bedra (an experienced consultant using Clojure). > > The practice will be providing mentorship, training and development > services for those using, or planning to use, Clojure, and sustaining > Clojure itself. > > Not interested in Clojure mentorship, training or dev assistance? > There's still plenty of good news for the Clojure community in this > announcement. One of the missions of Clojure/core is the > sustainability of Clojure. The team will spend 20% of its time on > Clojure itself. This includes working on enhancements and tickets, > incorporating patches, helping tend the mailing list etc. This will > enable our team to get a lot more done than I could ever do myself, > while enabling me to focus on the fundamental aspects of Clojure. It > will also broaden the pool of people with intimate knowledge of the > internals of Clojure. > > The availability of services such as this is an important milestone > for Clojure, as people choosing to adopt Clojure can be assured they > can get mentorship, training and dev assistance, from experts. > > I'm very excited about this effort. The folks at Relevance have never > failed to impress me with their skills and attitude, and they truly > get Clojure and care about its sustainability. > > Note: clojure.com will now resolve to the Clojure/core site. Come > check it out! > > http://clojure.com > > Rich > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group > athttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: question about agent implementation
>> Unless I am misunderstanding the context in which the code runs, I > > Which I was. Please ignore my previous post (sorry, think before I > post... think before I post...) and consider me joined in the OP's > question. And every time this happens I wonder if I should just leave it to avoid flooding with responses further, or follow-up yet again, risking the realization that I have to take something back *again*. I think I was confused the second time and right the first. But to elaborate on my first post to clarify: As far as I can tell, execute() is only ever called by enqueue() and enqueue() will only ever call execute() if the queue was non-empty when the action was enqueued using the compareAndSet(). Further, if it *was* empty, it always calls execute(). doRun() itself does a similar compareAndSet() loop and *always* executes itself if the queue is non-empty. The resulting behavior is that any CAS loop that ends with the realization that there was something already there to execute, leads to said action being executed if needed. In the case of doRun() this is accomplished by calling execute() itself - since doRun() is the one already being executed, it knows it is done and that scheduling one more action will lead not lead to a >1 concurrency level. In the case of enqueue(), it either does nothing (if there was *already* something there), or schedules the execution if the enqueue() invocation was responsible for making the queue non-empty. In either case, the concurrency level can never go above 1. (I find this to be a very interesting use-case for immutable data structures btw... it allows a complex data structure, without them in and of themselves doing careful lock-less operations to support concurrency, to be used in combination with simple CAS loops to great effect.) -- / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Anyone experienced in using clojure as a "database"
Clojure is not a great choice for this. It's oriented as a programming language, not a database. It doesn't have any built-in persistence mechanisms, and while it has many virtues, it's a little bit of a memory hog. That isn't really what you want in an in-memory DB. For anything more than a toy app where you don't want to do the work, I think you'll be much more pleased with the results if you hook up a real DB or NoSQL solution. - Luke On May 25, 2:08 pm, Fabio Kaminski wrote: > Folks, > > i would like advice, > cause since im starting something that will be eventually big data > intensive, from scratch > and i really like the options already built in in clojure like STM, > parallelizing data and concurrency logic implemented on it > i think its wonderfully tuned to use as database... and you can achieve > different strategies, like graphs or balanced trees for different data > > my worries are about the efficiency in serializing it and recovering from/to > the disk, > java VM as a hungry heap VM, > (and with immutable strategies, more heap needed) > > the benefits are control of sharding mechanism's and parallelizing not only > in the unit's cores but between nodes of a cluster.. > > anyone using clojure not just as database middleware(wich is perfect for) > but as database backend too? > > Thanks all, > > Fabio Kaminski > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group > athttp://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
The people have spoken! The trims have it! Stu I've done Perl coding and I still mix up chomp and chop. The meaning of trim, ltrim, and rtrim is immediately clear to me. trim, ltrim, and rtrim could take an optional argument for characters to strip: (rtrim foo) ;; strip trailing whitespace (rtrim foo "\r\n") ;; equivalent to chomp If clojure.contrib.string/butlast actually mirrored clojure.core/ butlast, it would do the same as chop (c.c.s/butlast requires an extra arg). Justin On May 26, 2:08 pm, Fogus wrote: "chomp" has a clear meaning to anyone who's touched Perl/Ruby/shell- scripting. Believe me I can sympathize with this, but just because they are well- known to some doesn't mean that they are good names. On that note, just because rtrim and less make sense to me... you know the rest. :-) :f -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
On May 26, 12:42 pm, Sean Devlin wrote: > I'd like to see a specific proposal for replace & replace-first. > Stuart Sierra put a lot of effort into getting those fns the way they > are in contrib, and we should be careful to not undo any lessons > learned in the process. Yes, originally replace and replace-first were multimethods. But that's too slow for string routines, which tend to be called often. The type-specific replace-* and replace-first-* functions are carefully optimized. -Stuart -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Some suggestions for transients
Hi! I have some suggestions about transients (btw. the http://clojure.org/transients is not linked from http://clojure.org). Maybe before you give up reading the whole post I will post as first the digression: vars binding and transient are similar, however in the first case we have thread isolation on reading and writing with reference covering/ hiding ability. Currently operations on transients structures seems to be badly interfaced in Clojure and below is a deal: Why do we have to deal with conj! and rest of foo! operations, when there are much more functions like update-in, assoc-in etc. what about them? In most my code I fail to use transient because of xyz-in operations. More over I know that the code is whole executed by one thread, since I know where the transient structure starts to exist and when it ends. Tracking such code is easy task to do since most fast compuations are free of side effects and thread intercommunication. If the whole talk is about thread isolation (which is great feature), then the interface should be simplified, in the way like - (transient x) - attaches thread (which calls transient) reference to my structure (object), when any other thread tries to modify x then the exception is thrown. When I do (persistent x), the thread reference is detached from the structure, so it becomes persistent and others threads can concurrently modify it. This would eleminate duplication of functions and allow for single threaded computations. This would satisfy most computations related with reduce operation and recurention. So easy to do, so easy to track, yet not in Clojure ;-(. The (transient x) and (persistent x) are required since the are explicit declaration of single thread mutation. Also it would be nice if such transient structures could be used in binding clasues, since I have found other adoption - for example thread is doing computations in a functional way - and with binded transients I'm gathering statistics (time measurement, bytes counting etc. in an imperative, side effecting, more like aspect way.) What are your thoughts? Thanks, BTW. What does it mean "don't bash in place" - since for not all people English is not a native language I suggest to use simpler words in such formulations. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: question about agent implementation
Thanks for your post, Peter. I'm tracing the code, and it's interesting. The interesting point is definitely the agent's aq member, the AtomicReference that wraps an ActionQueue. The aq.compareAndSet call keeps the value of the ActionQueue from switching out form under us while we attempt to set aq to a new ActionQueue wrapping a PersistentQueue that contains the agent's action -- the compareAndSet will be retried if it returns false. As I read the end of Agent's enqueue method, the action is only told to execute if the ActionQueue's PersistentQueue was empty before the compareAndSet and the ActionQueue is free of errors. I also see where Agent's static doRun method will pop an action off the agent's queue and execute the action. Where is Action's execute method called in the event the queue is not empty? Michael On May 26, 4:28 pm, Peter Schuller wrote: > >> Unless I am misunderstanding the context in which the code runs, I > > > Which I was. Please ignore my previous post (sorry, think before I > > post... think before I post...) and consider me joined in the OP's > > question. > > And every time this happens I wonder if I should just leave it to > avoid flooding with responses further, or follow-up yet again, risking > the realization that I have to take something back *again*. > > I think I was confused the second time and right the first. But to > elaborate on my first post to clarify: > > As far as I can tell, execute() is only ever called by enqueue() and > enqueue() will only ever call execute() if the queue was non-empty > when the action was enqueued using the compareAndSet(). Further, if it > *was* empty, it always calls execute(). > > doRun() itself does a similar compareAndSet() loop and *always* > executes itself if the queue is non-empty. > > The resulting behavior is that any CAS loop that ends with the > realization that there was something already there to execute, leads > to said action being executed if needed. In the case of doRun() this > is accomplished by calling execute() itself - since doRun() is the one > already being executed, it knows it is done and that scheduling one > more action will lead not lead to a >1 concurrency level. In the case > of enqueue(), it either does nothing (if there was *already* something > there), or schedules the execution if the enqueue() invocation was > responsible for making the queue non-empty. > > In either case, the concurrency level can never go above 1. > > (I find this to be a very interesting use-case for immutable data > structures btw... it allows a complex data structure, without them in > and of themselves doing careful lock-less operations to support > concurrency, to be used in combination with simple CAS loops to great > effect.) > > -- > / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: question about agent implementation
> Where is Action's execute method called in the event the queue is not > empty? If the agent's queue was non-empty from the perspective of enqueue(), that means one of the following is true: (1) A previous enqueue() has already scheduled the execution of an action, but it has not yet begun running. (2) doRun() is running but has not yet completed its CAS loop at the end. In either case, once doRun() runs and reaches its CAS loop, it will detect that the queue is non-empty and schedule the next action. This is the: if(error == null && next.q.count() > 0) ((Action) next.q.peek()).execute(); } which appears towards the end of doRun(). Next is the atomically obtained (through CAS looping) queue, after it popped itself. Another way to look at it might be that the queue can be in two relevant states at any point in time: * empty * non-empty In the non-empty state, doRun() is continuously responsible for re-scheduling itself. In the empty state, enqueue() is responsible for scheduling it. Because of the use of CAS loops, the transition from "empty" to "non-empty" can be atomically detected by enqueue(), allowing it to determine whether or not it was responsible for such a state transition, in which case it schedules the action for execution. -- / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: question about agent implementation
OK, chouser gave me the explanation on IRC. It's amazing that we can pop into #clojure and there's one of the two people who've touched this file. Thanks, chouser! The compareAndSet (CAS) that protects the agent's queue from overlapping updates forces the agent's actions into serial execution. When enqueue determines the queue has gone from 0 items to 1 item, it starts a chain of executions: at the end of execute, if another action can be popped off the queue (CAS again) then it is, and it is executed. That execution will repeat the attempt to execute the next action, if any, on the queue. If the queue was already non-zero in size, there is guaranteed to be an execution underway that will in time trigger the new action's execution, so no explicit execute call is needed. The CAS on the queue, and the placement of calls to execute only in enqueue and execute itself, force an agent's actions to execute serially, without any locks. Sweet! Cheers, Michael On May 26, 5:23 pm, "Michael Harrison (goodmike)" wrote: > Thanks for your post, Peter. I'm tracing the code, and it's > interesting. > > The interesting point is definitely the agent's aq member, the > AtomicReference that wraps an ActionQueue. > > The aq.compareAndSet call keeps the value of the ActionQueue from > switching out form under us while we attempt to set aq to a new > ActionQueue wrapping a PersistentQueue that contains the agent's > action -- the compareAndSet will be retried if it returns false. > > As I read the end of Agent's enqueue method, the action is only told > to execute if the ActionQueue's PersistentQueue was empty before the > compareAndSet and the ActionQueue is free of errors. > > I also see where Agent's static doRun method will pop an action off > the agent's queue and execute the action. > > Where is Action's execute method called in the event the queue is not > empty? > > Michael > > On May 26, 4:28 pm, Peter Schuller > wrote: > > > >> Unless I am misunderstanding the context in which the code runs, I > > > > Which I was. Please ignore my previous post (sorry, think before I > > > post... think before I post...) and consider me joined in the OP's > > > question. > > > And every time this happens I wonder if I should just leave it to > > avoid flooding with responses further, or follow-up yet again, risking > > the realization that I have to take something back *again*. > > > I think I was confused the second time and right the first. But to > > elaborate on my first post to clarify: > > > As far as I can tell, execute() is only ever called by enqueue() and > > enqueue() will only ever call execute() if the queue was non-empty > > when the action was enqueued using the compareAndSet(). Further, if it > > *was* empty, it always calls execute(). > > > doRun() itself does a similar compareAndSet() loop and *always* > > executes itself if the queue is non-empty. > > > The resulting behavior is that any CAS loop that ends with the > > realization that there was something already there to execute, leads > > to said action being executed if needed. In the case of doRun() this > > is accomplished by calling execute() itself - since doRun() is the one > > already being executed, it knows it is done and that scheduling one > > more action will lead not lead to a >1 concurrency level. In the case > > of enqueue(), it either does nothing (if there was *already* something > > there), or schedules the execution if the enqueue() invocation was > > responsible for making the queue non-empty. > > > In either case, the concurrency level can never go above 1. > > > (I find this to be a very interesting use-case for immutable data > > structures btw... it allows a complex data structure, without them in > > and of themselves doing careful lock-less operations to support > > concurrency, to be used in combination with simple CAS loops to great > > effect.) > > > -- > > / Peter Schuller > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: question about agent implementation
Thanks for the explanation, Peter, and for accompanying me on this journey into the unknown. Your description of enqueue is what chouser explained to me too. Someday I have to write some code with a queue named eat so that eat will pop itself. Cheers, Michael On May 26, 5:54 pm, Peter Schuller wrote: > > Where is Action's execute method called in the event the queue is not > > empty? > > If the agent's queue was non-empty from the perspective of enqueue(), > that means one of the following is true: > > (1) A previous enqueue() has already scheduled the execution of an > action, but it has not yet begun running. > (2) doRun() is running but has not yet completed its CAS loop at the end. > > In either case, once doRun() runs and reaches its CAS loop, it will > detect that the queue is non-empty and schedule the next action. This > is the: > > if(error == null && next.q.count() > 0) > ((Action) next.q.peek()).execute(); > } > > which appears towards the end of doRun(). Next is the atomically > obtained (through CAS looping) queue, after it popped itself. > > Another way to look at it might be that the queue can be in two > relevant states at any point in time: > > * empty > * non-empty > > In the non-empty state, doRun() is continuously responsible for > re-scheduling itself. In the empty state, enqueue() is responsible for > scheduling it. Because of the use of CAS loops, the transition from > "empty" to "non-empty" can be atomically detected by enqueue(), > allowing it to determine whether or not it was responsible for such a > state transition, in which case it schedules the action for execution. > > -- > / Peter Schuller -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
labrepl dependencies
Hi all, The instructions on the labrepl git page says to "download missing dependencies" of the labrepl. For some reason I cannot download them in NetBeans running on Ubuntu 10.04. Can I also just download them manually one by one? If so, what, specifically, are the dependencies that the labrepl requires? Thanks for your help. If I am using the wrong forum, please advise. Harrison. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: API in Clojure for Java folklore
Hi all, Inspired by Erik above, I've written a macro: gen-class+javadoc (http://gist.github.com/415269). It works quite well for me on Windows XP. For *nix, I think people will have to make at least one change - the shell command (at line 57). What it does - 1. Generates a javadoc for your API made using gen-class. How to use - 1. Just use gen-class+javadoc macro instead of the gen-class macro. _No other changes are required by the coder_. Functioning - 1. It calls gen-class first as usual with the args. 2. Generates a .java file containing the javadoc. 3. Runs the javadoc command and generates docs in the doc/ directory. 4. Deletes the .java file created above. Few points to note - 1. It is by no means complete. For eg. it doesn't handle interface related stuff yet. 2. It uses macroexpand inside a macro, but some people on Clojure# pointed out that this is not recommended. I'm very new to macro-foo, so please let me know of the alternatives. 3. The macro itself contains a lot of side effects, dunno if this is a very big issue. Try it out if you expose an API through gen-class. Any comments / suggestions / critiques are welcome. - Thanks -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: labrepl dependencies
Hi Harrison. Welcome! I am not familiar with netbeans but reading the labrepl instructions it appears that dependencies will auto resolve. Is there an error? Any more info? On May 26, 5:34 pm, Harrison Maseko wrote: > Hi all, > The instructions on the labrepl git page says to "download missing > dependencies" of the labrepl. For some reason I cannot download them > in NetBeans running on Ubuntu 10.04. Can I also just download them > manually one by one? If so, what, specifically, are the dependencies > that the labrepl requires? > Thanks for your help. If I am using the wrong forum, please advise. > > Harrison. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: promoting contrib.string to clojure, feedback requested
Mark Engelberg writes: > If you're developing a trio, like ltrim, trim, rtrim, wouldn't it be > better to call them triml, trim, trimr so that they show up next to > each other in the alphabetized documentation? +1 for modifiers at the end Let's not forget those of us who search for functions using tab-completion in the repl. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: labrepl dependencies
Harrison, Use leiningen (http://github.com/technomancy/leiningen) and then run "lein deps" at your command line. -- Paul Hobbs On Wed, May 26, 2010 at 11:34 PM, Harrison Maseko wrote: > Hi all, > The instructions on the labrepl git page says to "download missing > dependencies" of the labrepl. For some reason I cannot download them > in NetBeans running on Ubuntu 10.04. Can I also just download them > manually one by one? If so, what, specifically, are the dependencies > that the labrepl requires? > Thanks for your help. If I am using the wrong forum, please advise. > > Harrison. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
NullPointerException on disj
Hey everyone. I was playing around with the protocols/deftype stuff and ran into a weird NullPointerException when calling the satisfies? function. Seems to only happen with a java.lang.Object instance. Clojure 1.2.0-master-SNAPSHOT user=> (defprotocol Greeter (greet [this])) Greeter user=> (satisfies? Greeter nil) false user=> (satisfies? Greeter "") false user=> (satisfies? Greeter (Object.)) java.lang.NullPointerException (NO_SOURCE_FILE:0) Narrowed it down to this function: ;; core_deftype.clj (defn find-protocol-impl [protocol x] (if (instance? (:on-interface protocol) x) x (let [c (class x) impl #(get (:impls protocol) %)] (or (impl c) (and c (or (first (remove nil? (map impl (butlast (super-chain c) (when-let [t (reduce pref (filter impl (disj (supers c) Object)))] (impl t)) (impl Object))) More specifically, here: (disj (supers c) Object) Since in this case, `c` is java.lang.Object, supers returns nil which disj doesn't seem to like. Shouldn't disj handle nil gracefully? Thanks, Allen -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en