Re: struct question
On Jan 21, 11:48 pm, Mark Engelberg mark.engelb...@gmail.com wrote: Thanks for the thread links. This is basically what I suspected -- if you want to use structs in multimethods, you have to roll your own constructor which adds some kind of type tag to either the hashmap or the metadata. It just seems like a common case, so I was hoping there was a more convenient way. But I guess that's what macros are for... In that vein, there's this thread: http://groups.google.com/group/clojure/browse_thread/thread/257caab7867aa09c?hl=en# which may do something like what you would like. This is also an issue I'm interested in, and I was planning on making some group/blog posts about it in the near future. FYI, I usually follow the following pattern: My interface files contain a bunch of (defmulti ...)s, which mostly dispatch on the :class of the first argument Then, my class files contain (derive ::MyClass :namespace/ParentClass) (defstruct my-class :class :a :b :c) (defn make-my-class [a b c] (struct my-class ::MyClass a b c)) followed by a bunch of (defmethod ...)s But this does involve a bit of repetition, and I'm not sure if this is the most idiomatic way to do things currently. -Jason --~--~-~--~~~---~--~~ 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 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: struct question
On 22.01.2009, at 07:48, Mark Engelberg wrote: Is there any way to determine whether something is a struct (versus an ordinary hash map), and if so, determine which kind of struct it was built from? Not that I know. I have been searching for a while, and ended up using my own tag attached to the struct as metadata. In clojure.zip there is a similar use of metadata: methods are implemented as functions passed in the metadata. I am not entirely happy with this approach though. If everyone starts to use metadata for various purposes, such type tags may well disappear by some function replacing the metadata on an object without preserving the tags that are already there. This is all the more likely because there is nothing in the standard library to add a tag to an existing metadata map. All there is is (with-meta ...), which replaces the metadata map completely. Konrad. --~--~-~--~~~---~--~~ 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 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: struct question
Finally started a GitHub repo just for this project. http://github.com/swannodette/cljos/tree/master The earlier version of course was very flawed/buggy. OK start, but the macros in it were written with little/no understanding about how symbols are resolved into their namespaces in Clojure (or Lisp for that matter). If anybody is interested at all please feel free to fork or to leave comments. In particular I found no way to capture the symbols and their true namespaces without resorting to eval and some wacky macros. That said, it does indeed work. defclassed structs always refer to the namespace in which they were declared, and parents correctly reflect their originating namespace as well. New stuff: (instance-of? my-platypus platypus) (member-of? a-circle shape) No need for tags. The only time you need tags is when defining multimethods. There's no real clean way to get around this except implementing a macro around defmethod, and I'm not really sure creating a macro around defmethod is so hot. The discussion earlier about multiple hierarchies for multimethod, especially predicate support would solve this cleanly. defclass now returns the struct. I've also been toying around with an optional Smalltalk message based dispatch. Note the special applym, a special version of apply that first checks to see if a struct responds? to a multimethod. If not it checks to see if there is a proxy and forwards the message with the args to proxy. This could allow for some interesting interactions. (defclass my-spore-animal [platypus] (:third-eye true)) (defclass bacteria [object] (:digest-grass true)) (def my-spore (make-instance my-spore-animal)) (def my-parasite (make-instance bacteria)) (defmulti digest :tag) (defmethod digest ::bacteria [obj] (println Munch munch!)) ;; we can pass messages to a proxy class (applym digest (assoc my-spore :proxy my-parasite)) ;; Munch Munch! The most exciting thing however is multimethod reflection (many thanks to Rich). The following is all the code it takes to see all the multifns that specializes a particular tag. In fact, really it should check all the ancestors of the tag as well in order and I'm open to suggestions on what the best way to implement that would be. (defn has-dispatch? [multifn tag] (not (= (tag (methods multifn)) nil))) (defn responds? [obj multifn] (has-dispatch? multifn (:tag obj))) (defn is-multi? [metadata] (and (:tag metadata) (= clojure.lang.MultiFn (:tag metadata (defn who-specializes-tag? [tag] (filter #(and (is-multi? (meta %)) (has-dispatch? (var-get %) tag)) (flatten (map #(vals (ns-interns %)) (all-ns) (defmacro who-specializes? [constructor] `(who-specializes-tag? (:class (meta (var ~(symbol (name constructor))) --~--~-~--~~~---~--~~ 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 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: struct question
I am not entirely happy with this approach though. If everyone starts to use metadata for various purposes, such type tags may well disappear by some function replacing the metadata on an object without preserving the tags that are already there. This is all the more likely because there is nothing in the standard library to add a tag to an existing metadata map. All there is is (with-meta ...), which replaces the metadata map completely. Konrad. Permanently changing the tag of an object after instantiation probably isn't such a safe thing to do anyway. That's where functions like pose-as and applym can come in handy. --~--~-~--~~~---~--~~ 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 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: struct question
Konrad Hinsen a écrit : there is nothing in the standard library to add a tag to an existing metadata map. All there is is (with-meta ...), which replaces the metadata map completely. It itched me before and since there's already alter-meta! maybe there should also be an alter-meta (or better name) in core.clj. Christophe (defn alter-meta Returns an object of the same type and value as obj, with (apply f (meta obj) args) as its metadata. [obj f args] (with-meta o (apply f (meta o) args))) --~--~-~--~~~---~--~~ 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 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: struct question
On 22.01.2009, at 09:30, Konrad Hinsen wrote: Not that I know. I have been searching for a while, and ended up using my own tag attached to the struct as metadata. In clojure.zip there is a similar use of metadata: methods are implemented as functions passed in the metadata. After a quick look at the Clojure source code, I had an idea for implementing something better, and did it :-) A patch is attached. This patch adds: - a Java method on structmaps that returns the structure basis (the object created by defstruct). - a few Clojure functions to work with this: (struct-basis x) returns the structure basis of structmap x (struct? x) returns true if x is a structmap (struct? x s) returns true if x is a structmap with basis s (struct-basis? s) returns true if s it a structure basis - a minimal patch to derive that allows structure basis objects to be used in hierarchies At the end of this message is a simple illustration of what can be done with these changes. Any feedback is welcome of course! Konrad. (defstruct rectangle :x :y :w :h) (defstruct circle :x :y :r) (defmulti area struct-basis) (defmethod area rectangle [r] (* (:w r) (:h r))) (defmethod area circle [c] (let [r (:r c)] (* (. Math PI) r r ))) (area (struct rectangle 0. 0. 2. 3.)) (area (struct circle 0. 0. 1.)) (derive rectangle ::shape) (derive circle ::shape) (defmulti center struct-basis) (defmethod center ::shape [s] [(:x s) (:y s)]) (defmethod center rectangle [r] (let [{:keys [x y w h]} r] [(/ (+ x w) 2) (/ (+ y h) 2)])) (center (struct rectangle 0. 0. 2. 3.)) (center (struct circle 0. 0. 1.)) --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~--- structs_in_multimethods.diff Description: Binary data
Re: Clojure Web Libraries
On Jan 21, 9:39 pm, Frank ffai...@gmail.com wrote: I am interested in trying to use Clojure to develop web-based applications. Can someone point me to any Clojure libraries that have been written that I can use. Thanks. There's Compojure, which looks like this: (defservlet demo-servlet (GET / (html [:h1 Hello World])) ( http://github.com/weavejester/compojure ) Weld, which I believe looks like this (Mark, please correct me if I've misrepresented Weld): (def config {'weld.routing/*router* (compiled-router [['index-page :index :get /]])}) (defn index-page [req] (respond (html [:h1 Hello World]))) ( http://github.com/mmcgrana/weld ) And Webjure, which looks like this: (defh / [] {:output :html} `(:h1 Hello World)) ( http://code.google.com/p/webjure ) Out of the three frameworks, it's possible that Compojure is the most popular: at least, I've seen more tutorials and sites written with it. But since I'm the author of Compojure, I can't exactly claim I'm unbiased :) - James --~--~-~--~~~---~--~~ 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 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: struct question
On 22.01.2009, at 10:51, Konrad Hinsen wrote: At the end of this message is a simple illustration of what can be done with these changes. Any feedback is welcome of course! Maybe I should reply immediately to some objections I expect to come: 1) Why create a secondary type system around structs? Why not something more general? Many languages have type system grown out of structures, e.g. C++, or Scheme. It works pretty well. I'd happily propose something more general if I had a great idea. In the meantime, there is a real need for something like a type system for use with multimethods, as the topic comes up repeatedly on this group. It looks strange to see a language in which it is easy to define a type hierarchy (using derive) but in which putting the type label on an object is a pain. 2) Using metadata is more general. A bit, but metadata is limited to collections as well. Moreover, it is used for many different applications, which creates the risk of conflicts. Finally, it is invisible (not part of the printed representation) and not used in comparisons etc. It is not considered part of the value of a data item, whereas type information normally *is* part of the value, even an important one. 3) Structmaps are just an optimized implementation of maps. That's what they are now, but that doesn't mean they can't evolve into something else. For structs to become an official type system, some more changes would be useful: - Structure basis objects should have a printed representation that includes the name given in defstruct (or nil for an anonymous one created by create-struct) - Structure basis objects could acquire some methods, e.g. for obtaining the keys. Konrad. --~--~-~--~~~---~--~~ 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 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: Agent as a processing queue
Thanks Tim, I'll have a look at that. To clarify my use case, I was thinking of events that can be processed sequentially but that may take a non-trivial amount of time to complete (both CPU and IO bound at different stages of processing) so it's ideal to have a thread pool to process different tasks in parallel, even though they are independent. (That's step one. Step two will be spreading that thread pool out over multiple JVMs running on different hardware). On Jan 22, 2:39 am, Timothy Pratley timothyprat...@gmail.com wrote: Hi Greg Here is a proof of concept of one approach you could take:http://groups.google.com/group/clojure/web/job-queue.clj A set of agents are maintained to represent computation jobs. When the results are gathered, the agent is thrown away. I think using multiple agents in this way could be quite convenient as it means the jobs can be done in parallel. If you run the script from the command line you should get something like this: C:\javaclj job-queue.clj (4 3) (0 nil Hi mum) Which are the results of multiple queued computations taken at two subsequent points in time. From your post it wasn't clear to me if your 'events' imply sequential processing (which could be achieved with a single agent). Regards, Tim. --~--~-~--~~~---~--~~ 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 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: Gorilla issue with recent builds?
Hi Meikel, On Jan 21, 3:01 pm, Meikel Brandmeyer m...@kotka.de wrote: There was a breakage some time ago, which made it necessary to release a bug fix release. The revisions are named on the vim.org page, where you can download Gorilla. Please check there if this solves your problem. If not, please send me the revisions of clojure and clojure-contrib and the version of Gorilla you are using. I have the 1.1.1 version of Gorilla, yes. I ran some tests and I've determined when it breaks: clojure rev, clojure-contrib rev, vim repl working 1214, 405, yes 1215, 405, no So some change in Clojure from 1214 - 1215 causes the Vim Repl to stop working. The clojure-contrib version appears not to be a factor. I haven't had a chance to dig deeper, but this additional info may shed a bit more light... Thanks, Mark. --~--~-~--~~~---~--~~ 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 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: Streams work
On Jan 22, 12:53 am, Mark H. mark.hoem...@gmail.com wrote: On Jan 21, 5:21 pm, e evier...@gmail.com wrote: I would think it would be useful to have something exactly like a stream but that allowed as many iterators as you like but that a mutex prevented any two from consuming the same piece of information. That might be useful for something, but it's hard to make correct in all cases. The reason is that both stream elements and connections between stream elements are mutable and shared. Here follows an example. Imagine iterating over a singly-linked list, where you delete each node (explicitly, not by losing the reference) _and_ the link to the next node right after you get the next node. (For example, a directory of files might be implemented as a singly-linked list, and you want to delete all the files _and_ the directory itself and print all the files deleted, by only making one pass over the directory.) You could implement this as a generator which is a closure over a let- bound Java object (I've made up some utility function names below): (defn make-dir-gen [dirname] (let [dirstart (directory-list dirname)] (fn [eos] (loop [dirent dirstart] (if (dir-empty? dirent) eos (let [link (next-link dirent)] next (next-entry link)] (delete-file! dirent) (delete-link! link) (recur next))) Now imagine two threads T1 and T2 accessing this generator at the same time. Suppose they reach the same node at the same time, and suppose that you've protected file deletion and link deletion each individually with a mutex (and forbade multiple deletions silently). T1 might delete the file and the link and get to recur next before T2 can call (next-entry link). Now T1 goes on but T2 is stuck: link is _gone_ so (next-entry link) goes nowhere. Protecting the data for access by multiple threads has to be the responsibility of the person implementing the generator function, because a generator function can have arbitrary side effects and iterate over arbitrary mutable data structures with constantly changing topology. (Imagine a generator that goes five times around a circular list, then breaks the circular link and splices the list into another list, leaving a list fragment floating.) It's too hard to try to imagine a streams implementation that could automatically make everything thread-safe, or even to imagine what thread-safe means in the context of general mutable data structures. Those are important things to think about. There are, in fact, thread semantics for the streams mechanism, as for the rest of Clojure. Currently, I've made it such that the stream/iter/ seq combination ensures serialized access to the generator, allowing use of generators over otherwise unsynchronized multi-step activities. Obviously, stream-backed seqs are safe, being persistent and immutable. but it is also currently the case that the stream iter is MT safe as well. All calls to next! on an iter are atomic re: its generator, i.e. no 2 threads can be in the generator code at once. That means that, within a private consumer, you could fire up multiple threads that share the same iter and coordinate to produce a result, and return the result or a stream upon it. Used correctly, this is a powerful feature. However, I'm reluctant to expose/guarantee it, lest people start using iters as connection points and invalidating the whole stream protection model. A well- written API should take/return streams/seqs, never iters, so MT use of an iter should always be an implementation detail of a single stream step. But I can't enforce that. For those looking to experiment with such things, feel free to try it now and provide feedback. Thanks, 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 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: Streams work
Now imagine two threads T1 and T2 accessing this generator at the same time. Suppose they reach the same node at the same time, and suppose that you've protected file deletion and link deletion each individually with a mutex (and forbade multiple deletions silently). T1 might delete the file and the link and get to recur next before T2 can call (next-entry link). Now T1 goes on but T2 is stuck: link is _gone_ so (next-entry link) goes nowhere. hmm. Good point. I'm sure there's a lot to think about, but, at first, that sounds like a challenge. Like now I'm wondering if what you could do is have the generator automatically update the list of handed out iterators automatically. Then I realize you'd have to update eos, too. But the client may already have checked eos. So I see that Rich's idea is more obvious. Rather than making magic streams, he shows how one might do the same thing by sharing a single iterator. --~--~-~--~~~---~--~~ 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 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: Agent as a processing queue
I like the example, and I should be able to adapt it. I do have one question about the example (probably not related to agents: ; queue up some work to be done (defn add-job [func] (let [a (agent nil)] (send a (fn [_] (func))) (swap! jobs #(conj %1 a What is the notation fn [_]? I can't seem to find any documentation for what _ as a function argument means... On Jan 22, 6:14 am, Greg Harman ghar...@gmail.com wrote: Thanks Tim, I'll have a look at that. To clarify my use case, I was thinking of events that can be processed sequentially but that may take a non-trivial amount of time to complete (both CPU and IO bound at different stages of processing) so it's ideal to have a thread pool to process different tasks in parallel, even though they are independent. (That's step one. Step two will be spreading that thread pool out over multiple JVMs running on different hardware). On Jan 22, 2:39 am, Timothy Pratley timothyprat...@gmail.com wrote: Hi Greg Here is a proof of concept of one approach you could take:http://groups.google.com/group/clojure/web/job-queue.clj A set of agents are maintained to represent computation jobs. When the results are gathered, the agent is thrown away. I think using multiple agents in this way could be quite convenient as it means the jobs can be done in parallel. If you run the script from the command line you should get something like this: C:\javaclj job-queue.clj (4 3) (0 nil Hi mum) Which are the results of multiple queued computations taken at two subsequent points in time. From your post it wasn't clear to me if your 'events' imply sequential processing (which could be achieved with a single agent). Regards, Tim. --~--~-~--~~~---~--~~ 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 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: Streams work
On 21.01.2009, at 20:33, Rich Hickey wrote: I've started documenting the streams work I have been doing, for those interested: http://clojure.org/streams Nice! I have played a bit with the stream implementation, and I came across a behaviour that I do not understand: First, define a random stream that calls rand, and an iter on it: (def rand-stream (stream (fn [_] (rand (def rand-iter (stream-iter rand-stream)) Calling it a few times shows that it works: (next! rand-iter nil) (next! rand-iter nil) Next, try to use it as a seq: (take 4 rand-stream) This fails, as it should: java.lang.IllegalStateException: Already iterating (NO_SOURCE_FILE:0) Detach the iter and try again: (detach! rand-iter) (take 4 rand-stream) Now it works - fine. But what happened to the seq that now owns the stream? Nothing refers to it, so it should be gone. Did it perhaps liberate the stream, so that I can create an iter again? Let's try: (def rand-iter (stream-iter rand-stream)) (next! rand-iter nil) (next! rand-iter nil) It seems so. But... let's be mean: (take 4 rand-stream) I would expect this to throw the IllegalStateException again, but it doesn't: it returns the same four-number sequence as the last time it was called. Where was that one stored? In the stream itself? Or does the stream keep a reference to the seq, so that it never disappears? But then I shouldn't be able to create another iterator. Let's be mean again: (next! rand-iter nil) (take 10 rand-stream) (next! rand-iter nil) (next! rand-iter nil) (take 15 rand-stream) All of these work - it seems I have both an iter and a seq on the same stream, with the iter returning values that are also in the seq. Konrad. --~--~-~--~~~---~--~~ 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 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: struct question
On Jan 22, 4:46 am, Christophe Grand christo...@cgrand.net wrote: Konrad Hinsen a écrit : there is nothing in the standard library to add a tag to an existing metadata map. All there is is (with-meta ...), which replaces the metadata map completely. It itched me before and since there's already alter-meta! maybe there should also be an alter-meta (or better name) in core.clj. Me too. I've added vary-meta in SVN 1223. 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 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: printing deeply nested things
Hi Rich, It is a small real problem: in the book I demonstrate an incorrect, stack-consuming recursion that blows up on a deeply nested structure. When the recursion is fixed, it *still* blows up because the REPL cannot print it, so I introduce *print-level*. I don't think printing super-deep structures at the REPL is particularly important, but I am curious how you would go about implementing it. Stuart On Jan 21, 8:43 pm, Stuart Halloway stuart.hallo...@gmail.com wrote: Consider the function deeply-nested: (defn deeply-nested [n] (loop [n n result [:bottom]] (if (= n 0) result (recur (dec n) [result] If you print it at the REPL for small values of n, no problem: (deeply-nested 25) - [[:bottom]] But for large values of n: (deeply-nested 100) - java.lang.StackOverflowError You can dodge this problem by setting *print-level* (set! *print-level* 25) - 25 (deeply-nested 100) - [#] But what if you really want to print a deeply nested structure? What is the simplest modification to core_print.clj that gets the job done? Is this a good use case for trampoline, or is there a better Clojurish way? Is this a real problem or a theoretical one? 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 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: Agent as a processing queue
On Thu, Jan 22, 2009 at 2:52 PM, Greg Harman ghar...@gmail.com wrote: I like the example, and I should be able to adapt it. I do have one question about the example (probably not related to agents: ; queue up some work to be done (defn add-job [func] (let [a (agent nil)] (send a (fn [_] (func))) (swap! jobs #(conj %1 a What is the notation fn [_]? I can't seem to find any documentation for what _ as a function argument means... It's a conventional name for unused/ignored arguments. On Jan 22, 6:14 am, Greg Harman ghar...@gmail.com wrote: Thanks Tim, I'll have a look at that. To clarify my use case, I was thinking of events that can be processed sequentially but that may take a non-trivial amount of time to complete (both CPU and IO bound at different stages of processing) so it's ideal to have a thread pool to process different tasks in parallel, even though they are independent. (That's step one. Step two will be spreading that thread pool out over multiple JVMs running on different hardware). On Jan 22, 2:39 am, Timothy Pratley timothyprat...@gmail.com wrote: Hi Greg Here is a proof of concept of one approach you could take:http://groups.google.com/group/clojure/web/job-queue.clj A set of agents are maintained to represent computation jobs. When the results are gathered, the agent is thrown away. I think using multiple agents in this way could be quite convenient as it means the jobs can be done in parallel. If you run the script from the command line you should get something like this: C:\javaclj job-queue.clj (4 3) (0 nil Hi mum) Which are the results of multiple queued computations taken at two subsequent points in time. From your post it wasn't clear to me if your 'events' imply sequential processing (which could be achieved with a single agent). Regards, Tim. -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ 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 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: struct question
On Jan 22, 2:48 am, Mark Engelberg mark.engelb...@gmail.com wrote: Thanks for the thread links. This is basically what I suspected -- if you want to use structs in multimethods, you have to roll your own constructor which adds some kind of type tag to either the hashmap or the metadata. It just seems like a common case, so I was hoping there was a more convenient way. But I guess that's what macros are for... For now, yes. Struct bases are largely an implementation detail at this point. I don't want people marrying the current implementation. Doing something more for structs is on the agenda, but just what is an open question. It's pretty easy to write a trivial struct system, much harder to address performance, interop, compilability, dynamicity etc constraints. As a simple case, if a defstruct is re-evaluated, will objects created after that be of the same 'type' as objects created before? What if fields have been added/removed? There are people using structs right now who are very interested in the interface they present to Java clients. I'd prefer people experiment with libraries built on the existing facilities, with an open mind as to the possibilities of categorizing things other than by their structure. 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 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: Streams work
On Thu, Jan 22, 2009 at 2:18 PM, Rich Hickey richhic...@gmail.com wrote: Those are important things to think about. There are, in fact, thread semantics for the streams mechanism, as for the rest of Clojure. Currently, I've made it such that the stream/iter/ seq combination ensures serialized access to the generator, allowing use of generators over otherwise unsynchronized multi-step activities. Obviously, stream-backed seqs are safe, being persistent and immutable. but it is also currently the case that the stream iter is MT safe as well. All calls to next! on an iter are atomic re: its generator, i.e. no 2 threads can be in the generator code at once. That means that, within a private consumer, you could fire up multiple threads that share the same iter and coordinate to produce a result, and return the result or a stream upon it. Used correctly, this is a powerful feature. However, I'm reluctant to expose/guarantee it, lest people start using iters as connection points and invalidating the whole stream protection model. A well- written API should take/return streams/seqs, never iters, so MT use of an iter should always be an implementation detail of a single stream step. But I can't enforce that. Hmm... could we imagine a (synced-iter an-iter) that returned a wrapped iter that _did_ guarantee MT safety? Ofcourse this only makes sense if you end up not guaranteing MT safety of ordinary iters, and I don't know enough to prefer one approach over the other. For those looking to experiment with such things, feel free to try it now and provide feedback. Thanks, Rich -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~-~--~~~---~--~~ 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 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: Clojure Web Libraries
I'd suggest using Compojure for your first project - its fairly widely used, is easy to pick up, and has a growing set of docs. I'm not sure that Webjure is maintained anymore (i.e. no commits to its repo in a few months). Weld is still a work in progress - I'm trying to stabilize it now but it needs some more time. - Mark On Thu, Jan 22, 2009 at 5:08 AM, James Reeves weavejes...@googlemail.com wrote: On Jan 21, 9:39 pm, Frank ffai...@gmail.com wrote: I am interested in trying to use Clojure to develop web-based applications. Can someone point me to any Clojure libraries that have been written that I can use. Thanks. There's Compojure, which looks like this: (defservlet demo-servlet (GET / (html [:h1 Hello World])) ( http://github.com/weavejester/compojure ) Weld, which I believe looks like this (Mark, please correct me if I've misrepresented Weld): (def config {'weld.routing/*router* (compiled-router [['index-page :index :get /]])}) (defn index-page [req] (respond (html [:h1 Hello World]))) ( http://github.com/mmcgrana/weld ) And Webjure, which looks like this: (defh / [] {:output :html} `(:h1 Hello World)) ( http://code.google.com/p/webjure ) Out of the three frameworks, it's possible that Compojure is the most popular: at least, I've seen more tutorials and sites written with it. But since I'm the author of Compojure, I can't exactly claim I'm unbiased :) - James --~--~-~--~~~---~--~~ 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 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: struct question
On 22.01.2009, at 15:26, Rich Hickey wrote: It's pretty easy to write a trivial struct system, much harder to address performance, interop, compilability, dynamicity etc constraints. Indeed. As a simple case, if a defstruct is re-evaluated, will objects created after that be of the same 'type' as objects created before? I'd say no, which resolves the next question: What if fields have been added/removed? Anyway, I don't think that re-evaluation is a serious issue, except in interactive development sessions. The typical use would be defining a struct once and then not touch it any more. I'd prefer people experiment with libraries built on the existing facilities, with an open mind as to the possibilities of categorizing things other than by their structure. The added flexibility of multimethods is quite appreciable in non- trivial situations. But at the moment there is no simple way to handle simple situations. Using structs is straightforward and familiar from other languages. It is certainly not *the* solution to categorizing, but it's a simple one that is good enough for many applications. Konrad. --~--~-~--~~~---~--~~ 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 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: Streams work
On Jan 22, 9:08 am, Konrad Hinsen konrad.hin...@laposte.net wrote: On 21.01.2009, at 20:33, Rich Hickey wrote: I've started documenting the streams work I have been doing, for those interested: http://clojure.org/streams Nice! I have played a bit with the stream implementation, and I came across a behaviour that I do not understand: First, define a random stream that calls rand, and an iter on it: (def rand-stream (stream (fn [_] (rand (def rand-iter (stream-iter rand-stream)) Calling it a few times shows that it works: (next! rand-iter nil) (next! rand-iter nil) Next, try to use it as a seq: (take 4 rand-stream) This fails, as it should: java.lang.IllegalStateException: Already iterating (NO_SOURCE_FILE:0) Detach the iter and try again: (detach! rand-iter) (take 4 rand-stream) Now it works - fine. But what happened to the seq that now owns the stream? Nothing refers to it, so it should be gone. No, the stream must refer to it, in order to keep its promise to return the same seq every time. Did it perhaps liberate the stream, so that I can create an iter again? Let's try: (def rand-iter (stream-iter rand-stream)) (next! rand-iter nil) (next! rand-iter nil) It seems so. But... let's be mean: (take 4 rand-stream) I would expect this to throw the IllegalStateException again, but it doesn't: it returns the same four-number sequence as the last time it was called. Where was that one stored? In the stream itself? Or does the stream keep a reference to the seq, so that it never disappears? But then I shouldn't be able to create another iterator. What you've created an iter on the second time is the seq of the stream. Right now, once you've treated a stream as a seq it will always behave like one. So this second stream-iter call actually creates an iter on a stream on that seq. Let's be mean again: (next! rand-iter nil) (take 10 rand-stream) (next! rand-iter nil) (next! rand-iter nil) (take 15 rand-stream) All of these work - it seems I have both an iter and a seq on the same stream, with the iter returning values that are also in the seq. No, you've got a generator, a stream on that, a seq on that, a stream on that seq and an iter on that stream - that's why you are getting the same values. You'll never have a seq and an iter on the same generator, i.e. interleaved values. I understand this may not be intuitive or clear yet from the docs. Nor am I set in this being the behavior. The case I am looking towards is this one: (def s (stream (range 10))) (if (seq s) (take 4 (map-stream inc s)) A stream is used as a seq and then passed to a stream function. Without this seqed-stream-behaves-as-seq capability, this will fail with Already iterating, and would have to be written: (if (seq s) (take 4 (map-stream inc (seq s 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 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: Agent as a processing queue
(both CPU and IO bound at different stages of processing) so it's ideal to have a thread pool to process different tasks in parallel, even though they are independent. If you use the agents, the underlying implementation uses two thread pools: (1) static relative to your processors, use send to access it - best to only use this for cpu hungry threads where you want to maximize throughput while limiting context switching. (2) the other grows on demand, use send-off to access it - better choice if IO blocking is involved, otherwise you have a limited number of threads not doing much. As such it might be more convenient if the stages you describe were treated as separate tasks, so they can be queued on the appropriate thread pool. (That's step one. Step two will be spreading that thread pool out over multiple JVMs running on different hardware). Clojure doesn't have any built in distributed features afaik, so you'd need to develop a custom protocol or use a popular java lib. --~--~-~--~~~---~--~~ 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 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: Streams work
On 22.01.2009, at 16:27, Rich Hickey wrote: Now it works - fine. But what happened to the seq that now owns the stream? Nothing refers to it, so it should be gone. No, the stream must refer to it, in order to keep its promise to return the same seq every time. OK. Did it perhaps liberate the stream, so that I can create an iter again? Let's try: (def rand-iter (stream-iter rand-stream)) (next! rand-iter nil) (next! rand-iter nil) What you've created an iter on the second time is the seq of the stream. Right now, once you've treated a stream as a seq it will always behave like one. So this second stream-iter call actually creates an iter on a stream on that seq. Does that mean that calling seq on a stream converts the stream into a seq for all practical purposes? That sounds a bit dangerous considering that so many operations in Clojure call seq implicitly. One can easily have a seq steal a stream and not notice it before all memory is used up by the seq. I understand this may not be intuitive or clear yet from the docs. Nor am I set in this being the behavior. The case I am looking towards is this one: (def s (stream (range 10))) (if (seq s) (take 4 (map-stream inc s)) A stream is used as a seq and then passed to a stream function. Without this seqed-stream-behaves-as-seq capability, this will fail with Already iterating, and would have to be written: (if (seq s) (take 4 (map-stream inc (seq s I think the second is in fact clearer. It seems weird in a largely functional context to have an enormous side-effect of calling seq on a stream. Konrad. --~--~-~--~~~---~--~~ 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 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: Clojure Web Libraries
Hi Frank, I'd also recommend looking at Restlet http://www.restlet.org/ and the Java Servlets API. -Stuart Sierra On Jan 21, 4:39 pm, Frank ffai...@gmail.com wrote: Hi, I am interested in trying to use Clojure to develop web-based applications. Can someone point me to any Clojure libraries that have been written that I can use. Thanks. Frank --~--~-~--~~~---~--~~ 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 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: very simple javascript source using clojurescript?
On Thu, Jan 22, 2009 at 12:33 AM, Allen Rohner aroh...@gmail.com wrote: Chouser, how usable is clojurescript to generate extremely simple javascript calls? When creating HTML templates, I find myself using ugly string interpolation to generate the .js. I would really love it if I could do something like: (clojurescript/str (swfobject/embedSWF open-flash-chart.swf my_chart, 500, 200, 9.0.0, false, {:data-file /my/data})) turns into: script type=text/javascript swfobject.embedSWF(open-flash-chart.swf, my_chart, 550, 200, 9.0.0, expressInstall.swf, {data-file:/my/data}); /script ClojureScript currently requires a patch to Clojure in order to work (no breaking changes, though), and so the code is not in the regular clojure-contrib path. That said, the API for that example would currently be: (require '[clojure.contrib.clojurescript :as cljs]) (cljs/formtojs '(.embedSWF swfobject open-flash-chart.swf my_chart 500 200 9.0.0 false {:data-file /my/data})) There's a couple things to note there. The most important is that JavaScript objects don't have packages or static members like Java objects, so you use the instance-method call format a lot more often in ClojureScript than in Clojure. Another thing to note is commas are witespace. :-) Anyway, the above returns this string (after adding whitespace by hand): (function __user_fn_571(){ return ((clojure.JS.resolveVar(swfobject,user)).embedSWF( open-flash-chart.swf,my_chart,(500),(200),9.0.0,false, clojure.core.hash_map(clojure.core.keyword(,data-file),/my/data))) }).apply(null,[]) The most important item to note here is that your {:data-file ...} map is a Clojure hash-map, not a JavaScript Object. ClojureScript doesn't currently do JSON-like translations for you. And unlike Java, JavaScript doesn't have any way (that I know of) to provide a custom object (like hash-map) that provides the same interface as the builtin collection. This is the kind of useful, practical, missing feature that probably still abounds in ClojureScript. I'm not sure if there'd be a way to use an existing clojure-to-json lib for this, or if something would have to be ported. At least it could be written in ClojureScript instead of JavaScrtipt! You can try out ClojureScript and see what works (and likely uncover bugs) with the browser-based REPL: http://clojurescript.n01se.net/repl/ I haven't figured out yet why my clojure-created applets sometimes fail on Mac, so that may not work in a Mac browser. I've made no attempt to trim the size of either the applet or the .js code on that page, so it may take a while to download and get everything started. But once the applet rectangle has gone blank and the word ClojureScript is on the page, you can try some expressions: (alert hi) (- document .body (.appendChild (.createTextNode document Hello World))) The most extensive example of ClojureScript code is, perhaps unsurprisingly, the browser REPL itself: http://clojurescript.n01se.net/repl/repl.cljs --Chouser --~--~-~--~~~---~--~~ 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 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: Agent as a processing queue
Tim, Could you explain atoms the way you explained agents?\ Emeka --~--~-~--~~~---~--~~ 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 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: struct question
http://lispnyc.org/soc2009.clp Forget most of what I said, it seems the BDFL already has these things in mind ;) Enough of types and structs for me, time for me dive into the less familiar territory of Clojure. On Thu, Jan 22, 2009 at 12:25 PM, David Nolen dnolen.li...@gmail.comwrote: Can't some elements of the problem be solved with some form of predicate dispatching as proposed by Meikel? Predicate dispatching would allows us to use _anything_ as a type (i.e. structs themselves), as well as allowing user defined functions to do the matching instead of being limited to isa? and the global hierarchy. This of course has some performance implications I imagine... http://groups.google.com/group/clojure/browse_thread/thread/f8b1be403c927b03/438c21a80072a105?lnk=gstq=hierarchy#438c21a80072a105 I have to say that I find the lack of a type system around structs to be fairly liberating. You can invent one if you need one, but you are not constrained by it. However, if somebody comes up with something like CLJOS as a set of handy macros, or extracts whatever parts they deem relevant, why not put that in clojure-contrib so that people can at least have something to use for the simple cases as pointed out by Konrad? On Thu, Jan 22, 2009 at 10:25 AM, Konrad Hinsen konrad.hin...@laposte.net wrote: On 22.01.2009, at 15:26, Rich Hickey wrote: It's pretty easy to write a trivial struct system, much harder to address performance, interop, compilability, dynamicity etc constraints. Indeed. As a simple case, if a defstruct is re-evaluated, will objects created after that be of the same 'type' as objects created before? I'd say no, which resolves the next question: What if fields have been added/removed? Anyway, I don't think that re-evaluation is a serious issue, except in interactive development sessions. The typical use would be defining a struct once and then not touch it any more. I'd prefer people experiment with libraries built on the existing facilities, with an open mind as to the possibilities of categorizing things other than by their structure. The added flexibility of multimethods is quite appreciable in non- trivial situations. But at the moment there is no simple way to handle simple situations. Using structs is straightforward and familiar from other languages. It is certainly not *the* solution to categorizing, but it's a simple one that is good enough for many applications. Konrad. --~--~-~--~~~---~--~~ 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 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: Streams work
On Jan 21, 2:33 pm, Rich Hickey richhic...@gmail.com wrote: I've started documenting the streams work I have been doing, for those interested: Cool! 3 questions: 1. Can you feed things into a stream? 2. Could streams be used for I/O? 3. Can streams have clean-up/close code when they are emptied or go out of scope? -Stuart Sierra --~--~-~--~~~---~--~~ 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 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: struct question
Hi, Am 22.01.2009 um 18:25 schrieb David Nolen: Can't some elements of the problem be solved with some form of predicate dispatching as proposed by Meikel? Predicate dispatching would allows us to use _anything_ as a type (i.e. structs themselves), as well as allowing user defined functions to do the matching instead of being limited to isa? and the global hierarchy. This of course has some performance implications I imagine... No, Rich mentioned predicate dispatching. :) I barely wrote a simple patch to allow per def-multi hierarchies. However I looked at the a paper by Chambers and Chen on predicate dispatch and it looks a little more involved than the patch mentioned above. ;) This is really interesting. Although I think that I didn't even test the current multimethod system to its limits. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
File, Line Number and Usage Info
Here's a dumb question which has been answered before... but I can't find it in the docs. How does one find out the file and line number upon which a symbol was defined? I want to use it for go-to-defintion in the IntelliJ plugin. Also, is there any way to find all the code that is referencing a symbol? I need that to implement find-usages, rename and move. Thanks 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 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: File, Line Number and Usage Info
On Thu, Jan 22, 2009 at 1:20 PM, Peter Wolf opus...@gmail.com wrote: Here's a dumb question which has been answered before... but I can't find it in the docs. user= (map (meta (var take)) [:file :line]) (core.clj 1434) Which is to say, the file and line number are stored in the metadata of the Var. The namespace, docstring, and other useful tidbits are there too. This information is used by the clojure.contrib.repl-utils/source macro: user= (source take) (defn take Returns a lazy seq of the first n items in coll, or all items if there are fewer than n. [n coll] (when (and (pos? n) (seq coll)) (lazy-cons (first coll) (when ( n 1) (take (dec n) (rest coll)) nil --Chouser --~--~-~--~~~---~--~~ 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 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: Streams work
On Jan 22, 2009, at 11:17 AM, Konrad Hinsen wrote: On 22.01.2009, at 16:27, Rich Hickey wrote: Now it works - fine. But what happened to the seq that now owns the stream? Nothing refers to it, so it should be gone. No, the stream must refer to it, in order to keep its promise to return the same seq every time. OK. Did it perhaps liberate the stream, so that I can create an iter again? Let's try: (def rand-iter (stream-iter rand-stream)) (next! rand-iter nil) (next! rand-iter nil) What you've created an iter on the second time is the seq of the stream. Right now, once you've treated a stream as a seq it will always behave like one. So this second stream-iter call actually creates an iter on a stream on that seq. Does that mean that calling seq on a stream converts the stream into a seq for all practical purposes? That sounds a bit dangerous considering that so many operations in Clojure call seq implicitly. One can easily have a seq steal a stream and not notice it before all memory is used up by the seq. Calling seq on a stream yields a seq that will forever own the stream - if you think about it a bit, you'll see why that has to be the case. OTOH, that seq is lazy, so I'm not sure what the memory issue is. I understand this may not be intuitive or clear yet from the docs. Nor am I set in this being the behavior. The case I am looking towards is this one: (def s (stream (range 10))) (if (seq s) (take 4 (map-stream inc s)) A stream is used as a seq and then passed to a stream function. Without this seqed-stream-behaves-as-seq capability, this will fail with Already iterating, and would have to be written: (if (seq s) (take 4 (map-stream inc (seq s I think the second is in fact clearer. It seems weird in a largely functional context to have an enormous side-effect of calling seq on a stream. Again, I don't see the enormous side effect. Steams form a safe, stateful pipeline, you'll generally only call seq on the end of the pipe. If you ask for a seq on a stream you are asking for a (lazy) reification. That reification and ownership is what makes the pipeline safe. I am working on seq/stream api unification right now, and we will see how often we'll be calling seq fns yet subsequently using as a stream. Many of those places where seq is called will now call stream instead (e.g. sequence fn entry points), and there may be a non-generator- capturing function for determining eos. 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 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: Streams work
On Jan 22, 2009, at 12:36 PM, Stuart Sierra wrote: On Jan 21, 2:33 pm, Rich Hickey richhic...@gmail.com wrote: I've started documenting the streams work I have been doing, for those interested: Cool! 3 questions: 1. Can you feed things into a stream? Yes, you can put a generator on the end of a queue. 2. Could streams be used for I/O? Yes, that's one of the primary use cases. 3. Can streams have clean-up/close code when they are emptied or go out of scope? I'm addressing the resource cleanup issue more generally in a scope mechanism, also present in the streams SVN branch. Still in progress, but you can get the gist of it here: http://paste.lisp.org/display/73838 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 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 -~--~~~~--~~--~--~---
newbie: namespaces and load-file
Suppose I have a clojure file called app.clj that contains something like: (ns app) (defn foo [] (println hello)) (defn reader [filename] (load-file filename)) and a file called data that simply contains (foo) What I would like to see, from the REPL, is: user= (load-file app.clj) user= (app/reader data) hello As described, this doesn't work. load-file looks up symbols in the current namespace (user in this case), but foo is interned in app. I found that I could get the behavior I wanted if I changed the definition of reader to: (defn reader [filename] (binding [*ns* (the-ns 'app)] (load-file filename))) But this has a sort of evil feeling to it. Is there a better way of doing this? Thanks, Paul P.S. I know that doing (load-file app.clj) (in-ns 'app) (reader data) from the REPL works as well, but I don't want to force the user to switch namespaces. --~--~-~--~~~---~--~~ 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 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: newbie: namespaces and load-file
On Jan 22, 2009, at 12:46 PM, Paul Henning wrote: As described, this doesn't work. load-file looks up symbols in the current namespace (user in this case), but foo is interned in app. At some point in this process, Clojure needs to know which foo you're talking about. It can't retrieve the var associated with foo without knowing which namespace it's in. That determination can either be explicit or it can be made via the current namespace (*ns*), but it has to be made somehow. I found that I could get the behavior I wanted if I changed the definition of reader to: (defn reader [filename] (binding [*ns* (the-ns 'app)] (load-file filename))) That's one way to say that foo is in namespace app. But this has a sort of evil feeling to it. Is there a better way of doing this? Another way is to use symbols with namespaces in data: (app/foo) Another way is to declare within data the namespace in which the symbols it contains should be resolved: (in-ns 'app) (foo) One nice feature of loading in Clojure is that any namespace changes are reverted at the end of the file. After the repl commands you used in your example, the repl namespace will still be user. --Steve smime.p7s Description: S/MIME cryptographic signature
Re: newbie: namespaces and load-file
At some point in this process, Clojure needs to know which foo you're talking about. It can't retrieve the var associated with foo without knowing which namespace it's in. That determination can either be explicit or it can be made via the current namespace (*ns*), but it has to be made somehow. Years of using C++ namespaces have rotted my brain, but I think the surprise here was that (load-file) uses the current namespace from the run-time environment, rather than the compile-time environment. To my way of thinking, anything appearing beneath the (ns whatever) should operate in that namespace. As long as no one cares if I muck with *ns*, I can make it work the way I want. Thanks for pointing out that namespaces revert at the end of a load. Clearly matches observed behavior, but I hadn't thought about it before. Paul --~--~-~--~~~---~--~~ 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 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: File, Line Number and Usage Info
Hello, Here is how I get an hierarchical data structure of information on ns in clojure-dev : The tree has really just 3 levels : one root node representing all ns, one child node of the root node representing one ns each, one child node per ns node for ns interned symbols. Each node is represented as a map, with a simple convention : the type of the node is at key :key, the children of the node are at key :children, and are a vector of maps. Other information for the given node are other keys. And now the code (that uses (var ..) : (defn- meta-info [v] (reduce (fn [m e] (merge m { (first e) (str (second e)) })) {} (meta v))) (defn- var-info [v] (merge { :type var :name (str v) } (meta-info v))) (defn- ns-info [n] { :name ((comp str ns-name) n) :type ns :children (apply vector (map #(var-info (second %)) (ns-interns n))) }) (defn namespaces-info [] { :name namespaces :type namespaces :children (apply vector (map ns-info (all-ns))) }) HTH, Regards, -- Laurent On 22 jan, 19:20, Peter Wolf opus...@gmail.com wrote: Here's a dumb question which has been answered before... but I can't find it in the docs. How does one find out the file and line number upon which a symbol was defined? I want to use it for go-to-defintion in the IntelliJ plugin. Also, is there any way to find all the code that is referencing a symbol? I need that to implement find-usages, rename and move. Thanks 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 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 -~--~~~~--~~--~--~---
Calling Clojure from Java (again)
This is a rejuvenation of the old calling Java from Clojure thread I have been looking at the solutions from Mark / 1) From a Java application, read a text file containing Clojure code and invoke specific functions it defines from Java code. 2) Compile Clojure code to bytecode and use it from a Java application just like any other Java code. An example of the first option is provided at http://markmail.org/message/tx23zaxf77b6widh#query:%22calling%20Clojure%22%20%22from%20Java%22+page:1+mid:tx23zaxf77b6widh+state:results. / and Stuart / Here's how I do it: import clojure.lang.RT; import clojure.lang.Var; ... RT.loadResourceScript(source/file/on/classpath/here.clj); Var myfunction = RT.var(my-namespace, my-function); myfunction.invoke(arg 1, arg 2, ...); / Where is the documentation on this Java API? In particular, all these functions seem to side-effect a single Clojure image. Can I create several disjoint images? Can I stop or destroy an image that has run amok? I want to use this for the IntelliJ plugin, and I don't want bogus user code to clobber the IDE. I also want the defined symbols for a file to be a function just of the code in that file, not all the files that happen to be loaded by the IDE at the moment. How does Swank handle this? Thanks 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 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: newbie: namespaces and load-file
On Jan 22, 2009, at 3:56 PM, Paul Henning wrote: As long as no one cares if I muck with *ns*, I can make it work [...] That brings up an important point. The var *ns* may look like a global variable in C++, but it's really a dynamic variable--something quite a bit safer and more powerful. The value of the var named *ns* is not (in the general case) a single piece of data. In the general case it's many pieces of data simultaneously. These different values are isolated from each other such that at any given time, each piece of running code sees only one of them. They are separated by thread--each thread has its own stack of values, and by binding depth--the effective value at any given point in the thread's runtime is the one that's associated with the nearest enclosing call to binding. (This may be the value bound at the time binding was called, or it may be a value set subsequently with set!.) When you use in-ns, one of its internal operations is a set! of *ns*. For that to succeed, *ns* must have a thread-local binding in effect at the time of the set!. Calling in-ns only changes the effective namespace in the thread that calls it and only until that binding is popped off the stack by the code exiting the binding form. The overall effect of this is that when you muck with *ns*, only your code (and code it calls) will see what you did. That isolation makes a Clojure's var much easier to reason about than a global variable would be--especially in the case of many threads accessing its value concurrently. Thanks for pointing out that namespaces revert at the end of a load. Clearly matches observed behavior, but I hadn't thought about it before. You're quite welcome. --Steve smime.p7s Description: S/MIME cryptographic signature
Re: Clojure Web Libraries
Thanks to everyone for their responses. I will be looking into all these libraries. I wanted to add two other references to this thread that I will also be researching. I found two libraries written by Christophe Grand: Ring - http://github.com/mmcgrana/ring/tree/master Enlive - http://github.com/cgrand/enlive/tree/master Ring is described as Clojure web application library: abstracts HTTP to allow modular and concise webapps and Enlive is described as a selector-based (à la CSS) templating system for Clojure. -Frank On Jan 22, 11:44 am, Stuart Sierra the.stuart.sie...@gmail.com wrote: Hi Frank, I'd also recommend looking at Restlet http://www.restlet.org/ and the Java Servlets API. -Stuart Sierra On Jan 21, 4:39 pm, Frank ffai...@gmail.com wrote: Hi, I am interested in trying to use Clojure to develop web-based applications. Can someone point me to any Clojure libraries that have been written that I can use. Thanks. Frank --~--~-~--~~~---~--~~ 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 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: Calling Clojure from Java (again)
On Thu, Jan 22, 2009 at 4:43 PM, Peter Wolf opus...@gmail.com wrote: This is a rejuvenation of the old calling Java from Clojure thread I have been looking at the solutions from Mark / 1) From a Java application, read a text file containing Clojure code and invoke specific functions it defines from Java code. 2) Compile Clojure code to bytecode and use it from a Java application just like any other Java code. An example of the first option is provided at http://markmail.org/message/tx23zaxf77b6widh#query:%22calling%20Clojure%22%20%22from%20Java%22+page:1+mid:tx23zaxf77b6widh+state:results. / and Stuart / Here's how I do it: import clojure.lang.RT; import clojure.lang.Var; ... RT.loadResourceScript(source/file/on/classpath/here.clj); Var myfunction = RT.var(my-namespace, my-function); myfunction.invoke(arg 1, arg 2, ...); / Where is the documentation on this Java API? In particular, all these functions seem to side-effect a single Clojure image. Can I create several disjoint images? Can I stop or destroy an image that has run amok? I want to use this for the IntelliJ plugin, and I don't want bogus user code to clobber the IDE. I also want the defined symbols for a file to be a function just of the code in that file, not all the files that happen to be loaded by the IDE at the moment. How does Swank handle this? Clojure has no notion of an environment. Its environment is the JVM in which it is running, just like Java. There was a thread about this awhile back, its long, but it goes over some the issues I think you're getting at: http://groups.google.com/group/clojure/browse_thread/thread/d98cedb860f16a34/18c930d1c76aa31c The bottom line is that you can only isolate Clojure within a single JVM in the same you that you can isolate Java in a single JVM--ClassLoaders. The other heavy-weight option is to run multiple JVMs. I don't think you need to worry about user code hijacking the IntelliJ IDE--Clojure cannot redefine Java classes which have already been loaded. It is however possible for Clojure code to clobber previously compiled Clojure code, so if you are worried about that, then I think you'll need to look at an isolation mechanism like ClassLoaders or launching a new JVM. I don't think Swank really deals with the issue at all. I just checked and it is entirely possible to re-def swank functions from the Emacs SLIME repl. /mike. --~--~-~--~~~---~--~~ 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 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: File, Line Number and Usage Info
Peter, A weird thing seems to happen often those days, and I have remarked it's related to you. You start a new post, but it appears to be in the continuation of a previous one, with the subject changed. This does not look good to me. Are you doing something like this to start a new post : open the last e-mail received by the ml, click on reply, change the subject, throw the body out and replace it by my own ? If so, then please consider creating a new e-mail each time you start a new subject ? If not so, then your mailer may have a problem with googlegroups ? Regards, -- Laurent On 22 jan, 19:20, Peter Wolf opus...@gmail.com wrote: Here's a dumb question which has been answered before... but I can't find it in the docs. How does one find out the file and line number upon which a symbol was defined? I want to use it for go-to-defintion in the IntelliJ plugin. Also, is there any way to find all the code that is referencing a symbol? I need that to implement find-usages, rename and move. Thanks 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 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: Clojure Web Libraries
On Jan 22, 10:15 pm, Frank ffai...@gmail.com wrote: I found two libraries written by Christophe Grand: Only Enlive was written my Christophe; Ring was written by Mark. From what I gather Ring is an abstraction layer like Rack, and isn't designed to be used directly to build web applications. Rather, it's a common interface for frameworks like Weld and Compojure to handle HTTP requests and responses. - James --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
function that takes primitives?
Hi folks, Is there any way to make a function that takes primitive parameters? It seems you can't, but I might be missing something. I have the following code (a start to playing with mandelbrot sets): (defn step [x0, y0, xn, yn] (let [xm (+(-(* xn xn)(* yn yn)) x0) ym (+(* 2 xn yn) y0) ] [xm ym] ) ) (defn try_to_solve [x0, y0, xn, yn, n, max_n] (let [m (+ n 1) [xm ym] (step x0 y0 xn yn) zm (+(* xm xm)(* ym ym)) ] (cond ( zm 2.0) m (= n max_n) [x0, y0, xm, ym, m, max_n] true (recur x0, y0, xm, ym, m, max_n) ) ) ) This works fine (it's my first clojure code, so I'm sure there are things I could do better, but I'm happy with it as a start) However, I want to do this a lot, so I was trying to coerce the paramters to primitive doubles. It seems you can't write: (defn step [#^double x0, #^double y0, #^double xn, #^double yn] and from comments I've seen before, I get the impression if I use type hinting, clojure will use Doubles and boxing, which is a speed overhead I don't want. I get the impression I can rewrite try_to_solve to use a loop/recur, and then can use primitives - but I can't see any way to make calls to step use primitives, short of inlining the function... - Korny -- Kornelis Sietsma korny at my surname dot com --~--~-~--~~~---~--~~ 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 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: File, Line Number and Usage Info
Ooops! How embarrassing :-( Yes, that's exactly what I am doing. It did not occur to me that there is extra information embedded in the reply that marks it as being part of a thread. Sorry, won't happen again P lpetit wrote: Peter, A weird thing seems to happen often those days, and I have remarked it's related to you. You start a new post, but it appears to be in the continuation of a previous one, with the subject changed. This does not look good to me. Are you doing something like this to start a new post : open the last e-mail received by the ml, click on reply, change the subject, throw the body out and replace it by my own ? If so, then please consider creating a new e-mail each time you start a new subject ? If not so, then your mailer may have a problem with googlegroups ? Regards, -- Laurent On 22 jan, 19:20, Peter Wolf opus...@gmail.com wrote: Here's a dumb question which has been answered before... but I can't find it in the docs. How does one find out the file and line number upon which a symbol was defined? I want to use it for go-to-defintion in the IntelliJ plugin. Also, is there any way to find all the code that is referencing a symbol? I need that to implement find-usages, rename and move. Thanks 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 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: Calling Clojure from Java (again)
Thanks for the lengthy reply Laurent, Replies in-line lpetit wrote: Peter, We asked us the same question some weeks ago, on clojuredev. We took the path to follow how eclipse launches a java application when the user requires it to test it. So we created a customized launch configuration (sorry, eclipse jargon), that is just a classical eclipse java launcher with some options predefined. Yes, this is exactly what I do also, and it is even called a configuration in IntelliJ To enable the user work against the clojure version he wants, we require him to have clojure library as a standard library dependency on the classpath of his eclipse project. I think you could do quite the same thing for IntelliJ. We did that because of several reasons : - we wanted the user to be able use his own version of clojure, not an imposed one - we wanted the user to be able to have several clojures running at the same time - we absolutely wanted to prevent the user run his code in the eclipse VM ! - we wanted regular eclipse users to feel at home with clojuredev, having in mind that having a smooth migration path from java to clojure, first by just incorporating bits of clojure in a (n already existing) java project codebase, could be a good thing. Yep. Same solution, same reasons. So we took the road you described by quoting Stuart. We call a bridge function that takes strings and returns strings (or core clojure datastructures : maps, vectors, strings, keys, java.lang basic types). This bridge function runs on the eclipse JVM, and calls a server we systematically install in the remote JVM when the user launches his project. The code for the client part is here : http://code.google.com/p/clojure-dev/source/browse/clojuredev/trunk/src/clojuredev/debug/clientrepl.clj The code for the server part is here : http://code.google.com/p/clojure-dev/source/browse/clojuredev/trunk/src/clojuredev/debug/serverrepl.clj (and yes, it's yet another variation on the repl over socket) Thanks, I shall take a look at this. However, if there is only one Clojure image used for references and the like, what happens if someone calls an infinite loop, or infinite recursion, in a file. Does the Clojure server hang/blow up? How do you detect it/protect from it? For example, I was using the SmallSnake code for testing, and when that file is loaded, it pops up a window and runs a process forever. I don't want that to happen, just because someone included that file in their IntelliJ project. This must be a problem common to all Swank based IDEs. What is the Clojure way here? --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
what when (some identity maps) mean?
Hi, Here is def of merge: (defn merge [ maps] (when (some identity maps) (reduce #(conj (or %1 {}) %2) maps))) How can I interpret when (some identity maps)? Thanks -sun --~--~-~--~~~---~--~~ 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 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: Agent as a processing queue
wow. I wonder if I could use this for the quicksort I was talking about. I would need to have the function being added as a job be able to add it's own jobs recursively . . . .and kill jobs when they are done. But do you have to sleep, or is there a way to join the children when they are done? And is there a way to throttle the total number of agents? I'm lazy, so if this is something I should be reading about on my own, I totally understand. I'm wondering if this post is enough of a clue to get started is all. So any frame in the stack is responsible for taking any sequence of at least one element and: 1) first element is the pivot. 2) if there are elements less than pivot, make a job to quicksort them when there is an available agent. 3) fire off a quicksort for stuff greater than pivot when there is an available agent. 4) join back with the two child tasks and grab their now sorted subsequences 5) kill the child jobs 6) glue the subsequences with the pivot in the middle 7) return to the parent code At first, there will only be one thread for the first pass, but the number will grow as subtasks fire sub-sub tasks. I am sure this is a silly way to sort because the threadspawning time is so much longer than the filtering time, but it's just an exercise. Is that example (provided in the link) enough knowledge to get started on this? Thanks. On Thu, Jan 22, 2009 at 2:39 AM, Timothy Pratley timothyprat...@gmail.comwrote: Hi Greg Here is a proof of concept of one approach you could take: http://groups.google.com/group/clojure/web/job-queue.clj A set of agents are maintained to represent computation jobs. When the results are gathered, the agent is thrown away. I think using multiple agents in this way could be quite convenient as it means the jobs can be done in parallel. If you run the script from the command line you should get something like this: C:\javaclj job-queue.clj (4 3) (0 nil Hi mum) Which are the results of multiple queued computations taken at two subsequent points in time. From your post it wasn't clear to me if your 'events' imply sequential processing (which could be achieved with a single agent). Regards, Tim. --~--~-~--~~~---~--~~ 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 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: what when (some identity maps) mean?
Hi, It means that some of the maps can be nil, but at least one of them has to be non-nil. some requires a predicate, but since nil is logical false, we can just use identity. Here's the behavior: user (merge nil nil nil) nil user (merge {:a 1} nil {:b 2}) {:b 2, :a 1} -Stuart Sierra On Jan 22, 7:16 pm, wubbie sunj...@gmail.com wrote: Hi, Here is def of merge: (defn merge [ maps] (when (some identity maps) (reduce #(conj (or %1 {}) %2) maps))) How can I interpret when (some identity maps)? Thanks -sun --~--~-~--~~~---~--~~ 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 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: Calling Clojure from Java (again)
On Jan 22, 6:51 pm, Peter Wolf opus...@gmail.com wrote: However, if there is only one Clojure image used for references and the like, what happens if someone calls an infinite loop, or infinite recursion, in a file. Does the Clojure server hang/blow up? If you code an infinite loop, the SWANK server will run an infinite loop. The only solution is to kill off the Java process. If you wanted to get clever, you could load the file in a separate thread and just kill off that thread. For example, I was using the SmallSnake code for testing, and when that file is loaded, it pops up a window and runs a process forever. That's an unfortunate side effect of using Clojure as a scripting language like Perl or Python. Perhaps it would be more proper for the distributed file to define a function that will run the application. -Stuart Sierra --~--~-~--~~~---~--~~ 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 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: Streams work
On Jan 21, 1:33 pm, Rich Hickey richhic...@gmail.com wrote: I've started documenting the streams work I have been doing, for those interested: http://clojure.org/streams Feedback welcome, Rich This work reminds me in a general way of the old Dylan iteration protocol. They're not the same, and the Dylan iteration protocol does not provide the safety for concurrency that you're working on. Still, just in case any of the old ideas happen to be useful, I thought I'd provide a link: http://amigos.rdsathene.org/other/prefix-dylan/book.annotated/ch12.html#iteration%20protocol0 (this link is to a webbed version of the 1992 lisp-syntax version of Dylan. the manual is getting increasingly hard to find online.) --~--~-~--~~~---~--~~ 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 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: Inheritance multiple inheritance using structs
On Jan 19, 12:38 am, David Nolen dnolen.li...@gmail.com wrote: Of course it might be the case that not many people are interested in the implementing ideas from CLOS for Clojure It's definitely interesting. I'd like to have eql specializers and the ability to build hierarchies of arbitrary types (e.g. a hierarchy of strings for one particular application I'm working on), so any hacking around with CLOS-like dispatching and specializers is interesting to me. --~--~-~--~~~---~--~~ 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 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: Agent as a processing queue
On Jan 22, 4:24 pm, e evier...@gmail.com wrote: At first, there will only be one thread for the first pass, but the number will grow as subtasks fire sub-sub tasks. I am sure this is a silly way to sort because the threadspawning time is so much longer than the filtering time, but it's just an exercise. It's also not so efficient because in Quicksort, the pivot isn't always in the middle of the current subarray. That means different agents will probably get different array sizes and thus you will lose performance through load imbalance. Parallel Quicksort can only be made efficient if the language supports efficient nested parallelism. mfh --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
Any way we can get this in clojure-contrib?
Under the suggestion of some people in the #clojure channel, I started working on a date library for Clojure since the built-in Java one is kind of a mess. It's not totally complete, but I think it could be quite useful. It supports getting the current date and time, and creating dates based on input. It also has excellent date formatting and parsing support, which allows users do define they're own custom date formats as well as using the built-in java ones. The code is here: http://gist.github.com/49656 I was wondering if this could get added to clojure-contrib. I'm not really sure how things work for the project, but I figured this would be the best place to ask. Dates are a pretty basic data structure, so I think many would benefit from having 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 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: Any way we can get this in clojure-contrib?
By the way, I'm in the process of sending in my contributor agreement. Just so you know :) --~--~-~--~~~---~--~~ 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 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: Inheritance multiple inheritance using structs
[sorry for duplicating content from the email i sent you David] Would anyone be interested in simplifying some of the boilerplate for defining methods in clojs? Currently you have to do this, (defclass circle [shape] (:radius 10)) (defmulti area :tag) (defmethod area ::circle [this] (* (:radius this) (:radius this) (Math/ PI))) But it seems like 99% of the time this is boilerplate b/c you want multi-methods to dispatch on :tag, so we should maybe have a shortcut to let us do this... (defclass circle [shape] (:radius 10) (defmethod area [] (* :radius :radius Math/PI))) I'm not a macro-wiz but it must be possible to alter that defmethod to check if it's defined and to wrap the symbol refrences with (:symbol this) and cons this to the argument list. Just a thought, Aria On Jan 22, 7:55 pm, evins.mi...@gmail.com evins.mi...@gmail.com wrote: On Jan 19, 12:38 am, David Nolen dnolen.li...@gmail.com wrote: Of course it might be the case that not many people are interested in the implementing ideas from CLOS for Clojure It's definitely interesting. I'd like to have eql specializers and the ability to build hierarchies of arbitrary types (e.g. a hierarchy of strings for one particular application I'm working on), so any hacking around with CLOS-like dispatching and specializers is interesting to me. --~--~-~--~~~---~--~~ 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 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: Any way we can get this in clojure-contrib?
That sounds interesting; you might take a look at Joda Timehttp://joda-time.sourceforge.net/. Although I've never used it myself, from what I've heard it's the Java library that people actually use for dates/times (I do know that Google uses it). Doing a quick search, it looks like Mark McGranaghan is working on a Clojure wrapper for Joda Time here http://github.com/mmcgrana/clj-garden/tree/master under clj-time. On Thu, Jan 22, 2009 at 11:51 PM, Matt Moriarity matt.moriar...@gmail.comwrote: By the way, I'm in the process of sending in my contributor agreement. Just so you know :) --~--~-~--~~~---~--~~ 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 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: Any way we can get this in clojure-contrib?
We discussed Joda Time, but it was decided that it wasn't a good idea to add another dependency, since this is something so integral to the language. I don't know what other people think, though. This was just an informal decision on #clojure. On Jan 23, 12:05 am, Nick Vogel voge...@gmail.com wrote: That sounds interesting; you might take a look at Joda Timehttp://joda-time.sourceforge.net/. Although I've never used it myself, from what I've heard it's the Java library that people actually use for dates/times (I do know that Google uses it). Doing a quick search, it looks like Mark McGranaghan is working on a Clojure wrapper for Joda Time herehttp://github.com/mmcgrana/clj-garden/tree/masterunder clj-time. On Thu, Jan 22, 2009 at 11:51 PM, Matt Moriarity matt.moriar...@gmail.comwrote: By the way, I'm in the process of sending in my contributor agreement. Just so you know :) --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---
updated pdf of clojure manual?
Hi folks; Is there any way to get an updated dump of clojure.org as a pdf file? I like to print out stuff and read it on the train, and the clojure_manual.pdf available on the google groups site is a tad old, good for an introduction, but I'd like to read the bleeding edge stuff off-line. - Korny -- Kornelis Sietsma korny at my surname dot com --~--~-~--~~~---~--~~ 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 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 -~--~~~~--~~--~--~---