Re: Why cannot last be fast on vector?
Warren Lynn wrn.l...@gmail.com writes: Although I have not yet looked at any of Clojure's internals yet, I suspect the change won't be too difficult (for the right person). So I hope/wish someone with enough knowledge, skills and influence will agree with me and advocate a review of the design (last may not be the only one with issues) and fix some of those things before things get too messy down the road. Err, I don't think this is an issue of design let alone something worthy of getting a bit weepy about Clojure failing to be worthy of use in your production system as implied by your previous posts. Here is a version of last for clojure.core that will use peek on vectors. (def ^{:arglists '([coll]) :doc Return the last item in coll. :added 1.0 :static true} last (fn ^:static last [s] (if (vector? s) (peek s) (if (next s) (recur (next s)) (first s) If the intent of specifying in linear time in the docstring was to guarantee the user that we would be looping over a sequence using first/next, then it should explicitely say so and not just imply it by mentioning linear time. Otherwise, I see the phrase as a warning, and not as a guarantee. David Nolen asked about drop-last and take-last and but-last. drop-last is defined as returning lazy sequences. A change to them that returned a vector with it's tail peeked off would be a change to the language. I am not so keen on that. take-last returns a seq, and it's not obvious after a whiskey just how to rewrite it to be more efficient for vectors and not just end up making it linear scaling on n for vectors. However, butlast is documented as returning a seq, so changing pop on a vector might have some performance advantage, and not change the outcomes of the function. Here is what that would look like. (def ^{:arglists '([coll]) :doc Return a seq of all but the last item in coll, in linear time :added 1.0 :static true} butlast (fn ^:static butlast [s] (if (and (not (empty? s)) (vector? s)) (pop s) (loop [ret [] s s] (if (next s) (recur (conj ret (first s)) (next s)) (seq ret)) These changes don't really bring any new entanglement between clojure.core and the clojure.lang java objects -- because the language defines explicitely how vector conj/peek. However, going thru clojure.core and optimizing it based on knowledge of implementation in clojure.lang would be complecting - thus punishable by exile to the bitcoin mines. -- Craig Brozefsky cr...@red-bean.com Premature reification is the root of all evil -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
Sam Ritchie sritchi...@gmail.com writes: Perhaps place them inside a protocol, where core supplies I don't think a protocol is needed to identify a performance characteristic, which as far as I can tell really is limited to vectors. The definition of vector? itself is sufficient. Also, consider that last is defined as part of the very base of core, before protocols get loaded, and even before defn is available. Using a protocol to optimize at that level is gonna get dirty dirty. See my reply to Warren my proposed change to core. Those defs can be dropped into clojurescript too, btw. -- Craig Brozefsky cr...@red-bean.com Premature reification is the root of all evil -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Would adef- macro for private varibales make sense?
For functions I have a defn macro to create public functions and a defn- macro to define private functions. For variables I have only def. Would it make sense to also have a def macro for public variables and a def- macro for private variables, also variables which can be only accessed from within the namespace? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Would adef- macro for private varibales make sense?
This topic has come up before. The conclusion from people of authority is that clojure.core is not the place for this macro, but may be appropriate for some other library. Thanks, Ambrose On Sat, Jun 30, 2012 at 7:49 PM, Goldritter marcus.goldritter.lind...@googlemail.com wrote: For functions I have a defn macro to create public functions and a defn- macro to define private functions. For variables I have only def. Would it make sense to also have a def macro for public variables and a def- macro for private variables, also variables which can be only accessed from within the namespace? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
Having separate peek and last, with documented performance characteristics, makes it straightforward to reason about how code is likely to perform, a point that Mark made earlier. It is a fundamental design principle of Clojure that, when given two approaches, A and B, make primitive the one that could be used to build the other. Clojure's peek and last might be useful to somebody building the last that Warren wants. Warren's last is *useless* for building the peek and last that Clojure already has. Not arguing against having Warren's last. Just saying that c.c/last ain't broken, and is simpler. Stu Even not a single action is taken because of this thread, I still would not consider the thread fruitless. It helped me (and maybe others) understand the issue better. My point was: you need a clear documentation on a coherent, consistent abstraction, and let the programmer to understand. Just clear documentation is not enough. You can document a very messy system in clear documentation (maybe the US tax code?). Here, we are having both peek and last, which is not coherent to me. consider the documentation on an alternative design: last: get the last element from an ordered collection. for queues and linked lists, it takes linear time. for vectors, it takes constant time. and get rid of peek (we already have first for linked list and queues, right?) Which one is cleaner? On Friday, June 29, 2012 3:27:57 PM UTC-4, Sean Corfield wrote: On Fri, Jun 29, 2012 at 7:51 AM, Warren Lynn wrn.l...@gmail.com wrote: 1. Put good documentations on the functions, and the programmer needs to have some idea what data structure is fast/slow for what use. At the risk of continuing what is quickly becoming a rather fruitless thread, I figured I'd quote the docstrings from last and peek: last: Return the last item in coll, in linear time peek: For a list or queue, same as first, for a vector, same as, but much more efficient than, last. If the collection is empty, returns nil. That seems like pretty good documentation to me. (last my-vector) is documented to be a linear operation. (peek my-vector) is documented to be much more efficient. last is not dependent on the type of its argument, peek is. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en Stuart Halloway Clojure/core http://clojure.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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Why cannot last be fast on vector?
On Friday, June 29, 2012, Mark Engelberg wrote: On Fri, Jun 29, 2012 at 4:50 PM, David Nolen dnolen.li...@gmail.comwrote: ISeq *is* an interface on Clojure JVM. But ideally it would be protocol as in ClojureScript. But then all ISeq implementing types must also implement this new protocol you are suggesting to get these basic *generic* sequence operations we enjoy today. I see, you're not saying it can't be done in Clojure, you're saying it wouldn't work on ClojureScript. It seems to me that's a limitation of either ClojureScript, or protocols, or both. My guess is that it's a limitation of ClojureScript, because my understanding is that in Clojure, every protocol generates a Java interface, so I can't think of any reason why you couldn't list that generated interface as a type in another protocol (although I haven't tried it). It is a host detail one can take advantage of in Clojure. But it is not a feature of protocols. In fact using protocols this way will fail. You have to go under the hood to the generated interface. And even then doesn't work for extend-typed things. As far as whether this is a problem for large software I don't share you concerns. ClojureScript is getting towards 7000 lines of standard library. Not problems yet. core.logic is approaching 40 protocols and 3000 lines of code. No problems encountered and none foreseen when the full functionality is ported to ClojureScript. Why does this seem to scale? Because Clojure's interfaces were already written in a protocol style. Inheritance doesn't matter much, and they only define 2-3 methods on average. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
As I mentioned before, the issue here is not just a fast last. The issue here is I find the design of Clojure wrong, or confusing. That really shakes my confidence in the whole system. I am also not talking about implementations, which is a separate issue that I don't know much yet According to the book Clojure Programming by Chas, one of the Clojure's principles is to build on abstractions and to separate abstractions from concrete types. Now I have a little deeper contact with Clojure and my impression is that is not the reality. On Saturday, June 30, 2012 3:47:58 AM UTC-4, Craig Brozefsky wrote: Warren Lynn wrn.l...@gmail.com writes: Although I have not yet looked at any of Clojure's internals yet, I suspect the change won't be too difficult (for the right person). So I hope/wish someone with enough knowledge, skills and influence will agree with me and advocate a review of the design (last may not be the only one with issues) and fix some of those things before things get too messy down the road. Err, I don't think this is an issue of design let alone something worthy of getting a bit weepy about Clojure failing to be worthy of use in your production system as implied by your previous posts. Here is a version of last for clojure.core that will use peek on vectors. (def ^{:arglists '([coll]) :doc Return the last item in coll. :added 1.0 :static true} last (fn ^:static last [s] (if (vector? s) (peek s) (if (next s) (recur (next s)) (first s) If the intent of specifying in linear time in the docstring was to guarantee the user that we would be looping over a sequence using first/next, then it should explicitely say so and not just imply it by mentioning linear time. Otherwise, I see the phrase as a warning, and not as a guarantee. David Nolen asked about drop-last and take-last and but-last. drop-last is defined as returning lazy sequences. A change to them that returned a vector with it's tail peeked off would be a change to the language. I am not so keen on that. take-last returns a seq, and it's not obvious after a whiskey just how to rewrite it to be more efficient for vectors and not just end up making it linear scaling on n for vectors. However, butlast is documented as returning a seq, so changing pop on a vector might have some performance advantage, and not change the outcomes of the function. Here is what that would look like. (def ^{:arglists '([coll]) :doc Return a seq of all but the last item in coll, in linear time :added 1.0 :static true} butlast (fn ^:static butlast [s] (if (and (not (empty? s)) (vector? s)) (pop s) (loop [ret [] s s] (if (next s) (recur (conj ret (first s)) (next s)) (seq ret)) These changes don't really bring any new entanglement between clojure.core and the clojure.lang java objects -- because the language defines explicitely how vector conj/peek. However, going thru clojure.core and optimizing it based on knowledge of implementation in clojure.lang would be complecting - thus punishable by exile to the bitcoin mines. -- Craig Brozefsky cr...@red-bean.com Premature reification is the root of all evil -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
core.incubator 0.1.1 released
Hi all, Version 0.1.1 of the core.incubator project has been released. It may take a couple of hours for the release to be synced up to Maven central. The project itself can be found here: https://github.com/clojure/core.incubator The only change in this version compared to 0.1.0 is the addition of the `` string interpolation macro (originally described here: http://cemerick.com/2009/12/04/string-interpolation-in-clojure/). Cheers, - Chas -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Would adef- macro for private varibales make sense?
It's better to use ^:private metadata on the symbol naming the var, since there is also defmacro, defmulti, etc, which not have hyphened versions too. суббота, 30 июня 2012 г., 17:49:36 UTC+6 пользователь Goldritter написал: For functions I have a defn macro to create public functions and a defn- macro to define private functions. For variables I have only def. Would it make sense to also have a def macro for public variables and a def- macro for private variables, also variables which can be only accessed from within the namespace? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
On Saturday, June 30, 2012 9:51:56 AM UTC-4, stuart@gmail.com wrote: Having separate peek and last, with documented performance characteristics, makes it straightforward to reason about how code is likely to perform, a point that Mark made earlier. As I said before, I strongly feel mixing abstraction and speed path is the wrong direction to take. Let me elaborate a little bit more: 1. What's the purpose of high level language and dynamic typing? To abstract so we can be more efficient in writing code (Note: code itself my not run fast) and the code is easier to read and maintain. Statically typed language has less abstraction power (although it still tries hard with things like C++ templates), but faster. Dynamic language has higher abstraction power but slower performance. So it is wrong to me to throw away the strength of abstraction of a dynamic language in pursuit of performance. Performance is of course important, but not at the expense of broken abstraction. Maybe that can be done on rare cases that may have a huge impact of performance on the whole system, but it seems wrong to do it as a design choice. 2. The argument that if a function takes its pre-designated speed characteristics, even when its possible to be faster on a particular type, will encourage better code performance or performance analysis, is a very convoluted one. If you say: by making last slow on vectors, it will force people to use peek, then why not make it even slower on vectors? (how about putting a sleep there for vectors?). If you say no, no, sometimes people may still use last on vectors and we still want the best performance in that case, then why not make it as fast as we can? 3. Maybe we don't have one now, but we will have a profiler in the future if the language will be put into serious use. With a profiler you can see where the performance bottleneck is, and a programmer can reason Ah, this part is slow because I used last on a large list, give we already documented that last will take linear time on lists. So he can choose the right data type instead of switching functions. If the abstraction is done right, switching a data type should not be difficult. It is a fundamental design principle of Clojure that, when given two approaches, A and B, make primitive the one that could be used to build the other. Clojure's peek and last might be useful to somebody building the last that Warren wants. Warren's last is *useless* for building the peek and last that Clojure already has. Not arguing against having Warren's last. Just saying that c.c/last ain't broken, and is simpler. I don't understand the argument that because a higher level function cannot be used to build a lower level function, so it is not worth working on or fixing. We can build Clojure with Java but Clojure cannot be used to build Java, so we don't need to work on Clojure? Keeping both type specific low level functions and abstraction level function is less of a problem to me, but I would avoid it if possible. Stu -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Using core.logic at a lower level
Michael Fogus writes: It's not a total solution to all of your requirements, but core.unify is meant for use as a library. See https://github.com/fogus/unifycle/blob/master/src/fogus/unifycle.clj for examples. Looks interesting, but I do need logic variables as distinct entities that can be created and then submitted to constraints by unification. In fact, what I want to do is use logic variables for dataflow programming. The main point of building on top of core.logic would be to avoid rewriting a unification engine that handles logic variables also inside (potentially nested) data structures. David Nolen writes: I don't forsee the protocols or functions around logic vars unification changing. I'm actually quite happy with how flexible extensible it's turned out to be. cKanren is just around the corner and unification has been left alone. That sounds promising indeed. Konrad. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
Warren Lynn wrn.l...@gmail.com writes: As I mentioned before, the issue here is not just a fast last. The issue here is I find the design of Clojure wrong, or confusing. That really shakes my confidence in the whole system. To say stuff like this, then be demure about digging into the code and understanding how things work, followed by asking for others to be do the coding and be and advocate for your rather vague feeling of unease, strikes me as passive-aggressive attention seeking. To do such while top posting, well, it's just too much for me. 8^) -- Craig Brozefsky cr...@red-bean.com Premature reification is the root of all evil -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
Craig: If the dominant community attitude is before you know everything about Clojure, you have no right to comment, then that itself will be the reason not to use Clojure. But I think that is just you, not the community. Although I am glad some people paid attention to this post, I have far more important things to do than seeking some attention from strangers. I hope I stimulated some thinking here. I am a lisp lover, and I feel Clojure has a good potential of being a great and practical language, but it has its broken parts too and I wish they get fixed, so I will have a better experience using it. That is my goal (obvious I hope). On Saturday, June 30, 2012 12:17:39 PM UTC-4, Craig Brozefsky wrote: Warren Lynn wrn.l...@gmail.com writes: As I mentioned before, the issue here is not just a fast last. The issue here is I find the design of Clojure wrong, or confusing. That really shakes my confidence in the whole system. To say stuff like this, then be demure about digging into the code and understanding how things work, followed by asking for others to be do the coding and be and advocate for your rather vague feeling of unease, strikes me as passive-aggressive attention seeking. To do such while top posting, well, it's just too much for me. 8^) -- Craig Brozefsky cr...@red-bean.com Premature reification is the root of all evil -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
Warren, I think the issue is this: You claim there is sg. broken in clojure while admitting that you know little about how the design decision was made. People that know clojure's implementation and the history of design decisions inside-out offered advice why they think it is not broken, they took time to explain the rationale for decision and even offerred advice how to fix it for yourself should you insist on your view of the matter. It seems to me you a) need to reread these arguments to perhaps get a better grasp b) have chosen to ignore them. While you have right to do either of them, if it's b) not even the clojure gods can really help you unless you actually spend some time with the internals of clojure. ;-). Las 2012/6/30 Warren Lynn wrn.l...@gmail.com Craig: If the dominant community attitude is before you know everything about Clojure, you have no right to comment, then that itself will be the reason not to use Clojure. But I think that is just you, not the community. Although I am glad some people paid attention to this post, I have far more important things to do than seeking some attention from strangers. I hope I stimulated some thinking here. I am a lisp lover, and I feel Clojure has a good potential of being a great and practical language, but it has its broken parts too and I wish they get fixed, so I will have a better experience using it. That is my goal (obvious I hope). On Saturday, June 30, 2012 12:17:39 PM UTC-4, Craig Brozefsky wrote: Warren Lynn wrn.l...@gmail.com writes: As I mentioned before, the issue here is not just a fast last. The issue here is I find the design of Clojure wrong, or confusing. That really shakes my confidence in the whole system. To say stuff like this, then be demure about digging into the code and understanding how things work, followed by asking for others to be do the coding and be and advocate for your rather vague feeling of unease, strikes me as passive-aggressive attention seeking. To do such while top posting, well, it's just too much for me. 8^) -- Craig Brozefsky cr...@red-bean.com Premature reification is the root of all evil -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- László Török -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
On Saturday, June 30, 2012 1:03:04 PM UTC-4, Las wrote: Warren, I think the issue is this: You claim there is sg. broken in clojure while admitting that you know little about how the design decision was made. People that know clojure's implementation and the history of design decisions inside-out offered advice why they think it is not broken, they took time to explain the rationale for decision and even offerred advice how to fix it for yourself should you insist on your view of the matter. It seems to me you a) need to reread these arguments to perhaps get a better grasp b) have chosen to ignore them. While you have right to do either of them, if it's b) not even the clojure gods can really help you unless you actually spend some time with the internals of clojure. ;-). Las First, this will be my last post on this thread, so I will be absolved from attention seeking. But really, as you have pointed out, things are getting in a kind of circle and we may just need to sit back and think for a while. I think some people agree with me something is broken here (puzzler, for example. Please correct me is I am wrong as I don't want to hijack other people's opinion). For the other people who don't agree with me, I am not really ignoring their argument (I tried hard to reply to each of them), it is just, I am not really convinced. No I don't know the language inside-out, and I don't know much about the implementation. But I was trying to keep my discussion on the high-level abstraction. If somebody told me Warren, I agree with you that the abstractions and design principles need some fixing, but man it is very hard to do now, take my word for it, even nothing changed I will feel better using Clojure because at least people admit there is a problem and there is a chance it will get fixed in the future (on on another host language). So far I have not get that kind of feedback. We all choose what we think is right for us, so there is no imposing anything on anybody. I appreciate the fact at least there is the language Clojure we can talk about. Thanks you all for the participation. And I will much more comfortalbe Of course in the end -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
On Sat, Jun 30, 2012 at 7:09 AM, Warren Lynn wrn.l...@gmail.com wrote: As I mentioned before, the issue here is not just a fast last. The issue here is I find the design of Clojure wrong, or confusing. That really shakes my confidence in the whole system. Some of Clojure's design decisions take a while to really internalize. Several folks here have explained them but you're still not satisfied. I don't think there's much more they can do at this point. According to the book Clojure Programming by Chas, one of the Clojure's principles is to build on abstractions and to separate abstractions from concrete types. Now I have a little deeper contact with Clojure and my impression is that is not the reality. But it is the abstractions specifically that lead to the situation you are in, with last operating the way it does, as several folks have explained. Some have suggested you read through and understand the implementation of Clojure. That may help you understand the abstractions better (it may not). But, as has been stated (repeatedly) in this thread, Clojure is this way for a (good) reason. I actually think Stu's post was one of the clearest explanations... -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Would adef- macro for private varibales make sense?
On Sat, Jun 30, 2012 at 7:30 AM, Vinzent ru.vinz...@gmail.com wrote: It's better to use ^:private metadata on the symbol naming the var, since there is also defmacro, defmulti, etc, which not have hyphened versions too. It seemed to be consensus that defn- was probably not a good idea but was too common to remove... -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: verify that a fn throws an exception via testing?
I am away in holidays and missed your response Brian...Thanks a lot for taking the time to reply and of course thanks for midje! I will consult the entire midje wiki once I go back to an actual office!!! Jim On Mon, Jun 25, 2012 at 11:05 PM, Brian Marick mar...@exampler.com wrote: On Jun 25, 2012, at 6:21 AM, Jim - FooBar(); wrote: (fact (try (fn-that-throws-exc bad-arg) (catch Exception e :works)) = :works) (fact (fn-that-throws-exc bad-arg) = (throws Exception)) You can also check the message, run a predicate over the exception, etc. https://github.com/marick/Midje/wiki/Checkers Ah, ok. Midje seems to support that, too. See https://github.com/marick/Midje/wiki/Prerequisites-that-throw-exceptions This is actually for sort of the opposite purpose. You're writing a function that needs to be able to handle an exception. That exception is hard to generate. So this is a way to artificially create and throw one. - Brian Marick, Artisanal Labrador Now working at http://path11.com Contract programming in Ruby and Clojure Occasional consulting on Agile -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
ANN Monger 1.1.0-beta1
Monger [1] is a Clojure MongoDB driver for a more civilized age: friendly, flexible, well documented and with batteries included. 1.1.0-beta1 is released to clojars [2]. This release includes a bunch of small improvements: * An alternative insert function many people have been suggesting * Clojure reader extensions for MongoDB-specific data types and Joda Time types (just like monger.joda-time does for clojure.data.json protocols) * An alternative Ring session store that stores session data in a way that's not interoperable with non-Clojure applications but works well with namespaced keywords that Friend [3] relies on The alternative insert function (monger.collection/insert-and-return) that returns the exact inserted document (with _id generated if needed) and not the write result. More details and the rationale can be found in the change log: https://github.com/michaelklishin/monger/blob/master/ChangeLog.md Otherwise this release is completely backwards compatible with 1.0.0. 1. http://clojuremongodb.info 2. https://clojars.org/com.novemberain/monger 3. https://github.com/cemerick/friend/ MK mich...@defprotocol.org signature.asc Description: Message signed with OpenPGP using GPGMail
[ANN] clj-cc lib
Available here: https://github.com/wrn/clj-cc This is a very simple lib (for now only three functions) that I created in response to people's suggestions in the following two threads: 1. Why cannot last be fast on vector?https://groups.google.com/forum/?fromgroups#%21topic/clojure/apkNXk08Xes 2. General subsequence functionhttps://groups.google.com/forum/?fromgroups#%21topic/clojure/q4iN7OLfjkU The purpose of this lib is to collect functions I think should be added to or replace existing ones in clojure.core, and to gather community support for that. Please check it out if you are interested. Thank you. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Clojure in OSGi and *use-context-classloader*
I am using clojure in apache karaf which has Thread context class loader set to karaf jars. I changed use-context-classloader to false in RT.java: final static public Var USE_CONTEXT_CLASSLOADER = Var.intern(CLOJURE_NS, Symbol.intern(*use-context-classloader*), F).setDynamic(); For some reason booleanCast(USE_CONTEXT_CLASSLOADER.deref()) doesn't always return false and RT still managed to create DynamicClassloader with thread context classloader as parent. Of course, it wasn't able to find any clojure classes. To make it work I commented out this line in baseLoader() method. else if (booleanCast(USE_CONTEXT_CLASSLOADER.deref())) { return Thread.currentThread().getContextClassLoader(); } Why booleanCast(USE_CONTEXT_CLASSLOADER.deref()) doesn't always return 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
class loading on startup
When debugging class loading issues I noticed that clojure tries to load many non-existing classes. For example this__5587__auto__, gf__x__8266 , f__5717__auto__. It happens on startup, in static init block of RT.java. Are those type hints generated by some macro ? protected Class? findClass(String name) throws ClassNotFoundException{ ReferenceClass cr = classCache.get(name); if(cr != null) { Class c = cr.get(); if(c != null) return c; else classCache.remove(name, cr); } try { return super.findClass(name); } catch (ClassNotFoundException e) { log.log(Level.SEVERE,FAILED to load + name); throw e; } } -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: ANN Monger 1.1.0-beta1
Michael, On Sat, Jun 30, 2012 at 9:11 PM, Michael Klishin michael.s.klis...@gmail.com wrote: * An alternative Ring session store that stores session data in a way that's not interoperable with non-Clojure applications but works well with namespaced keywords that Friend [3] relies on Excellent news. I look forward to using Monger friend together. cheers, Bruce -- @otfrom | CTO co-founder @MastodonC | mastodonc.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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Why cannot last be fast on vector?
On Sat, Jun 30, 2012 at 10:24 AM, Warren Lynn wrn.l...@gmail.com wrote: I think some people agree with me something is broken here (puzzler, for example. Please correct me is I am wrong as I don't want to hijack other people's opinion). One really nice thing about the Clojure community is that from the very beginning, Rich instilled a value that we should generally avoid talking in terms of a sky is falling mentality, and avoid using terms like broken. Generally speaking, the community has been trained to avoid engaging with people who make such exaggerated claims. This has a couple of beneficial effects: first, it helps keep criticisms grounded and constructive, second, it tends to limit the destructive potential of people who are just trolling. As a result of this community ethic, you'll find that if you keep calling Clojure broken, people will just tune you out. So no, I don't agree that last is broken. I claimed that last *could* be made polymorphic, and that if, it were up to me, I *would* make it polymorphic because I think there's little downside and it's generally better to make functions behave in an intuitive way; I believe that the name last implies fast access for data structures which offer fast access to the last element. However, I, like most of the others here, don't regard this as a big deal. The first time I read through the docs, I noted that last wasn't a particularly useful function because of its linear time bound. So I just don't use it. If I need fast access to the last element, I use a vector, and I use the peek function. It's not the way I would design things, but it's not a big deal, either. There are a number of aspects of Clojure I feel that way about, and it doesn't stop me from wanting to use it. Now I *do* find this discussion interesting, particularly because of things that David has said about protocols and ClojureScript, and the limitations that this may place on design. Ever since protocols were introduced, I have been very intrigued to see how they would play out in practice. I would like to discuss this issue further, but I will start a new thread to do so... -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
idempotency
In its optimization, does the Clojure compiler ever assume idempotency? That is, does it ever look at a function application `(f x y z)` and say to itself I may freely substitute the result of the first application of `f` to those particular arguments for any later call? I could imagine it doing that for built-ins (or just primitives?), but not for user-defined functions (given the existence of atoms, etc.) I can also imagine it not bothering for any calls. - Brian Marick, Artisanal Labrador Contract programming in Ruby and Clojure Occasional consulting on Agile -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Protocol as an abstract data type
This is a continuation of issues raised in the thread about making the core last function behave in a polymorphic manner. The separation of interfaces from implementation in Java serves several purposes, but one thing it does is it allows the creation of abstract data types, i.e., a type that is defined in terms of what it can do, rather than what it is comprised of or how it is implemented. Right now, in Clojure, ISeq is an interface, and by extension, it is an abstract type. One benefit this has is that we can polymorphically dispatch, via a protocol, for example, on whether something is an ISeq. We can easily create a function that applies to anything to which you can first and rest, and at the same time, we can leave the function open to extension by other types. However, once ISeq is made into a protocol (which has already been done in ClojureScript and may conceivably be done in the future in Clojure), there is a problem. No longer can you dispatch via protocols on whether something is an ISeq. In other words, by using a protocol to define ISeq. we have lost its capabilities to express an abstract data type. Protocols provide a way to polymorphically dispatch to various concrete data types but appear to lose the ability to dispatch based on the abstract data type, i.e., dispatching on what the object can *do*. A hypothetical polymorphic last function, proposed in that previous thread, is a great example of why one would want to do this. A naive implementation of a polymorphic last could take the form (cond (vector? s) ... (seq? s) ...), but this is a closed implementation. If we want to keep the implementation open for extension, you could use something like the protocol-based code I wrote there, but it absolutely relies on these abstract data types being represented as Java interfaces rather than other protocols. David says that in 10,000 lines of code, there hasn't yet been something that required protocols to dispatch on other protocols, but in nearly the same breath he says that a polymorphic last function is impractical because of this limitation. The difficulty, he notes, is that a hypothetical ILast protocol can't be made to automatically work for all implementers of ISeq. Every single person who ever wanted to implement ISeq would also have to implement ILast. I would argue that as soon as you're ruling out ideas such as a polymorphic last function specifically because it would make it too difficult to maintain in a protocol-based system, that is clear evidence that indeed, we *are* running into a real limitation of protocols. So, I would like to better understand this limitation, and brainstorm with everyone about workarounds. I have some thoughts and ideas about this, but I want to better understand the ClojureScript architecture first. David, could you walk me through the implementation of nth, which is a very similar kind of function? I was able to find the part of the code on Github where you define an IIndexed protocol which provides a protocol for nth. However, I was unable to find the place in the code where you implement nth in linear time for all those who implement ISeq and faster for random-access collections. Can you point me to the relevant source code? Is nth open to extension to other abstract data types? Is nth guaranteed to work and gain the default implementation for new data types that implement ISeq? Do coders need to remember to implement IIndexed any time ISeq is implemented, and if so, how is that documented? Thanks! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: idempotency
You should then use memoize explicitly then. Of course, avoid this if you have side effects in the function. Luc In its optimization, does the Clojure compiler ever assume idempotency? That is, does it ever look at a function application `(f x y z)` and say to itself I may freely substitute the result of the first application of `f` to those particular arguments for any later call? I could imagine it doing that for built-ins (or just primitives?), but not for user-defined functions (given the existence of atoms, etc.) I can also imagine it not bothering for any calls. - Brian Marick, Artisanal Labrador Contract programming in Ruby and Clojure Occasional consulting on Agile -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Protocol as an abstract data type
Look at the implementation of nth. Or how polymorphic unification works in ClojureScript core.logic for ISequential. I misspoke a bit, should have clearer that I simply meant that ILast (probably something else entirely) needs to be carefully considered since the logic needs too be moved to the actual fn or into a protocol default case in order to cover ISeq (which isn't a good idea anyway - IBoundedSeq or some such makes more sense to me). On Saturday, June 30, 2012, Mark Engelberg wrote: This is a continuation of issues raised in the thread about making the core last function behave in a polymorphic manner. The separation of interfaces from implementation in Java serves several purposes, but one thing it does is it allows the creation of abstract data types, i.e., a type that is defined in terms of what it can do, rather than what it is comprised of or how it is implemented. Right now, in Clojure, ISeq is an interface, and by extension, it is an abstract type. One benefit this has is that we can polymorphically dispatch, via a protocol, for example, on whether something is an ISeq. We can easily create a function that applies to anything to which you can first and rest, and at the same time, we can leave the function open to extension by other types. However, once ISeq is made into a protocol (which has already been done in ClojureScript and may conceivably be done in the future in Clojure), there is a problem. No longer can you dispatch via protocols on whether something is an ISeq. In other words, by using a protocol to define ISeq. we have lost its capabilities to express an abstract data type. Protocols provide a way to polymorphically dispatch to various concrete data types but appear to lose the ability to dispatch based on the abstract data type, i.e., dispatching on what the object can *do*. A hypothetical polymorphic last function, proposed in that previous thread, is a great example of why one would want to do this. A naive implementation of a polymorphic last could take the form (cond (vector? s) ... (seq? s) ...), but this is a closed implementation. If we want to keep the implementation open for extension, you could use something like the protocol-based code I wrote there, but it absolutely relies on these abstract data types being represented as Java interfaces rather than other protocols. David says that in 10,000 lines of code, there hasn't yet been something that required protocols to dispatch on other protocols, but in nearly the same breath he says that a polymorphic last function is impractical because of this limitation. The difficulty, he notes, is that a hypothetical ILast protocol can't be made to automatically work for all implementers of ISeq. Every single person who ever wanted to implement ISeq would also have to implement ILast. I would argue that as soon as you're ruling out ideas such as a polymorphic last function specifically because it would make it too difficult to maintain in a protocol-based system, that is clear evidence that indeed, we *are* running into a real limitation of protocols. So, I would like to better understand this limitation, and brainstorm with everyone about workarounds. I have some thoughts and ideas about this, but I want to better understand the ClojureScript architecture first. David, could you walk me through the implementation of nth, which is a very similar kind of function? I was able to find the part of the code on Github where you define an IIndexed protocol which provides a protocol for nth. However, I was unable to find the place in the code where you implement nth in linear time for all those who implement ISeq and faster for random-access collections. Can you point me to the relevant source code? Is nth open to extension to other abstract data types? Is nth guaranteed to work and gain the default implementation for new data types that implement ISeq? Do coders need to remember to implement IIndexed any time ISeq is implemented, and if so, how is that documented? 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.comjavascript:_e({}, 'cvml', 'clojure@googlegroups.com'); Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com javascript:_e({}, 'cvml', 'clojure%2bunsubscr...@googlegroups.com'); For more options, visit this group at http://groups.google.com/group/clojure?hl=en -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this
Re: Protocol as an abstract data type
On Sat, Jun 30, 2012 at 9:36 PM, David Nolen dnolen.li...@gmail.com wrote: Look at the implementation of nth. Or how polymorphic unification works in ClojureScript core.logic for ISequential. I misspoke a bit, should have clearer that I simply meant that ILast (probably something else entirely) needs to be carefully considered since the logic needs too be moved to the actual fn or into a protocol default case in order to cover ISeq (which isn't a good idea anyway - IBoundedSeq or some such makes more sense to me). OK, can you just give me the link to the relevant file? I don't understand the github clojurescript file directory structure. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Protocol as an abstract data type
Never mind, found 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 Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Protocol as an abstract data type
OK, I get it now. Protocols are attached to very specific capabilities. With this structure, it is easy to: Write a function that operates on an input that fulfills a specific protocol. Write a function that operates on an input that fulfills (all of) multiple protocols. Write a function that operates on a closed (non-extensible by outsiders) union of abstract data types (i.e., it satisfies *either* this protocol or that protocol). Write a function that has a default case, and can be extended by other concrete data types. Write a function that supports a closed union of abstract data types, but can still be extended by other concrete types. Pretty much the only thing you can't do with protocols is: Write a function that supports an open union of abstract data types, for example: I want this function to be able to work with objects that support nth, or objects that support the protocol for queues, and I want to leave it open to other kinds of abstract protocols I might not be able to think of right now. It's a limitation for sure. It is easy to think of scenarios like last where you want to offer one implementation for the abstract concept of sequential types, one for the abstract concept of reversible types, one for the abstract concept of random access types, and possibly leave it open for extension. But I can see why this kind of need for abstract extensibility might be rare, given the many other combinations that are well-supported by protocols. Regarding the specific use-case of last, in theory, I think it could be done in almost exactly the same way that nth is implemented. last would dispatch to a protocol containing -last to provide an extension point for concrete data types, and in a cond could test to see if various abstract protocols were satisfied, and if so use the corresponding last implementation. There's no point of extension for other abstract protocols, but that's not a huge deal (and certainly no worse than the current implementation which only supports one abstract protocol!) I don't feel strongly about last specifically, but if people wanted it to behave polymorphically, I'd be happy to volunteer to write the code. In any case, I feel like I understand better how you've structured things in ClojureScript and what can and can't be done easily with protocols. Thanks! -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Protocol as an abstract data type
implementation which only supports one abstract protocol!) I don't feel strongly about last specifically, but if people wanted it to behave polymorphically, I'd be happy to volunteer to write the code. Thanks a lot for the detailed analysis and volunteering to write the code. Not surprisingly, I am interested in seeing the code. I already put your protocol based implementation into my clj-cc lib. So you are going to write another version for ClojureScript? Or you are going to write a host independent version? -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Protocol as an abstract data type
On Sat, Jun 30, 2012 at 11:15 PM, Mark Engelberg mark.engelb...@gmail.com wrote: In any case, I feel like I understand better how you've structured things in ClojureScript and what can and can't be done easily with protocols. Thanks! I think predicate dispatch + protocols could eliminate the existing closed cases. David -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: idempotency
That's really a stricter requirement than idempotence (ie, functional purity). I don't believe the compiler ever does this. The JVM might, if it's able to inline some particular method call and discover therein that no mutation happens, but that's probably pretty rare given the amount of indirection that goes on when calling everything through the IFn interface. On Saturday, June 30, 2012 5:30:02 PM UTC-7, Brian Marick wrote: In its optimization, does the Clojure compiler ever assume idempotency? That is, does it ever look at a function application `(f x y z)` and say to itself I may freely substitute the result of the first application of `f` to those particular arguments for any later call? I could imagine it doing that for built-ins (or just primitives?), but not for user-defined functions (given the existence of atoms, etc.) I can also imagine it not bothering for any calls. - Brian Marick, Artisanal Labrador Contract programming in Ruby and Clojure Occasional consulting on Agile -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en