prog1
Hello, I was missing the prog1 macro from common lisp, so here it is. (defmacro prog1 [ body] (prog1 forms*) Evaluates all the forms, returning the result of the first form `(let [result# ~(first body)] ~@(rest body) result#)) user (prog1 a b c) a user (prog1) nil user (prog1 a) a Might be usefull to have this in the language. Maybe it's already there but couldn't find it ! Sacha --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Patch and audit: Use vectors for bindings in doseq, et al.
On Nov 8, 8:52 am, Chouser [EMAIL PROTECTED] wrote: Attached is an updated patch. Instead of using for in the implementation of doseq, this has a doseq that uses loop/recure. The interface is the same, but it should run faster. This also means doseq is only defined once (nor redefined as in the earlier patch). This patch is against 1089, the Interim checkin - DO NOT USE!! version of SVN. Patch applied - many thanks!! Rich On Sat, Nov 8, 2008 at 7:42 AM, Rich Hickey [EMAIL PROTECTED] wrote: On Nov 7, 5:09 pm, James Reeves [EMAIL PROTECTED] wrote: On Nov 7, 9:32 pm, Chouser [EMAIL PROTECTED] wrote: And in which case, your vector syntax could be misleading, because it seems to imply you're assigning i to 10: (dotimes [i 10] (prn i)) Vectors are also used for for: (for [i (range 10)] (* 2 i)) Here i is not bound to the seq (range 10) but to each of the numbers in turn. I'm still not convinced on this one. Currently, you have single assignments, where a value is assigned to a symbol as in let and binding, and sequence assignments, where each item in the sequence is assigned to a symbol. Adding a vector to dotimes would add a third type, and I don't think it's obvious what the [i 10] does. I mean, you originally put it down as [i (range 10)], so you were thinking in terms of [symbol sequence] too. The general idea behind this patch is that all macros that introduce names will do so in vector syntax. The nature of the bindings is going to be open, as is the set of macros - doseq/dotimes/let/loop all have different semantics. As it stands, it is confusing for people because they don't know if they need a vector or not, for each macro. Second, with your patch, is the following valid: (doseq [i (range 10) j (range 10)] (prn i) (prn j)) It behaves the same as for does, that is with j in an inner loop. It also supports :while and :when as for does. Well, not that my opinion matters ;) - but you've sold me on this one. Consistency with the for macro seems reasonable. This is a much-needed enhancement, as so many people use for for side- effects and forget dorun. Plus it will be faster for that use. My first inclination is to disallow it -- add a check to make sure only one binding pair is given. Alternatively it could act as if it were nested, as for (and now doseq) do, in which case it would act like an and, and both x and y would be bound to non-false values. Hm. A nested if would be consistent with the nested for and doseq macros. If this is implemented, nesting ifs would be my preference for this. I'd like to see this patch limit its enhancements to doseq a la for, and otherwise just be a syntax change for all the others. Rich doseq-vector-2.patch 27KViewDownload --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Patch and audit: Use vectors for bindings in doseq, et al.
On Nov 7, 5:09 pm, James Reeves [EMAIL PROTECTED] wrote: On Nov 7, 9:32 pm, Chouser [EMAIL PROTECTED] wrote: And in which case, your vector syntax could be misleading, because it seems to imply you're assigning i to 10: (dotimes [i 10] (prn i)) Vectors are also used for for: (for [i (range 10)] (* 2 i)) Here i is not bound to the seq (range 10) but to each of the numbers in turn. I'm still not convinced on this one. Currently, you have single assignments, where a value is assigned to a symbol as in let and binding, and sequence assignments, where each item in the sequence is assigned to a symbol. Adding a vector to dotimes would add a third type, and I don't think it's obvious what the [i 10] does. I mean, you originally put it down as [i (range 10)], so you were thinking in terms of [symbol sequence] too. The general idea behind this patch is that all macros that introduce names will do so in vector syntax. The nature of the bindings is going to be open, as is the set of macros - doseq/dotimes/let/loop all have different semantics. As it stands, it is confusing for people because they don't know if they need a vector or not, for each macro. Second, with your patch, is the following valid: (doseq [i (range 10) j (range 10)] (prn i) (prn j)) It behaves the same as for does, that is with j in an inner loop. It also supports :while and :when as for does. Well, not that my opinion matters ;) - but you've sold me on this one. Consistency with the for macro seems reasonable. This is a much-needed enhancement, as so many people use for for side- effects and forget dorun. Plus it will be faster for that use. My first inclination is to disallow it -- add a check to make sure only one binding pair is given. Alternatively it could act as if it were nested, as for (and now doseq) do, in which case it would act like an and, and both x and y would be bound to non-false values. Hm. A nested if would be consistent with the nested for and doseq macros. If this is implemented, nesting ifs would be my preference for this. I'd like to see this patch limit its enhancements to doseq a la for, and otherwise just be a syntax change for all the others. 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
Hello, Is there a benefit in implementing this as a macro instead of a function? The function version would be very simple: (defn returning [returnval body] returnval) This is just a K combinator with varargs. Robert Pfeiffer --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
doseq, dotimes loop/recur
More of an inquiry into the fp mindset as opposed to the procedural one than anything else ... If I got this right, there are two forms of iterations: internal and external. `map' is an internal iterator, `doseq' is an external iterator. An internal iterator does the iteration by itself and applies some provided fn to the collection, possibly resulting into some new collection. An external iterator provides you with the closest access to the collection, allowing you to decide for yourself what you want to do inline on an element by element basis, possibly deciding on a course of actions depending on the values seen so far, which would be more difficult to do with an internal iterator such as `map', because the fn would need to be passed those previous values of interest as arguments each time. Now, if I summarize the set of clojure provided iterations forms I get the internal ones such as `map' or 'reduce', the external ones such as `doseq' or `dotimes', plus, via loop/recur the means by which to implement my own internal iterators in the `map'/`reduce' vein. The question then is: is this all there is to iteration? And if any external iterator beyond `doseq' and `dotimes` is missing, what would they be? --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
On Nov 8, 2008, at 5:55 AM, Phlex wrote: Hello, I was missing the prog1 macro from common lisp, so here it is. (defmacro prog1 [ body] (prog1 forms*) Evaluates all the forms, returning the result of the first form `(let [result# ~(first body)] ~@(rest body) result#)) user (prog1 a b c) a user (prog1) nil user (prog1 a) a Might be usefull to have this in the language. Maybe it's already there but couldn't find it ! I came across a place where it would be useful as well, but worked around it manually. do1 would arguably fit better into Clojure's naming scheme. I think none of prog1, prog2, or a hypothetical do1 have names that really jump out at a beginner with what they mean (though of course, one isn't a beginner forever). A collection of some useful CL macros written in Clojure would probably make a nice addition to the wiki. --Steve --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
Hi, Am 08.11.2008 um 17:10 schrieb Robert Pfeiffer: Is there a benefit in implementing this as a macro instead of a function? The function version would be very simple: (defn returning [returnval body] returnval) Although I'm a strong proponent of using macros only where they are really needed, I would make an exception here. The function might be simple and the use of a K combinator - whatever that is - might be elegant, but it hides away the intent of the macro/function. The macro expansion on the other hand is clear: evaluate the first form, do the rest and return the first thing. The function call hides away the do the rest step. I apologise for being a peasant. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: prog1
Robert Pfeiffer wrote: Hello, Is there a benefit in implementing this as a macro instead of a function? The function version would be very simple: (defn returning [returnval body] returnval) Well no, the forms are evaluated. It's usefull for side effects. user (def *bleh* (ref nil)) user (prog1 (dosync (ref-set *bleh* 3)) (println (str bleh is now @*bleh*))) bleh is now 3 3 A function would work : (defn progz [return-value do-also-fn] (do-also-fn) return-value) user (progz (+ 1 3) (fn [] (prn hello) (prn i'm evaluated))) hello i'm evaluated 4 But it's not as terse. Sacha --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Print compiled Clojure svn revision?
If marking SVN revisions and/or release versions is something we still want and want automated, it now looks like using the build tool is the only way to go. The example I sent earlier to the list includes the creation of a versioninfo file from the build script which is then read and stored in a version var in boot.clj. The only problem is that the build script now depends on the svnversion command being available and a SVN repository being used for building. For tarball releases of the source, the versioninfo file can be generated for the release and the build script modified to use the existing file if svnversion isn't working. As for supporting git and other SCMs used to mirror the SVN repos, the build script can be made to use the tools available in any of the other SCMs to identify the SVN revision and generate the versioninfo file. Or have we decided this isn't worth it? -Matt On Nov 7, 2008, at 2:41 PM, Mike Hinchey wrote: Haven't we been through this before? http://groups.google.com/group/clojure/browse_thread/thread/1ae7eae292765d40/f49c4ccdaca67a23 --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
Hi, Am 08.11.2008 um 17:39 schrieb Meikel Brandmeyer: (defn returning [returnval body] returnval) And another question, which a I got when I read the mail of Phlex: Is the order of evaluation of function arguments guaranteed to be from the left to the right? Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: prog1
Hi, Am 08.11.2008 um 17:58 schrieb Randall R Schulz: Peasant? Or did you mean pedant? In german there is the word Banause which translates according the dictionary to peasant. It means something like the following: Artist: Oh! Look this beautiful picture! It's art! Banause: It's just a blob of blue color. Sincerely Meikel smime.p7s Description: S/MIME cryptographic signature
Re: prog1
On Saturday 08 November 2008 08:39, Meikel Brandmeyer wrote: Hi, Am 08.11.2008 um 17:10 schrieb Robert Pfeiffer: Is there a benefit in implementing this as a macro instead of a function? The function version would be very simple: (defn returning [returnval body] returnval) Although I'm a strong proponent of using macros only where they are really needed, I would make an exception here. The function might be simple and the use of a K combinator - whatever that is - might be elegant, but it hides away the intent of the macro/function. The macro expansion on the other hand is clear: evaluate the first form, do the rest and return the first thing. The function call hides away the do the rest step. I apologise for being a peasant. Peasant? Or did you mean pedant? Sincerely Meikel RRS --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: doseq, dotimes loop/recur
Hi, On Sat, Nov 8, 2008 at 11:20 AM, verec [EMAIL PROTECTED] wrote: More of an inquiry into the fp mindset as opposed to the procedural one than anything else ... If I got this right, there are two forms of iterations: internal and external. `map' is an internal iterator, `doseq' is an external iterator. I see where you're going there, but I wouldn't put too fine a point on the distinction between internal and external. Really they're just different syntax for expressing the same thing. The intention behind the do forms isn't about externality but evaluation strategy. As you know, sequences in Clojure are lazy. The do forms force evaluation of a sequence's elements to be done immediately, rather than lazily as needed. A common reason you'd want to do that is because your do-expression has side-effects (I/O) and you want the effects to happen now rather than spread out across a set of future time points (or possibly not at all, if the sequence is never evaluated to its end). Ignoring laziness for a moment, all of these iteration constructs can be expressed in terms of loop/recur, since any iteration form can be expressed in terms of recursion. They can also be built up from reduce, which is a form called a fold in other functional languages, and is the internal equivalent of loop/recur, to borrow your terminology. Using (doall) in conjunction with either of these would let you express the non-lazy do forms. The benefit of map, reduce, filter isn't that they are inherently different from loop/recur, but that they concisely express a notion of transforming one sequence into another using a transformation function. If the expression you're trying to build up naturally fits that pattern, then map, reduce, filter are a good fit. (Note, reduce is more general than map/filter, in that it can transform a sequence into something other than another sequence.) Since reduce is the internal equivalent to loop/recur, you might consider writing some expressions in both styles until the equivalence makes sense. For example, here are two simple functions described using loop and reduce. (defn add-up [numbers] (loop [nums numbers accumulator 0] (if (nil? nums) accumulator (recur (rest nums) (+ (first nums) accumulator) (defn add-up-reducing [numbers] (reduce + 0 numbers)) (defn sum-and-product [numbers] (loop [nums numbers sum 0 product 1] (if (nil? nums) [sum product] (recur (rest nums) (+ (first nums) sum) (* (first nums) product) (defn sum-and-product-reducing [numbers] (reduce (fn [[sum prod] frst] [(+ sum frst) (* prod frst)]) [0 1] numbers)) In short, if you can figure out how to write your expression using reduce rather than a loop, it can lead to more compact code. But more complex reduce expressions can be hard to follow, and loop will make for better readability. Hope this helps, Graham --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
On 8 Nov., 17:47, Phlex [EMAIL PROTECTED] wrote: Robert Pfeiffer wrote: Hello, Is there a benefit in implementing this as a macro instead of a function? The function version would be very simple: (defn returning [returnval body] returnval) Well no, the forms are evaluated. It's usefull for side effects. In what way would the forms *not* get evaluated when using Roberts function returning? user (def *bleh* (ref nil)) user (prog1 (dosync (ref-set *bleh* 3)) (println (str bleh is now @*bleh*))) bleh is now 3 3 user (def *bleh* (ref nil)) #=(var user/*bleh*) user (returning (dosync (ref-set *bleh* 3)) (println (str bleh is now @*bleh*))) bleh is now 3 3 A function would work : (defn progz [return-value do-also-fn] (do-also-fn) return-value) Your function only takes two arguments. Roberts took an arbitrary number of them. user (progz (+ 1 3) (fn [] (prn hello) (prn i'm evaluated))) hello i'm evaluated 4 But it's not as terse. But this is: user (returning (+ 1 3) (prn Hello) (prn I'm evaluated)) Hello I'm evaluated 4 Macros are much less often needed in a functional language which also comes with syntactic suger for (λ [args] ...) in form of #(...). --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
On 8 Nov., 18:32, Meikel Brandmeyer [EMAIL PROTECTED] wrote: Hi, Am 08.11.2008 um 17:58 schrieb Randall R Schulz: Peasant? Or did you mean pedant? In german there is the word Banause which translates according the dictionary to peasant. It means something like the following: The german word “Banause” is “Philistine” in english. What you said is, that you are sorry for being a Bauer :-) --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
On 8 Nov., 18:00, Meikel Brandmeyer [EMAIL PROTECTED] wrote: Hi, Am 08.11.2008 um 17:39 schrieb Meikel Brandmeyer: (defn returning [returnval body] returnval) And another question, which a I got when I read the mail of Phlex: Is the order of evaluation of function arguments guaranteed to be from the left to the right? I am very sure that Clojure guarantees this. In a pure functional language (like Haskell) this has not to be the case. As there are no side effects it absolutely does not matter at all in what order anything is evaluated. But Clojure is a functional and imperative language, and for running Java we need this guarantee. At a first glance I see no need for implementing that in the core language, and also not as a macro. This can easily be implemented as a function, as Robert demonstrated. I also don’t see how the function hides the “do the rest” part. Maybe returning is not the best name, but how would we benefit of a macro, which is more complicated and also is not first class and can’t be passed around? --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
On Saturday 08 November 2008 10:44, André Thieme wrote: On 8 Nov., 18:32, Meikel Brandmeyer [EMAIL PROTECTED] wrote: Hi, Am 08.11.2008 um 17:58 schrieb Randall R Schulz: Peasant? Or did you mean pedant? In german there is the word Banause which translates according the dictionary to peasant. It means something like the following: The german word “Banause” is “Philistine” in english. What you said is, that you are sorry for being a Bauer :-) I tried to keep this off the list, but I have recent ancestors whose surname is Bauer, so tread carefully, please... RRS --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
André Thieme wrote: On 8 Nov., 17:47, Phlex [EMAIL PROTECTED] wrote: Robert Pfeiffer wrote: Is there a benefit in implementing this as a macro instead of a function? The function version would be very simple: (defn returning [returnval body] returnval) Well no, the forms are evaluated. It's usefull for side effects. In what way would the forms *not* get evaluated when using Roberts function returning? Ah I guess you're right, either way it would be nice to have the functionality available in clojure. There must be some reason for CL to have it as a macro (call-argument-limit perhaps ?) Also there's not function call overhead with a macro. Though that should not be a concern. Macros are much less often needed in a functional language which also comes with syntactic suger for (λ [args] ...) in form of #(...). ahwell that's a debate... sure you can do much with lambdas. Some would say that's a leaking abstraction. I often implement some functionality as a higher order function, then wrap it around in a macro. Like a do-trie macro around a map-trie function. it's just prettier ! Sacha --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: prog1
On Sat, Nov 8, 2008 at 8:48 PM, André Thieme [EMAIL PROTECTED] wrote: On 8 Nov., 18:00, Meikel Brandmeyer [EMAIL PROTECTED] wrote: Hi, Am 08.11.2008 um 17:39 schrieb Meikel Brandmeyer: (defn returning [returnval body] returnval) [...] I also don't see how the function hides the do the rest part. [...] I agree that it's not obvious, but that's only because body makes no difference whatsoever, unless it causes side effects. -- Michael Wood [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: doseq, dotimes loop/recur
Hmmm. Thank you for the post. Questions of laziness apart, I know that recursion has been proven to be equivalent to iterations (expect to weed out interview candidates, as per Steve Yege's remarks :-) But then why would we want any of `doseq', `dotimes' or `doall', and if we do, is that set complete, and with respect to what design principle? For example, CL provides `do-symbols', `do-all-symbols' or `with- package-iterator' as external iterators. Clojure decided that anything that could be expressed as a `seq' could be iterated over using `doseq', so I can express the equivalent of CL's (do-symbols ...) using clojure (doseq [n all-ns] ) To rephrase the question differently, what could exist that is not a clojure `seq' that we would want to iterate over? Clojure already answers this (partially?) by providing (dotimes ...) (as CL does) to iterate over a zero based consecutive and finite sequence of numbers. Though the same (dotimes ...) could be _used_ to iterate over any finite range) What are the things that one could iterate over, for which clojure does not, currently, provide special cases à la `doseq' or 'dotimes' ? I can't think of any, but that's just my poor lack of imagination :-) Many thanks. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
nth and take-nth argument order
Is there any particular reason for the reversal of the order of arguments between nth and take-nth? I would have expected something like: clojure/nth ([n coll]) clojure/take-nth ([index coll]) ([index coll not-found]) or else: clojure/nth ([coll n]) clojure/take-nth ([coll index]) ([coll index not-found]) -- Michael Wood [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: nth and take-nth argument order
On Nov 8, 2:44 pm, Michael Wood [EMAIL PROTECTED] wrote: Is there any particular reason for the reversal of the order of arguments between nth and take-nth? Short answer - take-nth is more like take. Longer answer: http://groups.google.com/group/clojure/browse_frm/thread/8b2c8dc96b39ddd7/a8866d34b601ff43 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: doseq, dotimes loop/recur
HI, On Sat, Nov 8, 2008 at 2:39 PM, verec [EMAIL PROTECTED] wrote: But then why would we want any of `doseq', `dotimes' or `doall', and if we do, is that set complete, and with respect to what design principle? Well, given loop/recur as a fundamental iteration form, and doall as a mechanism for forcing evaluation of the spine of a sequence, I'd say that loop/recur + doall could be used to build all the other forms. (I realize I mis-spoke in my earlier message by saying that loop/recur and reduce could be equated. That's not true, since loop/recur allows for short-circuiting, and does not require a sequence as one of its arguments. So loop/recur is more general than reduce. Sorry about that.) I think we want a variety of forms for the same reason Common Lispers want DOTIMES, LOOP, etc. -- pragmatism. For example, CL provides `do-symbols', `do-all-symbols' or `with- package-iterator' as external iterators. Clojure decided that anything that could be expressed as a `seq' could be iterated over using `doseq', so I can express the equivalent of CL's (do-symbols ...) using clojure (doseq [n all-ns] ) Yes, exactly -- abstract sequences are a super idea, and make a lot of special-case procedures unnecessary. To rephrase the question differently, what could exist that is not a clojure `seq' that we would want to iterate over? Clojure already answers this (partially?) by providing (dotimes ...) (as CL does) to iterate over a zero based consecutive and finite sequence of numbers. Though the same (dotimes ...) could be _used_ to iterate over any finite range) I'd argue that dotimes iterates, but doesn't iterate *over* anything -- there's no Clojure sequence involved. What are the things that one could iterate over, for which clojure does not, currently, provide special cases à la `doseq' or 'dotimes' ? Not special cases -- dotimes doesn't traverse a sequence, and doseq can be thought of as a map that is evaluated immediately, for side-effects, and which discards the result of the map. (Like for-each in Scheme, compared with map in Scheme -- the former is for side-effects, the latter to produce a transformed list.) Clojure's concept of the 'seq' as the object of traversal, rather than a literal type (list, vector, etc.) is its fundamental genius, IMHO. Best, Graham --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: nth and take-nth argument order
On Sat, Nov 8, 2008 at 10:08 PM, Rich Hickey [EMAIL PROTECTED] wrote: On Nov 8, 2:44 pm, Michael Wood [EMAIL PROTECTED] wrote: Is there any particular reason for the reversal of the order of arguments between nth and take-nth? Short answer - take-nth is more like take. Longer answer: http://groups.google.com/group/clojure/browse_frm/thread/8b2c8dc96b39ddd7/a8866d34b601ff43 Ah, thanks. -- Michael Wood [EMAIL PROTECTED] --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: doseq, dotimes loop/recur
On Sat, Nov 8, 2008 at 4:23 PM, verec [EMAIL PROTECTED] wrote: Everything that can be interpreted as a `seq', clojure's `doseq' takes care of it. What I am after are the special cases for things one could somehow enumerate but are not a `seq'. A number range is one such thing, and clojure provides 'dotimes' to handle this case. What could be the XYZ that are neither a `seq' nor a number range, for which we would want a `doXYZ' ? In other words, is the set `doseq', `dotimes' and `doall' complete, and if not, what is missing? Of course, dotimes could be implemented in terms of doseq, e.g. (dotimes i n ...) (doseq i (take n (iterate inc 0)) ...) so really there aren't any special cases in Clojure. I can't think of anything that is sequence-like but couldn't be represented as a seq, so I think the bases are covered. :-) Best, Graham --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
a macro question, this time completely specified :-)
The defrunonce macro below works, creating a function that runs only once and tracking its run status in metadata. Now, how do I write it without using eval? (defn runonce Create a function that will only run once, given a function. Returns a vector containing the function and the reference that tracks whether the function has been run. [function] (let [has-run (ref false)] [(fn [ args] (or @has-run ; TODO: think through semantics for parallel target invocation (do (apply function args) (dosync (ref-set has-run true) has-run])) (defmacro defrunonce [sym doc forms] Defines a function with runonce semantics. Curren run status is kept in a reference under the :has-run metadata key. (let [[function has-run] (runonce (eval (concat (list 'fn []) forms)))] `(def ~(with-meta sym {:has-run has-run}) ~function))) --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: a macro question, this time completely specified :-)
On Sat, Nov 8, 2008 at 10:23 PM, Stuart Halloway [EMAIL PROTECTED] wrote: How about: (defn runonce Create a function that will only run its argument once. [function] (let [call-count (ref 0)] (fn [ args] (when (= 1 (dosync (alter call-count inc))) (apply function args) Or: (defn runonce Create a function that will only run its argument once. [function] (let [needed (java.util.concurrent.atomic.AtomicBoolean. true)] (fn [ args] (when (.getAndSet needed false) (apply function args) --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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: a macro question, this time completely specified :-)
On Nov 8, 2008, at 10:23 PM, Stuart Halloway wrote: How about: (defn runonce Create a function that will only run its argument once. [function] (let [call-count (ref 0)] (fn [ args] (when (= 1 (dosync (alter call-count inc))) (apply function args) The counter occurred to me too. I don't think it's necessary though. What's important is that one thread know that it was the one that cause the false to true transition. Regarding the value returned by dosync above, I'd believe it if someone told me that it could only return 1 to one thread, one time, guaranteed, but I've been wrong before in my reasoning about alter vs. commute regarding what's possible, so I'll have to give it more thought on correctness. Here's perhaps a more basic one shot building block: (defn once Returns a function that returns v the first time it's called and nil every time after that [v] (let [returned (ref false)] (fn [] (dosync (when-not (ensure returned) (ref-set returned true) v) --Steve --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: a macro question, this time completely specified :-)
How about: (defn runonce Create a function that will only run its argument once. [function] (let [call-count (ref 0)] (fn [ args] (when (= 1 (dosync (alter call-count inc))) (apply function args) On Nov 8, 2008, at 8:31 PM, Stuart Halloway wrote: The defrunonce macro below works, creating a function that runs only once and tracking its run status in metadata. Now, how do I write it without using eval? (defn runonce Create a function that will only run once, given a function. Returns a vector containing the function and the reference that tracks whether the function has been run. [function] (let [has-run (ref false)] [(fn [ args] (or @has-run ; TODO: think through semantics for parallel target invocation (do (apply function args) (dosync (ref-set has-run true) has-run])) Since the deref of has-run is outside a transaction, I don't see anything here that prevents two threads from running function if they're trying to do it at roughly the same time. I think the following version accomplishes the core task of running just once and could be adapted to return the has-run ref as well: (defn runonce Create a function that will only run its argument once. [function] (let [has-run (ref false)] (fn [ args] (when (dosync (ensure has-run) (when-not @has-run (ref-set has-run true))) (apply function args) I'd appreciate seeing corrections or simplifications of it. --Steve --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: a macro question, this time completely specified :-)
On Sat, Nov 8, 2008 at 8:31 PM, Stuart Halloway [EMAIL PROTECTED] wrote: (defmacro defrunonce [sym doc forms] Defines a function with runonce semantics. Curren run status is kept in a reference under the :has-run metadata key. (let [[function has-run] (runonce (eval (concat (list 'fn []) forms)))] `(def ~(with-meta sym {:has-run has-run}) ~function))) (defmacro defrunonce [sym doc forms] Defines a function with runonce semantics. Curren run status is kept in a reference under the :has-run metadata key. (let [has-run (gensym)] `(let [[function# ~has-run] (runonce (fn [] [EMAIL PROTECTED]))] (def ~(with-meta sym {:has-run has-run}) function# --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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: a macro question, this time completely specified :-)
On Nov 8, 2008, at 8:31 PM, Stuart Halloway wrote: The defrunonce macro below works, creating a function that runs only once and tracking its run status in metadata. Now, how do I write it without using eval? (defn runonce Create a function that will only run once, given a function. Returns a vector containing the function and the reference that tracks whether the function has been run. [function] (let [has-run (ref false)] [(fn [ args] (or @has-run ; TODO: think through semantics for parallel target invocation (do (apply function args) (dosync (ref-set has-run true) has-run])) Since the deref of has-run is outside a transaction, I don't see anything here that prevents two threads from running function if they're trying to do it at roughly the same time. I think the following version accomplishes the core task of running just once and could be adapted to return the has-run ref as well: (defn runonce Create a function that will only run its argument once. [function] (let [has-run (ref false)] (fn [ args] (when (dosync (ensure has-run) (when-not @has-run (ref-set has-run true))) (apply function args) I'd appreciate seeing corrections or simplifications of it. --Steve --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: (string?) bug
A StringBuilder is not a Java String... neither is it a StringBuffer :))) user= (string? (.toString (java.lang.StringBuilder. hello))) true user= because: user= (.getClass (java.lang.StringBuilder. hello)) java.lang.StringBuilder and user= (.getClass (.toString (java.lang.StringBuilder. hello))) java.lang.String user= (.getClass ABCDE) java.lang.String Clojure uses Java String, not StringBuffer or StringBuilder as it's String representation. You can write your own predicate if you need one. Luc On Sat, 2008-11-08 at 23:07 -0700, Brian Doyle wrote: This seems like a bug returning false for StringBuilder. user= (string? (new java.lang.String hello)) true user= (string? (new java.lang.StringBuilder hello)) false --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---