Re: doc suggestion for future function
Related to the (future function. (there is a bit of a lack of documentation on it, but I guess I can derive more from the example in http://clojure.org/refs,) can I call something like (apply await myvectorofrefs) if I have a bunch of futures running and I want to wait for them to finish before I go on with the next step in the model? On Feb 20, 3:24 pm, Jeffrey Straszheim wrote: > As far as I can tell, futures are *not* agents, but wrap the > java.util.concurrent.Future class. However, they do run in the same thread > pool that the agents use, so your point still stands. > > On Fri, Feb 20, 2009 at 9:09 AM, Mark Volkmann > wrote: > > > > > The doc string for the future function should probably mention that it > > uses an Agent so shutdown-agents should be called at the end of > > applications that use it. > > > -- > > R. Mark Volkmann > > Object Computing, Inc. --~--~-~--~~~---~--~~ 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: Waterfront - The Clojure-based editor for Clojure
On Feb 28, 1:57 am, zoltar wrote: > On Feb 25, 6:02 pm, "Stephen C. Gilardi" wrote: > > > > > - When using waterfront on Mac OS X, it appears that the control > > characters intended to trigger menu selections (e.g. ^E) are being > > intercepted before they reach the menus. In the specific case of ^E, > > it is being interpreted by the text input field as "move to end of > > line" which is a common meaning for it in Mac OS X. I suspect there is > > a way to trigger menu items using the "command-key" on the Mac (while > > still using the control key on Windows) and people using waterfront on > > Mac OS X would benefit from a change to using that mechanism. > > Indeed. Instead of hard-coding modifier keys, you should use the > Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(). This will > return control for windows and META (or command) for Mac. > > Curtis Curtis, Yes, that's exactly what I did in rev. 148, already available at sf.net. Thanks, -Itay --~--~-~--~~~---~--~~ 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: Observations about new lazy branch
Mark Engelberg a écrit : > Let's imagine that you are using map on a collection for which it is > very computation intensive to generate the rest, but trivial to > generate the first. > I don't think that's that simple: it depends on what is in the cons. For example, if the input seq is the result of mapping a computation intensive function (a common source of computation intensive seqs) then taking the rest of this seq is cheap because the rest itslef is a lazy-seq (as per map definition): user=> (def b (map #(do (println "mapping" %) %) (range 10))) #'user/b user=> (doall (take 3 (map inc b))) mapping 0 mapping 1 mapping 2 (1 2 3) When you really want to delay the computation of rest, you can replace (rest s) by (drop 1 s) but that holds on s (so does your lazier-map). Your lazier-map can be written: (defn lazier-map ([f coll] (lazy-seq (when-let [s (seq coll)] (cons (f (first s)) (lazier-map f (drop 1 s)) Hope this helps Christophe -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Waterfront 148 (was: Waterfront - The Clojure-based editor for Clojure)
Dan, Marko, I wonder whether you have the time to do a little experiment. The L&F is set at line 182 of net/sourceforge/waterfront/ide/ui.clj. Could you please try to see which L&F works on your machine or, otherwise, understand why an exception is thrown there? Thanks, -Itay On Feb 28, 12:58 am, Dan wrote: > > I'm not sure I understand. Are you referring to > > UIManager.getSystemLookAndFeelClassName() ? > > This is the L&F that Waterfront is using. If you don't get this L&F > > then perhaps the call to setLookAndFeel() fails on your machine. I'll > > add a piece of code to log the exception. > > > -Itay > > It also has the ugly default swing L&F on my machine too. I'm using Linux / > KDE. --~--~-~--~~~---~--~~ 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: doc suggestion for future function
bOR_ a écrit : > can I call something like (apply await myvectorofrefs) if I have a > bunch of futures running and I want to wait for them to finish before > I go on with the next step in the model? > No you can't use await. The simplest way to await for a future is to deref it: @fut blocks until the computation ends. Hence to await on a bunch of futures you can do: (doseq [f futs] @f) or (dorun (map deref futs)) But, since deref blocks, do you really need to await on them? Christophe -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: (rest ())
Hi, Am 28.02.2009 um 04:14 schrieb Mark Engelberg: I expect: (rest [1]) -> () (rest []) -> nil Just as (first []) yields nil, so should (rest []), IMO. The definition of rest, is that it returns a collection of items of the rest of the given seqable thing. first is a different case. It takes a seqable thing and returns a thing or nothing. If the given collection is empty (or it is given nil as a "sequence"), there is no first thing. Hence first returns nothing (nil). next is again different. It takes a seqable thing, and returns a sequence of the remaining items in the sequence without the first one or nothing if there are no more items (or there were none to begin with). rest is now a special view on the return value of next. It always returns a collection of the remaining items. If there are none, ie. next returned nil, this is the empty list, which is the concrete collection containing no items corresponding to an "empty sequence". So far everything seems consistent to me. rest is really just a different view of next. One can be considered the abstract concept, while the other is a concrete thing. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: The Application Context Pattern
On Feb 28, 3:26 am, samppi wrote: > It looks really nice. I have a question about those observers, though-- > every time that a context-processing function is called, every > observer is called one by one, no matter what the context-processing > function was. This seems somewhat inefficient, more so than listeners > that listen to only certain functions and are called when the listened > function is activated. In your experience, is this not a big problem? I believe that in many practical scenarios this is not a major problem. Most observers will exit almost immediately so iterating over them (even several hundreds of them) will not be too expensive. Anyway, if it does get into a problem I can think of two possible solutions: 1) It is possible to create more than one context in a program (in other words: the context is not a singleton). By splitting the contexts the number of observers per invocation of a context-processor will get smaller. 2) It is possible to create one observer (parent) that delegates to other observers (children). The parent will contain the logic as to whether the children need to be invoked. If it decides that the answer is "No" it will immediately return, thus reducing the workload on the observer invocation loop. -Itay > Or am I missing something? > > On Feb 27, 1:05 am, Itay Maman wrote: > > > Some of the reaction for Waterfront was related to the Application > > Context Pattern (ACP) - The pattern that allows most of Waterfront's > > code to be purely functional. I'll try to explain the basics in this > > post. Let me start with the motivation: the reason why FP is at odds > > with GUI code. > > > (Pure) Functional code has no side effects, which implies immutability > > of state. There are no fields nor global variables that can be > > assigned to. Thus, one function can affect the computation carried out > > by another function only by the passing of parameters. Most GUI > > systems are built around the notion of event handlers which are > > invoked by a message processing loop. There is no chain of calls from > > one event handler to another. > > In particular, if handler "A" computed some new value it cannot pass > > it on to handler "B" because the system will call "B" only after "A" > > returns. That's the predicament. > > > ACP overcomes this by capturing the applications current state in an > > immutable map. All event handlers receive a single parameter which is > > the "current" context and compute the "new" context. A typical handler > > (henceforth: "context processing function") will carry out these > > activities: (a) Examine the current context; (b) Perform some GUI > > operations (setSize, setText, etc.); (c) Compute a new context based > > on the current context and on information obtained from the GUI > > (getText, etc.). The caller (henceforth: "dispatcher") takes the > > returned context and will use it as the new current context, the next > > time a context processing function is invoked. > > > This means that when you register event handler with a Swing widget > > the handler needs to to call the ACP dispatcher passing it a context > > processing function. > > > The net effect of this approach is that only the dispatcher has to > > deal with mutable state. The context processors are functional: they > > merely compute the new state from the current. > > > application-context-pattern.clj (http://groups.google.com/group/ > > clojure/web/application-context-pattern.clj) shows a concrete example. > > It's about 140 LOC (ripped off from the real Waterfront codebase) > > structured as follows: > > Lines 1..40: General-purpose helpers. > > Lines 40..90: The ACP infrastructure > > Lines 90..140: A quick sample, built around ACP. > > > The sample program opens a JFrame with two buttons: Input and Output. > > A click on the input button will pop-up an input dialog box. A click > > on the output button will pop-up a message box showing the last value > > entered into the input box. There's also a JLabel showing the length > > of the input, but let's ignore it for the moment. > > > The entry point into the ACP world is the bootstrap function. It takes > > two parameters: a context processing function and an initial context. > > In the example, this is carried out at the bottom of the run-it > > function: > > > (defn run-it [] > > (let [build-ui (fn [ctx] > > (let [f (javax.swing.JFrame. "Frame") > > b-in (javax.swing.JButton. "Input") > > b-out (javax.swing.JButton. "Output")] > > > (.addActionListener b-in (new-action-listener (fn [event] > > ((ctx :dispatch) get-input > > > (.addActionListener b-out (new-action-listener (fn [event] > > ((ctx :dispatch) show-output > > > (.setLayout f (java.awt.FlowLayout.)) > > (doseq [x [b-in b-out]] > > (.add f x) ) > > > (doto f > > (.setSize 500 300) > > (.setDefaultCloseOperation
Re: doc suggestion for future function
Hmm. This is becoming something of a puzzle. A simple noncode version of the model I am using is this (loop (increase year with 1) (break and create bidirectional links between refs) ) The break and create step represents a contact network between humans, where each human is basically a struct-map which holds a list of other humans s/he is currently connected to. These connections need to be atomically broken and created, hence the refs. More details in the chlam-clean.clj file, and the accompanying forum post. To get this thing concurrent (i.e, using the multiple cpu's in my machine) Timothy suggested ( http://groups.google.com/group/clojure/browse_thread/thread/13372bfe6bdd6497/0141cad632130799 ) to use the future function. I'll be working on that coming monday, but I was gathering some more information on how to use that future function in the mean time. (loop (increase year with 1) (concurrent: (break and create bidirectional links between refs)) (wait for year to finish) ) I'll try your suggestion and see if it is workable. Thanks! On Feb 28, 10:35 am, Christophe Grand wrote: > bOR_ a écrit : > > > can I call something like (apply await myvectorofrefs) if I have a > > bunch of futures running and I want to wait for them to finish before > > I go on with the next step in the model? > > No you can't use await. The simplest way to await for a future is to > deref it: @fut blocks until the computation ends. > Hence to await on a bunch of futures you can do: > (doseq [f futs] @f) or (dorun (map deref futs)) > > But, since deref blocks, do you really need to await on them? > > Christophe > > -- > Professional:http://cgrand.net/(fr) > On Clojure:http://clj-me.blogspot.com/(en) --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Opinions on -> macro?
e wrote: > I think it's simpler just to have a consistent syntax, personally. > Otherwise, why not python or haskell style syntax for the language? because > code is data. So now there's a special case where the data is backwards. Consistent syntax is nice, but not very useful if it gets in the way of readability. Fortunately, Clojure has a consistent method for designing arbitrary new syntax when needed. -> is not a "special case". It's a well-documented macro intended to make some kinds of expressions more readable. The non-macro syntax is "simpler", yes, but not always easier to read, which is the reason why -> exists. -- Jarkko --~--~-~--~~~---~--~~ 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 + Terracotta = Yeah, Baby!
My approach was just to share what few refs I wanted, but another approach (like Luc's) is to share everything. The obvious advantage being that you can set! the root binding of vars (like function definitions). The goal with Terracotta is to make things as transparent as possible, so I don't think "share everything" would be a huge number of changes here. I think there are only a few roadblocks. 1. Remove AtomicReferences from Namespace class. If this is possible, I think a major win for the share everything approach would be to share clojure.lang.Namespace.namespaces. Once that is done almost all of the objects will get shared by nature of being included in the clojure.lang.Namespace.namespaces object graph. Almost all of the static members of classes are assigned by looking up a var in a namespace, or by creating Symbols, which are not a problem as far as I have seen. 2. Static members that are not assigned by looking up a var in a namespace. I'm not sure how many there are, but one example would be PersistentHashMap.EMPTY. There is one trick to sharing this. PersistentHashMap depends upon APersistentMap to generate and assign it's hashCode value to the _hash member. The first time that hashCode is called on the PersistentHashMap.EMPTY instance, Terracotta throws an exception because PersistentHashMap.EMPTY is changed outside of a lock. This can be fixed by adding * clojure.lang.APersistentMap.hashCode(..) write to the Terracotta config. This will make Terracotta guard the APersistentMap.hashCode method. This works, but adding the synchronized keyword to the APersistentMap.hashCode method (as well as ASeq, APersistentSet, and APersistentVector) would be a simple change (assuming there aren't any consequences I'm missing). I don't see why any of the Persistent data structures would need to be modified. There may be other issues that will come about after these changes, but I think it would be a good first step. After that fine tuning the lock definitions could be done (although one could always just define a broad lock config). I could look into creating a Terracotta Integration Module so that people could just say, "Terracotta, I'm using Clojure," and all of the instrumented classes, roots, and locks would be configured automagically, then the work wouldn't have to be duplicated every time. Paul On Fri, Feb 27, 2009 at 9:55 PM, Luc Prefontaine wrote: > You're right Rich, > > We all have to agree on the means used to implement this in the Clojure > runtime. > Any code we throw right now has to be somewhat aligned with these decisions. > > The decision to hide the AtomicReference class was easy to take. It was an > unavoidable > obstacle. Any other issues from the Clojure run time will need more thinking > and > there might be other ways to do work around these issues. > > I can post an update each 2 weeks or so or on demand before we spit out code > if we face an issue. > > Right now we are busy writing a tool in Clojure to generate the terracotta > configuration > from a set of classes. Finding each dependent class one by one is too slow. > We always end up missing one. It will also spit out the locking section with > all these member functions. > > This tool will speed us a lot in getting the prototype up. We will get the > master pieces of > the XML configuration. We can them removing unwanted classes from the > configuration > and tune the locking strategy as you test things. > > Luc > > On Fri, 2009-02-27 at 18:05 -0800, Rich Hickey wrote: > > It would be great if you could mention the difficulties you face as > you go, before you spend too much time on workarounds. I am interested > in seeing Clojure on Terracotta and if there are things I can do > easily to support this effort I will. > > Rich > > -- > > Luc Préfontaine > > Off.:(514) 993-0320 > Fax.:(514) 993-0325 > > Armageddon was yesterday, today we have a real problem... --~--~-~--~~~---~--~~ 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: Contributing
On Feb 27, 2009, at 10:59 PM, Joshua wrote: > > I have started looking into Issue 34 and I have some questions. > > Link: > http://code.google.com/p/clojure/issues/detail?id=34&colspec=ID%20Type%20Status%20Priority%20Reporter%20Owner%20Summary > > Is the desired syntax to match the CL version? > Should I create a separate reader for the read-only version or just > use an if statement within the EvalReader? > *read-eval* as a flag checked in EvalReader should be enough. 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: Contributing
Thanks. Joshua On Feb 28, 2009, at 8:16 AM, Rich Hickey wrote: > > On Feb 27, 2009, at 10:59 PM, Joshua wrote: > >> >> I have started looking into Issue 34 and I have some questions. >> >> Link: >> http://code.google.com/p/clojure/issues/detail?id=34&colspec=ID%20Type%20Status%20Priority%20Reporter%20Owner%20Summary >> >> Is the desired syntax to match the CL version? >> Should I create a separate reader for the read-only version or just >> use an if statement within the EvalReader? >> > > *read-eval* as a flag checked in EvalReader should be enough. > > 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: Observations about new lazy branch
On Feb 27, 2009, at 11:10 PM, Mark Engelberg wrote: > > I just finished porting my combinatorics code to the new lazy > constructs, and I discovered some subtleties to using lazy-seq that > were not at first apparent. > > To begin with, consider the two versions of map: > The old way: > > (defn map > ([f coll] > (when (seq coll) > (lazy-cons (f (first coll)) (map f (rest coll) > > The new way: > > (defn map > ([f coll] > (lazy-seq >(when-let [s (seq coll)] > (cons (f (first s)) (map f (rest s)) > > Let's imagine that you are using map on a collection for which it is > very computation intensive to generate the rest, but trivial to > generate the first. > > I believe that in this case, you'd get more desirable behavior from > the old way than the new way. > > That's because the original lazy-cons kept the first and rest thunks > separate. It would force the first to get the rest, but it would NOT > force the rest to get at the first. So if you ask for the first, it > wouldn't do all the rest-generating computation. However, the new > version uses a delayed regular cons. So when you invoke the first of > the sequence, both arguments of cons are evaluated, so (map f (rest > s)) is called, and therefore (rest s) must be evaluated. > > If this is unclear, consider this: > (defn a [] (do (println "a") nil)) > (def s (lazy-seq (cons (a) (a > (first s) > > If you type this into the REPL, you'll see that the rest gets > evaluated when you ask for the first. > > To get the desired separation of first and rest evaluation with the > new lazy-seq function, you'd actually need to do something like this: > > (def lazier-map > (let [step (fn step [f coll] > (when-let [s (seq coll)] >(cons (f (first s)) (lazy-seq (step f (rest s))] >(fn [f coll] > (lazy-seq (step f coll) > > Basically, I've made a helper function which uses lazy-seq to delay > the evaluation of the rest, and then wrapped the call to the helper > function in a lazy-seq in order to delay evaluation of the very first > item. > > As a challenge, try to similarly fix up the version of filter provided > on the lazy page so that it fully separates the evaluation of first > and rest, thus protecting you against unnecessary evaluation if rest > is a slow operation on coll. I think you'll find that you end up with > two levels of indirection, and it's extremely difficult to write it > properly. Post your simplest solution here. > > Now in both these examples, you could argue that in all likelihood, > rest will be a fast operation. But I chose map here because everyone > knows the way we're supposed to write map, so it seemed like a good > choice to illustrate my concerns without having to explain how the > function works, etc. > > But this kind of problem does actually occur in practice. It appeared > in several places in the code I ported, because my code tends to do > most of the work within the arguments to the recursive call. I found > it difficult to reason about where to place the calls to lazy-seq in > order to achieve the separation I needed for evaluating the first and > the rest. I think I pulled it off correctly, but I've got to say I'm > not crazy about how, to do the "right thing", the code ends up looking > quite obfuscated. > > In summary, the new version gives you the most power to place the > delays where you want, but it's hard to get it right. > I think you've got the responsibilities wrong. If someone is making a "collection" for which first is cheap and rest expensive, and that doesn't build rest via a recursive call to a lazy-seq-bodied function (as do all the sequence fns), they could create it as follows: ... (cons cheap (lazy-seq (expensive))) All consumers of sequences presume each sequence is lazy if need be. Pushing the delaying of the rest part onto consumers is backwards. If you want a lazy collection, make one. Clojure's fully-lazy now pretty much follows the "even" model described by Wadler: How to add laziness to a strict language without even being odd: http://homepages.inf.ed.ac.uk/wadler/papers/lazyinstrict/lazyinstrict.ps with the enhancement of allowing interoperability between lazy and concrete sequences. I think your fundamental hangup is on looking at (rest x) as a calculation/effect triggered by a consumer. (rest x) is logically just a slot lookup that obtains another seq. The laziness of that seq is its constructor's problem. 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 -~--~~~~--~~--~--~---
StringSeq
I noticed the other day that StringBuffers aren't seq-able. Would it make sense to allow StringSeq to work on any CharSequence implementation, not just Strings? -- Dave --~--~-~--~~~---~--~~ 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: Waterfront 148 (was: Waterfront - The Clojure-based editor for Clojure)
On Sat, Feb 28, 2009 at 4:31 AM, Itay Maman wrote: > > Dan, Marko, > > I wonder whether you have the time to do a little experiment. The L&F > is set at line 182 of net/sourceforge/waterfront/ide/ui.clj. Could you > please try to see which L&F works on your machine or, otherwise, > understand why an exception is thrown there? > > Thanks, > -Itay I'm not at home right now but as soon as I return (should be Monday), I'll check My guess is that it has to do with KDE being based on Qt. Java only has a GTK+ look and feel for Linux so it probably consider it doesn't have my native look and feel available and defaults to metal. --~--~-~--~~~---~--~~ 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: The Application Context Pattern
On Feb 27, 5:38 pm, Marko Kocić wrote: > Interesting approach, nice explained. > > Does anyone have similar example using one of the cells > implementations? > What would be pros/cons between this and cells approach? I think that in general, when comparing powerful facilities (such as the Context-Pattern or Cells) one usually ends up with the conclusion that they are largely equivalent: the former can be implemented in terms of the latter and vice-versa. Thus, a discussion of pros and cons is more about stylistic issues: how hard is it to achieve a certain behavior in the two approaches? With that in mind I think that cells are the natural choice for implementing a complicated net of (well...) spread-sheet-like cells. Contexts are more natural for UI since the observers are ran only after a processor has finished. Even if the processor alters several values in the context, the observers will be notified only when the processor returns, seeing all the changes bundled together. In many cases this is the desired behavior in UI apps. If a single user request adds 100 strings to a list you want the corresponding widget to be updated once, not 100 times. I think the differences boil down to the fact the processors are functional in their nature: the processor per-se does not notify the observers, only the dispatcher does. Thus, you can compose two processors (in the same manner you compose functions) without worrying of side effects due to observers being fired. -Itay > > Regards, > Marko Kocić --~--~-~--~~~---~--~~ 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: Synchronous watches
On Feb 28, 12:47 am, Mark Derricutt wrote: > Apologies for thread-hijackig but I thought I'd mention that one of the > problems I've had using Clojure under OSGi was fixed with a minor patch > (mentioned in my post > athttp://www.talios.com/clojure_running_successfully_under_osgi.htm) which > had to do with the assumption non jar:// classpath entries were File's. > I've switched to url.openConnection().getLastModified() in svn 1313 - thanks for the report. 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: Clojure + Terracotta = Yeah, Baby!
1) AtomicReference is used in several places. Instead of changing it, we think we can keep it when Clojure runs "locally" and provide an alternative when running in "shared" mode. AtomicReference is optimized to be efficient in a standalone JVM. We would like to keep it that way. Eventually Terracotta will provide instrumentation on this class by default so the "shared" implementation could be thrown away in the near future. We see the double implementations as a transition period until Terracotta supports it directly. 2) Noted Shared versus local mode: That's what we have in mind, getting Clojure to work in a "shared" mode versus a local/standalone mode. We want 0 impacts on the user code. Eventually we could use meta data to provide some hints that would allow us to fine tune shared interactions from user code. This would not impact "local" mode behaviours. We're not there yet but we know that this possibility exists so that's reassuring for the future. Integration is pretty simple once the common code base integrates the necessary changes. We need a shell script, a Terracotta configuration that will be maintained as part of the Clojure code base and some documentation. As of now we use a system property to toggle the modes, we will implement a transparent way (testing the presence of a terracotta property most probably). Luc On Sat, 2009-02-28 at 06:35 -0500, Paul Stadig wrote: > My approach was just to share what few refs I wanted, but another > approach (like Luc's) is to share everything. The obvious advantage > being that you can set! the root binding of vars (like function > definitions). The goal with Terracotta is to make things as > transparent as possible, so I don't think "share everything" would be > a huge number of changes here. I think there are only a few > roadblocks. > > 1. Remove AtomicReferences from Namespace class. If this is possible, > I think a major win for the share everything approach would be to > share clojure.lang.Namespace.namespaces. Once that is done almost all > of the objects will get shared by nature of being included in the > clojure.lang.Namespace.namespaces object graph. Almost all of the > static members of classes are assigned by looking up a var in a > namespace, or by creating Symbols, which are not a problem as far as I > have seen. > > 2. Static members that are not assigned by looking up a var in a > namespace. I'm not sure how many there are, but one example would be > PersistentHashMap.EMPTY. There is one trick to sharing this. > PersistentHashMap depends upon APersistentMap to generate and assign > it's hashCode value to the _hash member. The first time that hashCode > is called on the PersistentHashMap.EMPTY instance, Terracotta throws > an exception because PersistentHashMap.EMPTY is changed outside of a > lock. This can be fixed by adding > > * > clojure.lang.APersistentMap.hashCode(..) > write > > to the Terracotta config. This will make Terracotta guard the > APersistentMap.hashCode method. This works, but adding the > synchronized keyword to the APersistentMap.hashCode method (as well as > ASeq, APersistentSet, and APersistentVector) would be a simple change > (assuming there aren't any consequences I'm missing). > > I don't see why any of the Persistent data structures would need to be > modified. There may be other issues that will come about after these > changes, but I think it would be a good first step. After that fine > tuning the lock definitions could be done (although one could always > just define a broad lock config). I could look into creating a > Terracotta Integration Module so that people could just say, > "Terracotta, I'm using Clojure," and all of the instrumented classes, > roots, and locks would be configured automagically, then the work > wouldn't have to be duplicated every time. > > > Paul > > On Fri, Feb 27, 2009 at 9:55 PM, Luc Prefontaine > wrote: > > You're right Rich, > > > > We all have to agree on the means used to implement this in the Clojure > > runtime. > > Any code we throw right now has to be somewhat aligned with these decisions. > > > > The decision to hide the AtomicReference class was easy to take. It was an > > unavoidable > > obstacle. Any other issues from the Clojure run time will need more thinking > > and > > there might be other ways to do work around these issues. > > > > I can post an update each 2 weeks or so or on demand before we spit out code > > if we face an issue. > > > > Right now we are busy writing a tool in Clojure to generate the terracotta > > configuration > > from a set of classes. Finding each dependent class one by one is too slow. > > We always end up missing one. It will also spit out the locking section with > > all these member functions. > > > > This tool will speed us a lot in getting the prototype up. We will get the > > master pieces of > > the XML configuration. We can them removing unwanted classes from the > > conf
Example JUnit 4.4 use with Clojure
If you want to use junit with clojure, this is what I ended up doing. Yes, I know there are many clojure test frameworks. But if you are stuck with a junit mind, then here is an example approach. http://clojure.googlegroups.com/web/junit_example_clojure.clj?gsc=rSQdQgsBq71IhmeUYhS87PjFY2mX --~--~-~--~~~---~--~~ 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: Example JUnit 4.4 use with Clojure
On Feb 28, 12:04 pm, BerlinBrown wrote: > If you want to use junit with clojure, this is what I ended up doing. > Yes, I know there are many clojure test frameworks. But if you are > stuck with a junit mind, then here is an example approach. > > http://clojure.googlegroups.com/web/junit_example_clojure.clj?gsc=rSQ... The source is contained within one file, but in reality they should be broken up into three files. 1. The Test Case 2. The Test Suite 3. The compile class. --~--~-~--~~~---~--~~ 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: Example JUnit 4.4 use with Clojure
On Feb 28, 12:05 pm, Berlin Brown wrote: > On Feb 28, 12:04 pm, BerlinBrown wrote: > > > If you want to use junit with clojure, this is what I ended up doing. > > Yes, I know there are many clojure test frameworks. But if you are > > stuck with a junit mind, then here is an example approach. > > >http://clojure.googlegroups.com/web/junit_example_clojure.clj?gsc=rSQ... > > The source is contained within one file, but in reality they should be > broken up into three files. > > 1. The Test Case > 2. The Test Suite > 3. The compile class. Here is the output: Running Test Suite .Dog F Time: 0.002 There was 1 failure: 1) testDog(test.OctaneSampleTestGen) junit.framework.AssertionFailedError: Test not implemented at test.OctaneSampleTestGen$_testDog__10.invoke (OctaneSampleTestGen.clj:55) at test.OctaneSampleTestGen.testDog(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at test.OctaneSampleTestGen.runTest(Unknown Source) at test.OctaneSampleTestGen.runBare(Unknown Source) at test.OctaneSampleTestGen.run(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:86) at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:192) at clojure.lang.Reflector.invokeStaticMethod(Reflector.java:178) at test.OctaneTestSuite$_main__19.doInvoke(OctaneTestSuite.clj:58) at clojure.lang.RestFn.applyTo(RestFn.java:142) at test.OctaneTestSuite.main(Unknown Source) --~--~-~--~~~---~--~~ 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: dorun and map
On 25 Feb., 15:02, Stuart Sierra wrote: > I often find I need to do this when the mapping function depends on a > dynamic context, like an open stream or an SQL connection. I'm not > using side effects in this case, but I have to make sure that the > sequence is completely realized before leaving the scope in which it > was created. This issue has been mentioned before, but there doesn't > seem to be a good general-purpose solution. I have an "eager" module that contains emap, econcat, efilter and things like that. Open streams, SQL result sets, stuff that uses dynamic variables. Cheers, Juergen --~--~-~--~~~---~--~~ 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: The Application Context Pattern
Hi Itay, I'm a little confused about one aspect of the context pattern. If I understand this write, a listener is a function that takes an old context, and returns a new context, BUT it also calls the appropriate GUI functions (setText, setSize) to ensure that the gui state is consistent with the new context. Is that correct? If so then the listeners aren't purely functional. They don't affect any mutable state in atoms or refs, but they mutate the current running state of the GUI. So side-effects of these functions are therefore important. --~--~-~--~~~---~--~~ 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: Opinions on -> macro? (was Re: Extensive use of let?)
On Feb 27, 1:39 pm, "John D. Hume" wrote: > As a Java/Ruby guy who is not used to reading inside out, I'm curious > as to whether people who ARE accustomed to LISP find the -> macro > distracting since it flops things around. Are there circumstances > where you prefer it? Definitely. When you're applying a bunch of functions to the same object, it can be clearer to use ->. I don't use it often, but when I do, my code is much easier to read. -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: The Application Context Pattern
Hi, On Feb 28, 8:32 pm, CuppoJava wrote: > Hi Itay, > I'm a little confused about one aspect of the context pattern. > > If I understand this write, a listener is a function that takes an old > context, and returns a new context, BUT it also calls the appropriate > GUI functions (setText, setSize) to ensure that the gui state is > consistent with the new context. Is that correct? Yes. > > If so then the listeners aren't purely functional. They don't affect > any mutable state in atoms or refs, but they mutate the current > running state of the GUI. So side-effects of these functions are > therefore important. Processors/observers may mutate the UI. Yet, even if the processors manipulate the UI, they will not cause observer-issued side effects. Also, the affect of either processors or observers is limited to the UI - their behavior WRT to the program-manged state is side-effect free. Thanks for bringing this up, I wasn't very clear. -Itay --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
new Clojure article
I've written an article on Clojure. See http://ociweb.com/jnb/jnbMar2009.html. The goal of this article is to provide a fairly comprehensive introduction to the Clojure programming language. A large number of features are covered, each in a fairly brief manner. Check out the hyperlinked table of contents. Thanks to all of you that have patiently answered my questions about Clojure over that past couple of months! While reading this, if you spot errors or just have ideas for better ways to explain certain concepts, please email me. I plan to make updates to the article frequently in order to make it as valuable a resource as possible. -- R. Mark Volkmann Object Computing, Inc. --~--~-~--~~~---~--~~ 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 + Terracotta = Yeah, Baby!
In the Namespace case, it might be premature optimization to worry about AtomicReference being replaced. If there is a way to rewrite that code with, say, synchronized blocks, and it will work better with Terracotta, I think it would be worth doing. I don't think it would be normal usage to be updating the mappings and aliases in a namespace 1,000 times a second. AtomicReference is also used in Atom and Agent. Those cases may not be as straight forward. Paul On Sat, Feb 28, 2009 at 11:51 AM, Luc Prefontaine wrote: > > 1) AtomicReference is used in several places. Instead of changing it, we > think we can keep > it when Clojure runs "locally" and provide an alternative when running in > "shared" mode. > > AtomicReference is optimized to be efficient in a standalone JVM. We would > like to > keep it that way. Eventually Terracotta will provide instrumentation on this > class > by default so the "shared" implementation could be thrown away in the near > future. > We see the double implementations as a transition period until Terracotta > supports > it directly. > > 2) Noted > > Shared versus local mode: > > That's what we have in mind, getting Clojure to work in a "shared" mode > versus a > local/standalone mode. We want 0 impacts on the user code. Eventually we > could use meta data to provide some hints that would allow us to fine tune > shared interactions from user code. This would not impact "local" mode > behaviours. > We're not there yet but we know that this possibility exists so that's > reassuring > for the future. > > Integration is pretty simple once the common code base integrates the > necessary > changes. We need a shell script, a Terracotta configuration that will be > maintained > as part of the Clojure code base and some documentation. > > As of now we use a system property to toggle the modes, we will implement a > transparent way (testing the presence of a terracotta property most > probably). > > > Luc --~--~-~--~~~---~--~~ 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 + Terracotta = Yeah, Baby!
We think the same way. Our first implementation of an alternative to AtomicReference is straightforward, we will look at improving it if the need arises. It will be easier to do so when we get stats from Terracotta after running some benchmarks. There's much to do before getting there. Luc On Sat, 2009-02-28 at 14:33 -0500, Paul Stadig wrote: > In the Namespace case, it might be premature optimization to worry > about AtomicReference being replaced. If there is a way to rewrite > that code with, say, synchronized blocks, and it will work better with > Terracotta, I think it would be worth doing. I don't think it would be > normal usage to be updating the mappings and aliases in a namespace > 1,000 times a second. > > AtomicReference is also used in Atom and Agent. Those cases may not be > as straight forward. > > > Paul > > On Sat, Feb 28, 2009 at 11:51 AM, Luc Prefontaine > wrote: > > > > 1) AtomicReference is used in several places. Instead of changing it, we > > think we can keep > > it when Clojure runs "locally" and provide an alternative when running in > > "shared" mode. > > > > AtomicReference is optimized to be efficient in a standalone JVM. We would > > like to > > keep it that way. Eventually Terracotta will provide instrumentation on this > > class > > by default so the "shared" implementation could be thrown away in the near > > future. > > We see the double implementations as a transition period until Terracotta > > supports > > it directly. > > > > 2) Noted > > > > Shared versus local mode: > > > > That's what we have in mind, getting Clojure to work in a "shared" mode > > versus a > > local/standalone mode. We want 0 impacts on the user code. Eventually we > > could use meta data to provide some hints that would allow us to fine tune > > shared interactions from user code. This would not impact "local" mode > > behaviours. > > We're not there yet but we know that this possibility exists so that's > > reassuring > > for the future. > > > > Integration is pretty simple once the common code base integrates the > > necessary > > changes. We need a shell script, a Terracotta configuration that will be > > maintained > > as part of the Clojure code base and some documentation. > > > > As of now we use a system property to toggle the modes, we will implement a > > transparent way (testing the presence of a terracotta property most > > probably). > > > > > > Luc > > > -- Luc Préfontaine Off.:(514) 993-0320 Fax.:(514) 993-0325 Armageddon was yesterday, today we have a real problem... --~--~-~--~~~---~--~~ 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: Opinions on -> macro?
> Consistent syntax is nice, but not very useful if it gets in the way > of readability. Fortunately, Clojure has a consistent method for > designing arbitrary new syntax when needed. -> is not a "special > case". It's a well-documented macro intended to make some kinds of > expressions more readable. The non-macro syntax is "simpler", yes, but > not always easier to read, which is the reason why -> exists. > it's yet one more thing to learn how to read, so there's a trade off. Once you know it, the claim is that easier to read. > > -- > Jarkko > > > --~--~-~--~~~---~--~~ 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: Opinions on -> macro?
-> confuses me: Does it treat functions with multiple parameters different from functions with one parameter? Am I right that it can only be used with the latter? Joshua --~--~-~--~~~---~--~~ 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: Opinions on -> macro?
Hi, Am 28.02.2009 um 22:39 schrieb Joshua Fox: -> confuses me: Does it treat functions with multiple parameters different from functions with one parameter? Am I right that it can only be used with the latter? (-> a-thing fun-1 (fun-2) (fun-3 b-thing)) is turned into (fun-3 (fun-2 (fun-1 a-thing)) b-thing) So, -> takes the first argument and places it as first argument in the second argument. If the second argument is not a list, -> creates automatically a list the given thing as first argument. So here are the cases. (-> x foo) => (foo x) (-> x (foo)) => (foo x) (-> x (foo a b c)) => (foo x a b c) This works recursively. So you can easily chain functions together. One nice example is that of nested maps as given by James before in this thread. (-> the-map :a :b :c) is turned into (:c (:b (:a the-map))) Now consider the-map to be {:a {:b {:c 5}}} Then the above evaluates to 5. A bit contorted, but I hope this helps. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: Opinions on -> macro?
You are wrong. Many writings use ,, as a place-holder for where -> is placing the argument. Take Meikel's example above: (foo (bar (baz (frobnicate a-thing)) bla)) Becomes (-> a-thing frobnicate baz (bar bla) foo) So bar is a function of more than one argument. Re-written with place- holders it would be: (-> a-thing (frobnicate ,,) (baz ,,) (bar ,, bla) (foo ,,)) Does that make it more clear? -Drew On Feb 28, 9:39 pm, Joshua Fox wrote: > -> confuses me: Does it treat functions with multiple parameters different > from functions with one parameter? Am I right that it can only be used with > the latter? > Joshua --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Debugging Clojure with IntelliJ IDEA
Hello, all. Last build of "La Clojure" plugin for IntelliJ IDEA now supports debug for Clojure programs. It could be downloaded from http://plugins.intellij.net/plugin/?id=4050 Moreover, we've implemented completion for Java instance methods and implicitly imported classes. With best regards, Ilya Sergey JeetBrains Inc. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Early registration for International Lisp Conference (Cambridge, MA, 22-25 March 2009)
Rich will be presenting a "Clojure in Depth" tutorial session on Sunday, 22 March 2009 at the International Lisp Conference taking place at MIT in Cambridge, MA: http://www.international-lisp-conference.org/2009/tutorials#clojure It's scheduled in 3 parts for a total of 5 hours: http://www.international-lisp-conference.org/2009/schedule The conference agenda contains a lot more interesting Lisp-related content as well: http://www.international-lisp-conference.org/2009/index I'm writing to mention this today because the early registration deadline is nearly upon us. The conference fee for an individual participant is $210 on or before 1 March 2009 and rises to $250 after that: http://www.regonline.com/builder/site/Default.aspx?eventid=688757 If you've been on the fence about attending, now is a good time to conclude: "There's no way I'm missing that!" Cheers, --Steve smime.p7s Description: S/MIME cryptographic signature
Re: (rest ())
As Rich explained in one post, in Lisp-like languages, there is a certain amount of intertwining between two views of a sequence which is a series of linked nodes. One way is to think about these nodes as just nodes with a first and rest. Another way is to think about each node as representing an entire chain from this node onward to the end. He explained that next is more like the "move from one node to another" view, and rest is more like the view of these things as collections, where rest gives you the collection of everything but the first. (rest []) translates in my mind to "everything but the first item of []". There is no first item of [], and there isn't an everything-but-the-first-item of it. It's empty. You can't take something out of it. In Scheme, Haskell, ML, etc., the rest of something empty would produce an error. In Clojure, which seems to be less inclined to produce error messages, I'd expect it to produce nil, in the sense of "this has no meaning or no answer" (not in the sense of nil as an empty-like entity). Coming from other functional languages, (rest ()) producing () seems bizarre to me. If you think of (rest sequence) as looking up some "rest" slot in sequence, '(1) has some sort of empty thing in the rest slot. In contrast, the empty sequence doesn't even have a rest slot (or if it does, you'd expect that it stores null/nil in it, rather than another empty sequence). --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
functional programming idiom
hello, what's the common idiom in functional programming regarding checking the validity of arguments to functions. i think this is called defensive programming vs contract programming. for example: ;; this first version of foo checks the validity of arguments inside foo (defn foo [context arg] (if (arg-valid? arg) (change-context context arg) context)) ;; this version assumes that the caller of foo fulfills the preconditions of foo (defn foo "Precondition: (arg-valid? arg)" [context arg] (change context arg)) --~--~-~--~~~---~--~~ 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: Observations about new lazy branch
On Sat, Feb 28, 2009 at 6:09 AM, Rich Hickey wrote: > I think your fundamental hangup is on looking at (rest x) as a > calculation/effect triggered by a consumer. (rest x) is logically just > a slot lookup that obtains another seq. The laziness of that seq is > its constructor's problem. Right, I'm aware that "rest" isn't an expensive operation. This was meant to be for illustrative purposes. In my actual code, it's more like this: Imagine a permutation algorithm that works by storing the sequence in a vector, and then permuting the various indices to get new sequences. Simplifying considerably, with no laziness, the heart might look kind of like this: (defn permutation-helper [v indices] (cons (vector-in-order-of-indices v indices) (permutations v (do-complicated-transformation-of-indices-to-next-permutation indices So where should the lazy-seq call go? (defn permutation-helper [v indices] (lazy-seq (cons (vector-in-order-of-indices v indices) (permutations v (do-complicated-transformation-of-indices-to-next-permutation indices) unnecessarily does the complicated-transform function when you call first. (defn permutation-helper [v indices] (cons (vector-in-order-of-indices v indices) (lazy-seq (permutations v (do-complicated-transformation-of-indices-to-next-permutation indices) works better for this case, but unnecessarily does the vector-in-order-of-indices at the beginning, and whenever you call rest (not a hugely expensive operation, but let's pretend it is). (defn permutation-helper [v indices] (lazy-seq (cons (vector-in-order-of-indices v indices) (lazy-seq (permutations v (do-complicated-transformation-of-indices-to-next-permutation indices)) delays everything, but with a whole lot of overhead. When you have a lot of local definitions that compute things before the first call, and the helper function is embedded in something else, deciding where to put lazy-seq becomes even more complicated. For the most part, I decided the odd-style worked best, and went with something like this: (defn permutation-helper [v indices] (cons (vector-in-order-of-indices v indices) (lazy-seq (permutations v (do-complicated-transformation-of-indices-to-next-permutation indices) (defn permutation [sequence] (lazy-seq (permutation-helper (vec sequence) (initialize-indices))) thus delaying the setup and first element of the list, as well as all the rests. This is all just pseudo-code and not the actual thing, but it's enough to convey the idea. My point is that lazy-seq gives you a lot more choices than lazy-cons, but isolating the expensive part, rather than just blindly choosing even laziness (which is the paradigm it's mainly geared for), can be complicated. As I mentioned, rewriting filter to delay the call to rest is an interesting exercise to see the challenge involved (although I acknowledge that delaying rest isn't inherently useful given that, like you said, sequence providers will ensure that.rest is fast). --~--~-~--~~~---~--~~ 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: new Clojure article
Thank you. Now I have something to link friends too when they ask about Clojure. Mark Volkmann wrote: > I've written an article on Clojure. See http://ociweb.com/jnb/jnbMar2009.html. > > The goal of this article is to provide a fairly comprehensive > introduction to the Clojure programming language. A large number of > features are covered, each in a fairly brief manner. Check out the > hyperlinked table of contents. > > Thanks to all of you that have patiently answered my questions about > Clojure over that past couple of months! > > While reading this, if you spot errors or just have ideas for better > ways to explain certain concepts, please email me. I plan to make > updates to the article frequently in order to make it as valuable a > resource as possible. > > -- > R. Mark Volkmann > Object Computing, Inc. --~--~-~--~~~---~--~~ 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: Observations about new lazy branch
On Sat, Feb 28, 2009 at 6:09 AM, Rich Hickey wrote: > Clojure's fully-lazy now pretty much follows the "even" model > described by Wadler: > > How to add laziness to a strict language without even being odd: > > http://homepages.inf.ed.ac.uk/wadler/papers/lazyinstrict/lazyinstrict.ps OK, I just read the article. Section 4.3 is basically what I was talking about, where he talks about how, without the $ notation, the decrement in the call to countdown gets evaluated too soon. The postscript suggests that integrating something like the $ syntactic sugar does not conflict, and gives the best of both worlds. Maybe something like that could be added to Clojure to work with lazy-seq... --~--~-~--~~~---~--~~ 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: new Clojure article
I'm in the process of learning Clojure so this article has already helped me quite a bit (about half done with it). Bookmarked. Thanks Mark for the work. --~--~-~--~~~---~--~~ 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: Denver/Boulder Clojure users
I live in Boulder but have just started using Clojure. --~--~-~--~~~---~--~~ 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: Debugging Clojure with IntelliJ IDEA
Wow it's incredible how fast your progressing on the plugin. It's already a joy to use. Thank you very much. Is there a way to automatically indent when I press Enter? --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
letfn - mutually recursive local functions
I've added letfn, which lets you define mutually recursive local functions a la CL's labels. (defn ring [n] (letfn [(a [n] (if (zero? n) n (b (dec n (b [n] (if (zero? n) n (c (dec n (c [n] (if (zero? n) n (a (dec n] (c n))) (ring 1000) Note this is still subject to stack limits, i.e. no TCO, so please don't report your StackOverflowErrors. Useful for bounded data only. 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: Debugging Clojure with IntelliJ IDEA
Hello. What do you mean by "automatically indent"? If you press enter inside a Sexpr, vector or map, indentation will be ferformed automatically. Kind regards, Ilya On Mar 1, 1:37 am, CuppoJava wrote: > Wow it's incredible how fast your progressing on the plugin. It's > already a joy to use. Thank you very much. > > Is there a way to automatically indent when I press Enter? --~--~-~--~~~---~--~~ 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: Debugging Clojure with IntelliJ IDEA
Oh I'm sorry, I was still accidentally running the previous version. Indentation works perfectly. Thank you very much for this plugin. Debugging support is so invaluable to me. May I ask how long you think the Surround-With feature will take? -Patrick PS: I found your profile on the IntelliJ team page. You're only a year older than me! How did you land a job with IntelliJ? Have you been working there long? I assume you finished your Masters only recently. --~--~-~--~~~---~--~~ 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: Opinions on -> macro? (was Re: Extensive use of let?)
2009/2/28 Stuart Sierra > > On Feb 27, 1:39 pm, "John D. Hume" wrote: > > As a Java/Ruby guy who is not used to reading inside out, I'm curious > > as to whether people who ARE accustomed to LISP find the -> macro > > distracting since it flops things around. Are there circumstances > > where you prefer it? > > Definitely. When you're applying a bunch of functions to the same > object, it can be clearer to use ->. I don't use it often, but when I > do, my code is much easier to read. What you really wanted to say is "a bunch of functions to one object". (If it is to the same object, then it's doto that should be use) ? > > -Stuart Sierra > - Afficher le texte des messages précédents - > > > --~--~-~--~~~---~--~~ 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: Opinions on -> macro? (was Re: Extensive use of let?)
First, I have to say thanks. I'm only a part-time Clojure user, and I didn't know of the -> macro until today. Second, I think the -> syntax leads to more readable code for precisely those situations where you're coding a sequence of actions. Finally, I've got a comment about what I think might be a useful addition to Clojure. In my day job, I've been using F#. F# has a |> operator which relies on automatic currying to do what, at first blush, I though the -> macro did. In other words, if you've got, for example, a list of data in F#, you can do something like: listOfNum |> (map someFn) |> (filter anotherFn) |> max ;; note the brackets aren't necessary ;; I added them for readability which is functionally equivalent to: max ( filter anotherFn (map someFn listOfNum))) I quickly learned the -> macro can't be used in the same way for one simple reason; the value that is threaded through to the forms is always placed in the first argument position. How about adding a macro -- it could be called |> just as in F# -- that places the value in the last argument position? (It's dead simple to write -- I just copied and modified the -> macro.) With the new macro it would be possible to write code like: ( |> list-of-num ( map some-fn ) ( filter another-fn ) ( max )) instead of: (max (filter another-fn (map some-fn list-of-num))) IMHO, the |> macro, just like the -> macro, makes the sequence of the actions much easier to follow. Cheers, -- BF On Feb 27, 1:39 pm, "John D. Hume" wrote: > On Wed, Feb 25, 2009 at 4:11 PM, Jason Wolfe wrote: > > (you'll get use to reading inside-out quickly). > > As a Java/Ruby guy who is not used to reading inside out, I'm curious > as to whether people who ARE accustomed to LISP find the -> macro > distracting since it flops things around. Are there circumstances > where you prefer it? --~--~-~--~~~---~--~~ 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: letfn - mutually recursive local functions
On Sat, Feb 28, 2009 at 7:38 PM, Rich Hickey wrote: > > I've added letfn, which lets you define mutually recursive local > functions a la CL's labels. > > (defn ring [n] > (letfn [(a [n] (if (zero? n) n (b (dec n > (b [n] (if (zero? n) n (c (dec n > (c [n] (if (zero? n) n (a (dec n] > (c n))) > > (ring 1000) > > Note this is still subject to stack limits, i.e. no TCO, so please > don't report your StackOverflowErrors. Useful for bounded data only. This does work quite nicely with trampoline, though: (letfn [(a [n] #(if (zero? n) n (b (dec n (b [n] #(if (zero? n) n (c (dec n (c [n] #(if (zero? n) n (a (dec n] (trampoline c 10)) --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: Clojure + Terracotta = Yeah, Baby!
Hi guys, I work for Terracotta ( on the server side ) and find this work with Clojure + Terracotta very exciting. Writing a TIM is definitely the way to go, It's a place to hide the glue until both Terracotta and Clojure catches up with each other. If you have any questions feel free to post on our forums http://forums.terracotta.org/forums/forums/list.page If you check out our trunk version, theres also an effort to make a common-api which will help writing a TIM easier for you guys. Good luck! -Nabib On Sat, Feb 28, 2009 at 12:02 PM, Luc Prefontane < lprefonta...@softaddicts.ca> wrote: > We think the same way. Our first implementation of an alternative to > AtomicReference > is straightforward, we will look at improving it if the need arises. > > It will be easier to do so when we get stats from Terracotta after running > some benchmarks. > There's much to do before getting there. > > Luc > > > > On Sat, 2009-02-28 at 14:33 -0500, Paul Stadig wrote: > > In the Namespace case, it might be premature optimization to worryabout > AtomicReference being replaced. If there is a way to rewritethat code with, > say, synchronized blocks, and it will work better withTerracotta, I think it > would be worth doing. I don't think it would benormal usage to be updating > the mappings and aliases in a namespace1,000 times a second. > AtomicReference is also used in Atom and Agent. Those cases may not beas > straight forward. > > Paul > On Sat, Feb 28, 2009 at 11:51 AM, Luc > Prefontaine wrote:>> 1) AtomicReference is used > in several places. Instead of changing it, we> think we can keep> it when > Clojure runs "locally" and provide an alternative when running in> "shared" > mode.>> AtomicReference is optimized to be efficient in a standalone JVM. We > would> like to> keep it that way. Eventually Terracotta will provide > instrumentation on this> class> by default so the "shared" implementation > could be thrown away in the near> future.> We see the double implementations > as a transition period until Terracotta> supports> it directly.>> 2) Noted>> > Shared versus local mode:>> That's what we have in mind, getting Clojure to > work in a "shared" mode> versus a> local/standalone mode. We want 0 impacts > on the user code. Eventually we> could use meta data to provide some hints > that would allow us to fine tune> shared interactions from user code. This > would not impact "local" mode> behaviours.> We're not there yet but we know > that this possibility exists so that's> reassuring> for the future.>> > Integration is pretty simple once the common code base integrates the> > necessary> changes. We need a shell script, a Terracotta configuration that > will be> maintained> as part of the Clojure code base and some > documentation.>> As of now we use a system property to toggle the modes, we > will implement a> transparent way (testing the presence of a terracotta > property most> probably).>>> Luc > > > -- > > Luc Préfontaine > > Off.:(514) 993-0320 > Fax.:(514) 993-0325 > > Armageddon was yesterday, today we have a real problem... > > > > > --~--~-~--~~~---~--~~ 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 + Terracotta = Yeah, Baby!
> > > Writing a TIM is definitely the way to go, It's a place to hide the glue > until both Terracotta and Clojure catches up with each other. uhhh what is a TIM? Thanks Hank -- blog: whydoeseverythingsuck.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: Clojure + Terracotta = Yeah, Baby!
Its a way to package integration details into a module. For example, if I want to cluster EHCache, I can drive through the code and figure out what data structure to share and subsequently lock on. All that work can be packaged into a module for terracotta, so that way people who just want to use ehcache + terracotta change just include tim-ehache in terracotta configuration and that's it. the same can be done for clojure. the details can be abstract to a tim-clojure. http://www.terracotta.org/web/display/docs/Terracotta+Integration+Modules+Manual -Nabib On Sat, Feb 28, 2009 at 8:16 PM, hank williams wroote: > >> Writing a TIM is definitely the way to go, It's a place to hide the glue >> until both Terracotta and Clojure catches up with each other. > > > > uhhh what is a TIM? > > > Thanks > Hank > > > > -- > blog: whydoeseverythingsuck.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 -~--~~~~--~~--~--~---
time complexity for immutable priority queue?
After helping tutor some students earlier in the week on the subject of priority queues, I ended up implementing it in Clojure as a mutable data structure. It was straight forward, but curiosity struck and I implemented the priority queue as an immutable data structure. I'm pretty sure that 'ffirst 'first 'count and 'rest have a constant time complexity, but it is a little hard to wrap my mind around this code. Is it really constant time? ;- immutiable priority queue - (defn priority-cons [priority data queue] (defstruct element :priority :data) (let [elem (struct element priority data) queue-first (if (nil? queue) nil (queue 'ffirst)) queue-rest (cond (nil? queue) nil (nil? elem) (queue 'rest) (>= priority (queue-first :priority)) queue :else (priority-cons priority data (queue 'rest)))] (fn [op] (cond (= op 'count) (cond (nil? queue) 1 (nil? elem) (queue 'count) :else (inc (queue 'count))) (= op 'first) (cond (nil? queue) data (nil? elem) nil (>= priority (queue-first :priority)) data :else (queue-first :data)) (= op 'ffirst) (cond (nil? queue) elem (nil? elem) nil (>= priority (queue-first :priority)) elem :else queue-first) (= op 'rest) queue-rest ;--- testing code (defn print-priority-queue [queue] (loop [queue queue] (if (nil? queue) nil (do (println (queue 'first)) (recur (queue 'rest)) (def a (priority-cons 10 "hello" nil)) (print-priority-queue a) (a 'count) (def b (priority-cons 20 "hello2" a)) (print-priority-queue b) (b 'count) (def c (priority-cons 15 "hello-m" b)) (print-priority-queue c) (c 'count) ((c 'rest) 'count) (((c 'rest) 'rest) 'first) (((c 'rest) 'rest) 'count) (((c 'rest) 'rest) 'rest) --~--~-~--~~~---~--~~ 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?
I had the same problem with the Vim Repl, but rebuilding Gorilla fixed the problem. Build instructions are in the README, but to paraphase: $ cd /path/to/gorilla-1.1.1 $ vi local.properties $ cat local.properties clojure.jar=/path/to/clojure.jar clojure-contrib.jar=/path/to/clojure-contrib.jar $ ant clean jar (re-start Gorilla) Now pressing Enter at the Vim Repl sends to the socket Repl, and the value is returned. Note that control-Enter doesn't evaluate the input. This seems to be the reverse of what the screen-cast says (where control-Enter evaluates and Enter does not), but this behaviour seems better. Environment: clojure r1312, contrib r1312, gorilla 1.1.1, MacVim 7.2, Mac OS X 10.5.6 Thanks for a great plugin Meikel! -Matt --~--~-~--~~~---~--~~ 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?
> Environment: ... contrib r1312 ... Sorry, that should be clojure-contrib r545 (the latest revision) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---