Nested identities in a value-based universe
I'm a big believer in Clojure / Rich Hickey's principles regarding the separation of Identity and State (http://www.infoq.com/presentations/ Are-We-There-Yet-Rich-Hickey) and how this is generally a good idea. However I've recently been running into what seems to be a slight conceptual challenge with this model - I'm creating a simulation system where there is a "world" that contains within it (among other things) a number of "actors". Basically the actors are some form of "nested identity" within the world. I'd like to be able to think about the world as a single value. So the entire "state of the world" could be considered as an identity with a current value that is immutable and stored in a single ref. (as an aside, making the world a persistent data structure is actually particularly useful for things like efficiently recording a sequence of world states, simulation of alternate histories etc.). At the same time however, the "actors" within the world also have their own identity. This is where it starts to get tricky. There seem to be several options on how to handle of this, but none of them seem very pretty.. a) separate out the actor identities but keep the value of the actors within the world state - seems to work, but you now have to keep multiple identities in sync - if the state of an actor changes, you have to update *both* the world state and the state of the specific actor. And now the entire state of the world isn't contained within the world identity so you can't easily do snapshots etc. b) Don't use Clojure managed references for actor identity - instead give each actor some form of ID and look up this ID within the world state whenever the actor is referred to. Again this seems to work, but you now you don't get the benefits of Clojure's references, you have a second class form of "identity" and need to wrap everything in a lot of functions to handle all the ID lookups etc. c) Put actor identities inside the world state - nasty! now the world state is mutable Am I missing something? Is there an easy way to handle this? Or is this genuinely a complex problem with the Clojure identity/state model? Any thoughts appreciated! -- 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: Clojure 1.3 treatment of integers and longs
Luc, what you're saying sounds to me like "this is the way it is so deal with it". Can you give me some concrete code snippets showing why it's better to box ints as Longs? Do you really think the following is at all intuitive? user=> (class (Integer/parseInt "1")) java.lang.Long user=> (class (Integer/valueOf "1")) java.lang.Integer -Nathan On Oct 20, 10:27 pm, Luc Prefontaine wrote: > The "weirdness" here is that you seem to confuse the Java context and the > Clojure > context. They are not the same. Clojure has to satisfy to performance and > consistency > criterias. It's a language of it's own, not a Java offspring. > > user=> (class (Integer/parseInt "1")) > java.lang.Long > user=> > > Integer/parseInt returns a primitive type. Not a boxed Integer object. > If used as a key in a map or anything else in Clojure, it will get promoted > to a long value as per the math > promotion rules (long/double representation). Obviously needed if it is to be > used later in a computation > otherwise it would break math operations consistency by allowing mixed > int/long operands. > > If passed as an interop parameter it will retain it's int type. > > user=> (class (Integer/valueOf 1)) > java.lang.Integer > > Integer/valueOf returns an Integer object, not a primitive type. > It's an object, not a primitive type, Clojure will not change it. > If used as a key in a Clojure map or any Clojure data structure, it will > retain its object status. > > Just cast your keys accordingly if you want Integer objects as keys. > In your short example, 1 as a key will not do it, it gets promoted to > primitive long. > > You may not recall but in Java, int used not to be compatible with Integer > objects. > It's only since java 5 that you can assign an Integer object to a primitive > int. > That's the compiler tricking things to allow you to do that. In the JVM > there's still > not represented in the same way. > > The above Integer member functions and their behavior have nothing to do with > Clojure. > They result from bad decisions made years ago when designing Java and the JVM > and you are blaming > Clojure for not handling them according to some patch implemented afterward > in the Java compiler. > > You ran in the ClassCast exception by yourself. Clojure did not push you into > it. > When using Java interop you have to obey to Java rules and bend accordingly. > It's not Clojure that needs to bend, it's you to adapt to the interop > restrictions/conventions. > > If Java expects an Integer object somewhere make sure you are providing it. > > Luc P. > > On Thu, 20 Oct 2011 21:11:41 -0700 (PDT) > > > > > > > > > > nathanmarz wrote: > > Now I'm confused. So when I do this: > > > (def i (Integer/parseInt "1")) > > > Is "i" a primitive int, a primitive long, or a Long object? > > > I was under the impression that it was a primitive int based on > > Justin's test code, but when I run "(primitive-type i)" in the REPL it > > tells me :object. > > > If "i" is a primitive int, then the only change I'm proposing is that > > if Clojure needs to box that value later on, that it box it as an > > Integer instead of a Long. This change in behavior would not affect > > primitive number performance since it's at a point when Clojure is > > already boxing. > > > If "i" is a primitive long (which is what I thought was happening > > originally), I propose that Clojure box the value as an Integer unless > > you wrap the form in a "(long ...") form. In the latter case Clojure > > would do what it's doing currently so you can still get the > > performance if you need it. The difference is that you're being > > explicit about the type changing so there's no possible confusion in > > that regard. > > > Finally, if "i" is a Long object, I propose that it instead be boxed > > as an Integer object. > > > Note that I am not saying: > > > 1. That Clojure always box primitives into an object form > > 2. That Clojure implement 32 bit arithmetic > > > In all these cases, you can still get maximum performance without > > Clojure changing ints to longs. Please correct me if there's something > > I'm missing here. > > > Stu's argument from above is that Clojure boxes ints to Longs instead > > of Integer to avoid weirdness with hashcode/equality in collections. > > This is a reasonable point, but consider this code example: > > > user=> (def m1 {(Integer/valueOf "1") 2}) > > #'user/m1 > > user=> (def m2 {(Integer/parseInt "1") 2}) > > #'user/m2 > > user=> (map class (keys m1)) > > (java.lang.Integer) > > user=> (map class (keys m2)) > > (java.lang.Long) > > > Clojure doesn't prevent you from putting Integer objects in > > collections. So there are cases where you still need to do type > > coercion yourself. Given that Clojure can't hide this problem > > completely from you, I think it's better that it treat "int" and > > "Integer" consistently by boxing ints as Integers. Then there's no > > weirdness like I ran into with getting ClassCastExcept
Re: Clojure 1.3 treatment of integers and longs
On Fri, Oct 21, 2011 at 12:52 AM, nathanmarz wrote: > user=> (class (Integer/parseInt "1")) > java.lang.Long (Integer/parseInt "1") returns an int - which Clojure promotes to long (since it only has 64-bit primitives) and class takes an Object so long is boxed to Long. > user=> (class (Integer/valueOf "1")) > java.lang.Integer (Integer/valueOf "1") returns an Integer - which is already an Object so (class Integer-value) returns Integer. You're only going to get 32-bit ints if you are calling into Java and that API expects an int - and you coerce the (64-bit primitive long) Clojure primitive to a 32-bit int (again, as I understand the 1.3 numerics). If Java gives Clojure an int, it will be treated as a 64-bit long. If Java gives Clojure an Integer, it will be treated as an Object. I rather like the simplicity of 1.3's numeric handling: there are only longs and doubles - but you can coerce them to whatever you need for interop. It's performant by default, it's simple and consistent (in my eyes) and yet still flexible. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Railo Technologies, Inc. -- http://www.getrailo.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: Nested identities in a value-based universe
> c) Put actor identities inside the world state - nasty! now the world > state is mutable Not necessarily (and I'd be interested in the replies)? I mean, here's how I view it. If actors are part of the world, then they are part of its state. Hence, when the state of an actor changes, the state of the world changes. If we accept this, then there's nothing wrong with keeping the state of the 'world' and that of the actors in a single data structure (albeit a potentially massive one) and call this the new world (or universe). If you have the appropriate functions for finding an actor inside the universe and updating it, then you should be good to go. Cheers, Ulises -- 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: partial, but instead of args + additional, get additional + args
How about a potentially ugly workaround: user> (defn sum [ & {:keys [x y]} ] (+ x y)) #'user/sum user> (sum :x 1 :y 2) 3 user> (def inc-sum (partial sum :x 1)) #'user/inc-sum user> (inc-sum :y 1) 2 user> (inc-sum :y 2) 3 user> I know this is a trivial example, but I do quite fancy named arguments and being able to set them explicitly in partial. U -- 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: Nested identities in a value-based universe
On Oct 21, 4:25 pm, Ulises wrote: > > c) Put actor identities inside the world state - nasty! now the world > > state is mutable > > Not necessarily (and I'd be interested in the replies)? > > I mean, here's how I view it. If actors are part of the world, then > they are part of its state. Hence, when the state of an actor changes, > the state of the world changes. If we accept this, then there's > nothing wrong with keeping the state of the 'world' and that of the > actors in a single data structure (albeit a potentially massive one) > and call this the new world (or universe). If you have the appropriate > functions for finding an actor inside the universe and updating it, > then you should be good to go. Are you arguing for my option b) then? In which case actors don't have distinct identities, they are just part of the overall world? I'm probably leaning towards this option myself, though it seems a little uncomfortable that the solution boils down to "put everything in one big ref". Also, if you then create some kind of "multiverse" with multiple worlds then following the same logic you need to refactor everything to have one big ref for the multiverse with multiple worlds contained within it. i.e. it doesn't seem to compose neatly... -- 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: Nested identities in a value-based universe
> Are you arguing for my option b) then? In which case actors don't have > distinct identities, they are just part of the overall world? Not necessarily as your option b) already gives implementation details (using ids to find actors, etc.). I was mostly thinking out loud to see if anything emerged. But certainly the idea of merging things together makes my life (sometimes) easier. > I'm probably leaning towards this option myself, though it seems a > little uncomfortable that the solution boils down to "put everything > in one big ref". Where does the discomfort come from? Mine would come from performance: if multiple actions are taken in parallel on this universe, e.g. one or more actors 'acting' then things will get ugly. Which brings me to this question: If one mashes actors and the world together, is that effectively saying that only one actor can act at a time? If so, then this might not be what you want. > Also, if you then create some kind of "multiverse" with multiple > worlds then following the same logic you need to refactor everything > to have one big ref for the multiverse with multiple worlds contained > within it. i.e. it doesn't seem to compose neatly... It certainly does get more involved the minute you have several universes ... U -- 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: Clojure 1.3 treatment of integers and longs
> Luc, what you're saying sounds to me like "this is the way it is so > deal with it". Can you give me some concrete code snippets showing why > it's better to box ints as Longs? Do you really think the following is > at all intuitive? > > user=> (class (Integer/parseInt "1")) > java.lang.Long > user=> (class (Integer/valueOf "1")) > java.lang.Integer > > > -Nathan If you box Ints and Longs separately then collection keys stop working, as I said at the start of this thread. There is no such thing as intuitive. The behavior above follows from a clear rule that can be followed locally in all cases. What you propose, in addition to breaking collections, requires more contextual reasoning to understand code in a bunch of scenarios. Could we meet on IRC and discuss this later today? Feel like we are going in circles. 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Ok I watched the talk, and I picked up a few things. But I have questions, which hopefully some kind member in the community can answer. There are several instances of libraries Rich mentions that provide simple constructs so what clojure libraries provide, set functions and rules (is it core.logic?). Is there any good examples I can use to improve my knowledge on using the simple constructs Rich presents? (Such as use of datalog?) And how would one structure something as stateful as a web app using these techniques? Hopefully someone can point to a pre-existing example that follows all or many of these ideas. Regards, Folcon -- 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
Reading special characters with slurp
Hello, in portuguese there are lots of special characters (such as *á*, *é*, *ã...*), but when I need a file with slurp I don't get this characters in the result. For example, if I have this line in the file: "Ferida perdida na imensidão." When I execute (slurp file-name), I get: "Ferida perdida na imensid�o\r" Of course, the � depends on the console, but the thing is: it doesn't read those letters, what can I do to overcome this? -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Reading special characters with slurp
when I read* a file -- 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: Reading special characters with slurp
You need to tell slurp how the file is encoded. (slurp path-to-my-file :encoding "UTF-8") That means that you'll need to know what encoding your file is using. If you've never dealt with encoding before, I recommend reading this: http://www.joelonsoftware.com/articles/Unicode.html // Ben On Fri, Oct 21, 2011 at 14:14, Jonathan Cardoso wrote: > when I read* a file > > -- > 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: Reading special characters with slurp
Thank's a lot, bsmith.occs, it worked I haven't consider the encoding =P -- 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: Clojure 1.3 treatment of integers and longs
Like Stu says, this conversation is going in circle. "Concrete code examples" cannot be a replacement for consistent rules when designing software and especially a prog. language. Since the beginning of this thread, you have been exposed to two of these: a) make collections consistent b) make computations efficient in Clojure These are 2 major reasons why promoting to long is rational. No need for code snippets. "Intuitive" is relative, it's not an objective criteria. What may seem intuitive to you can be counter intuitive to others. It all depends on the background of individuals. If you know the rules relative to numerics in Clojure and why they have been chosen, then its perfectly rational. Read carefully: http://dev.clojure.org/display/doc/Documentation+for+1.3+Numerics They is nothing else to say about this subject. Luc On Fri, 21 Oct 2011 00:52:50 -0700 (PDT) nathanmarz wrote: > Luc, what you're saying sounds to me like "this is the way it is so > deal with it". Can you give me some concrete code snippets showing why > it's better to box ints as Longs? Do you really think the following is > at all intuitive? > > user=> (class (Integer/parseInt "1")) > java.lang.Long > user=> (class (Integer/valueOf "1")) > java.lang.Integer > > > -Nathan > > > > On Oct 20, 10:27 pm, Luc Prefontaine > wrote: > > The "weirdness" here is that you seem to confuse the Java context > > and the Clojure context. They are not the same. Clojure has to > > satisfy to performance and consistency criterias. It's a language > > of it's own, not a Java offspring. > > > > user=> (class (Integer/parseInt "1")) > > java.lang.Long > > user=> > > > > Integer/parseInt returns a primitive type. Not a boxed Integer > > object. If used as a key in a map or anything else in Clojure, it > > will get promoted to a long value as per the math promotion rules > > (long/double representation). Obviously needed if it is to be used > > later in a computation otherwise it would break math operations > > consistency by allowing mixed int/long operands. > > > > If passed as an interop parameter it will retain it's int type. > > > > user=> (class (Integer/valueOf 1)) > > java.lang.Integer > > > > Integer/valueOf returns an Integer object, not a primitive type. > > It's an object, not a primitive type, Clojure will not change it. > > If used as a key in a Clojure map or any Clojure data structure, it > > will retain its object status. > > > > Just cast your keys accordingly if you want Integer objects as keys. > > In your short example, 1 as a key will not do it, it gets promoted > > to primitive long. > > > > You may not recall but in Java, int used not to be compatible with > > Integer objects. It's only since java 5 that you can assign an > > Integer object to a primitive int. That's the compiler tricking > > things to allow you to do that. In the JVM there's still not > > represented in the same way. > > > > The above Integer member functions and their behavior have nothing > > to do with Clojure. They result from bad decisions made years ago > > when designing Java and the JVM and you are blaming Clojure for not > > handling them according to some patch implemented afterward in the > > Java compiler. > > > > You ran in the ClassCast exception by yourself. Clojure did not > > push you into it. When using Java interop you have to obey to Java > > rules and bend accordingly. It's not Clojure that needs to bend, > > it's you to adapt to the interop restrictions/conventions. > > > > If Java expects an Integer object somewhere make sure you are > > providing it. > > > > Luc P. > > > > On Thu, 20 Oct 2011 21:11:41 -0700 (PDT) > > > > > > > > > > > > > > > > > > > > nathanmarz wrote: > > > Now I'm confused. So when I do this: > > > > > (def i (Integer/parseInt "1")) > > > > > Is "i" a primitive int, a primitive long, or a Long object? > > > > > I was under the impression that it was a primitive int based on > > > Justin's test code, but when I run "(primitive-type i)" in the > > > REPL it tells me :object. > > > > > If "i" is a primitive int, then the only change I'm proposing is > > > that if Clojure needs to box that value later on, that it box it > > > as an Integer instead of a Long. This change in behavior would > > > not affect primitive number performance since it's at a point > > > when Clojure is already boxing. > > > > > If "i" is a primitive long (which is what I thought was happening > > > originally), I propose that Clojure box the value as an Integer > > > unless you wrap the form in a "(long ...") form. In the latter > > > case Clojure would do what it's doing currently so you can still > > > get the performance if you need it. The difference is that you're > > > being explicit about the type changing so there's no possible > > > confusion in that regard. > > > > > Finally, if "i" is a Long object, I propose that it instead be > > > boxed as an Integer object. > > > > > Note that I am not saying: > > > > > 1. That Cloj
accessing clojurescript browser REPL remotely
Is the clojurescript REPL set up to allow access from remote machines? My development box is all set up, and I'm able to connect to the REPL from OSX Safari and Simulated Mobile Safari. Everything is localhost, so it all works great. I'm currently able to use my iPad and iPhone to access my devbox's web server on the local wireless network, so I thought the browser REPL would just work. When I turn on the iPad debug console, I get one or more of the following errors: JavaScript: Error undefined TypeError: 'undefined' is not a constructor I've tried turning off the firewall. I've tried changing the hostname to a number of ips and local network names, i.e. (repl/connect "http:// 0.0.0.0:9000/repl"). Has anyone had success with this? I really sense a great environment for developing mobile web apps! -pat -- 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: Who will be at QCon SF?
Me too! It's gonna be great! On Wed, Oct 19, 2011 at 10:30 PM, Abbas wrote: > Look forward to your talk. > > Cheers, > Abbas > > On Oct 18, 5:19 pm, Aaron Bedra wrote: > > I will be there and am giving a talk in the functional web track > > > > http://qconsf.com/sf2011/presentation/One+%28%29+to+Rule+them+All > > > > See you on the coast. > > > > Cheers, > > > > Aaron Bedra > > -- > > Clojure/corehttp://clojure.com > > > > On 09/27/2011 06:28 PM, Demetrius Nunes wrote: > > > > > > > > > > > > > > > > > Hi guys, > > > > > I'd love to meet with fellow "clojurians" at QCon SF. How many of you > > > will be there? > > > > > cheers! > > > Demetrius > > > > > -- > > > 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 > -- http://www.demetriusnunes.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: Nested identities in a value-based universe
Hi, may I question the transitivity of state information? Maybe the world's state is that player "Trantor" is at position [15 34]. Now Trantor eats an appel. The appel is removed from his inventory and his health is raised by 5 hit points. Did the state of the world change? No. Trantor is still at position [15 34]. Does the world have to know about the apple in Trantors inventory and the sad state of his hit points? Disclaimer: I have no clue about game programming, about what information is needed where and how this is implemented insanely fast. Just a naive question from the distance. Sincerely Meikel -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Tail Recursion In Erjang
I thought tail recursion was actually not possible on the JVM but saw a talk on the Erlang VM yesterday and Robert Virding mentioned that Erjang managed to do it. I'm sure the core guys have seen it but just in case others thought the same as me here are a few links: http://www.javalimit.com/2009/12/tail-recursion-in-erjang.html https://github.com/trifork/erjang/wiki/How-Erjang-compiles-tail-recursion If someone could comment briefly on why one would not want to do this in clojure too that would be nice. Tom -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
> And how would one structure something as stateful as a web app using these > techniques? Hopefully someone can point to a pre-existing example that > follows all or many of these ideas. I currently work on a thick-client system. But our back-end is quite stateless. One thing that irks me the most about our system in C# is that we've intertwined business logic with business data. So, in our application, let's say we have a person class. We will have the following classes: tPerson (data class generated by our ORM) PersonDTO (data transfer object) Person (business object) So the idea is that SQL will load data from the tPerson table and place it into a tPerson C# object. Now, the last thing we want, is to have a hard dependency on tPerson from our Person object. that is, we never want to have Person take tPerson as an argument. Because then those two objects are tightly coupled. Where one goes, the other must follow. So instead we have a PersonDTO object that transfers the data between the objects. The Person object the contains business logic (user must have a last name...user must be over 18, etc.). The sad thing is, that business logic is now built directly into Person. This complicates the whole system. What Rich is advocating is this: throw all the data into a hashmap. Suddenly, my SQL driver can just dump data in to the map, I can throw that map around without introducing dependencies, and I can pass that map through the web to the client. In addition to all this, I should break my rules out of the Person object and into a set of validator functions. Now I have real power! Suddenly my rules apply to any and every object that has a last name property and a age property! So instead of 3 tightly coupled objects, I will be left with a map, and a set of highly generic functions that can be reused again and again. Getting back to your question, I think it's just good to sit down with your web app and start asking yourself. "What assumptions am I making about this code? Am I assuming function a will always call function b? Could there be a case where I would want a to call c? Well in that case, maybe I should account for that...". The SQLObject->DTO->BusinessObject pattern is fairly common in the real world. So perhaps that is something to re-evaluate in your designs. Timothy -- 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: Nested identities in a value-based universe
> Maybe the world's state is that player "Trantor" is at position [15 34]. Now > Trantor eats an appel. The appel is removed from his inventory and his > health is raised by 5 hit points. Did the state of the world change? No. > Trantor is still at position [15 34]. Does the world have to know about the > apple in Trantors inventory and the sad state of his hit points? I know absolutely nothing about games either, however whether an actor eating an apple changes the state of the world or not would depend on how you've modeled the world. If the apple was taken from the world so that other actors cannot eat the same apple then the act of eating changes the world. And we could even push the argument further by asking whether a healthier actor has an effect of the world and even consider the potential effect of a healthier actor as an effective change of the world. But that'd be pushing it :) U -- 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: Clojure 1.3 treatment of integers and longs
Perhaps I can clarify why the 1.3 behavior is confusing. For those who have focused on issues like "primitives need to be boxed, therefore you get a long" - I think you are missing Nathan's point. Here is what changed about boxing in 1.3: Clojure 1.2: (class (Long/parseLong "1")) => java.lang.Long (class (Integer/parseInt "1")) => java.lang.Integer (class (Short/parseShort "1")) => java.lang.Short (class (Byte/parseByte "1")) => java.lang.Byte (class (Float/parseFloat "1")) => java.lang.Float (class (Double/parseDouble "1")) => java.lang.Double Clojure 1.3: (class (Long/parseLong "1")) => java.lang.Long (class (Integer/parseInt "1")) => java.lang.Long (class (Short/parseShort "1")) => java.lang.Short (class (Byte/parseByte "1")) => java.lang.Byte (class (Float/parseFloat "1")) => java.lang.Float (class (Double/parseDouble "1")) => java.lang.Double So the issue is not "why do primitives get boxed at all?" - it is "why are primitive ints, uniquely amongst all primitive types, singled out and boxed as a wrapper type that is not the analogue of their primitive type?" I suspect that this is what Nathan is objecting to. - Chris -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Wow. Easily the best conference talk I have seen... well, ever. Executive summary: "Mutability is bad for your complection." :) - Chris -- 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: Tail Recursion In Erjang
Clojure does tail-call elimination for simple cases with loop/recur. This is by far the most common case. Most other tail-recursive situations can be represented as lazy sequences, which are another way to handle recursive functions without consuming stack space. For the final rare cases (e.g. mutually recursive functions) Clojure has `trampoline`, which does something similar to (on first glance) Erjang. One nice thing about Clojure's approach is that any function can be invoked from Java just like any other method. On a quick read, I can't tell if the Erjang approach requires special handling from Java code. The underlying goal of Clojure's recursion semantics is to always be explicit about where compilation strategies will differ. Loop/recur, lazy seqs, and trampoline all have different performance characteristics. You don't have to guess which method is being used. -Stuart Sierra 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
Re: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Great talk! I got lost a bit in the Abstraction for Simplicity. Could anybody provide me some concrete examples for Who When Where Why slides? -- 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: Tail Recursion In Erjang
Tom Hall writes: > I'm sure the core guys have seen it but just in case others thought > the same as me here are a few links: > http://www.javalimit.com/2009/12/tail-recursion-in-erjang.html > https://github.com/trifork/erjang/wiki/How-Erjang-compiles-tail-recursion > > If someone could comment briefly on why one would not want to do this > in clojure too that would be nice. Isn't that pretty much what clojure's `recur' special form does, i.e., converting a self-recursion into a non-stack-consuming loop? Bye, Tassilo -- 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: accessing clojurescript browser REPL remotely
Hmm I get no errors. But it doesn't work. I agree that would be a *real* killer app for ClojureScript. Debugging JS on mobile browsers is a big pain. I will try looking into it if no one else gets to it first, ticket created http://dev.clojure.org/jira/browse/CLJS-92 David On Thu, Oct 20, 2011 at 6:10 PM, stratospark wrote: > Is the clojurescript REPL set up to allow access from remote machines? > My development box is all set up, and I'm able to connect to the REPL > from OSX Safari and Simulated Mobile Safari. Everything is localhost, > so it all works great. > > I'm currently able to use my iPad and iPhone to access my devbox's web > server on the local wireless network, so I thought the browser REPL > would just work. When I turn on the iPad debug console, I get one or > more of the following errors: > > JavaScript: Error > undefined > TypeError: 'undefined' is not a constructor > > I've tried turning off the firewall. I've tried changing the hostname > to a number of ips and local network names, i.e. (repl/connect "http:// > 0.0.0.0:9000/repl"). > > Has anyone had success with this? I really sense a great environment > for developing mobile web apps! > > -pat > > -- > 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
leiningen: how to set compiled classes outputdir
Hi, I'm trying to set the classes output path different from the default src/main/classes by overriding :javac-options {:destdir "../../target/classes/"} and that does not seem to work. is there a property I can use to accomplish this? Thanks, Siyu -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Hey Timothy, Thanks for the response, I currently perform some of these steps. My data is taken out of mongodb and converted into straight clojure maps. I pass these around in my application, calling validation functions on them etc. Having said that, this talk will push me to take a good look at my code to see what kind of implicit assumptions that I am making. However I'm still not clear what a set function is, unless it's this http://en.wikipedia.org/wiki/Set_function. Which is odd because the compares them to looping constructs and Haskell's fold. And in the talk he mentions that rules are more simple than conditionals, which I (maybe incorrectly) take to mean that rules can replace conditionals. So what exactly do we mean by rules? Core.logic? And how do they take the place of conditionals? Regards, Folcon -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Question:Multi-Core processor affinity for load balancing Clojure Web apps
Thank you both.. This information was really helpful. Tim On Oct 20, 6:05 pm, Andy Fingerhut wrote: > I would suspect that you would not get a _significant_ performance advantage > from specifying processor affinity, but if you really want to measure it and > find out by experimentation, read on. > > I was not able to find any portable way within a JVM to set processor > affinity, after some amount of Googling on the Internet about a year ago. > There might be some ways that are specific to some JVMs, but I didn't find > any then. > > If you want to set the processor affinity for an arbitrary process running > on Linux, whether it is a JVM or not, you can do so with a sched_affinity() > call in a little wrapper process that starts up the process for you. > > According to the StackOverflow discussion linked below, user tgamblin found > that sched_affinity() semantics can vary across Linux distributions. They > mention a Portable Linux Processor Affinity library that may be useful, > although I haven't tried it myself. They mention that for some > high-performance parallel applications, e.g. using the MPI library, it is > common practice to manually specify processor affinity. > > http://stackoverflow.com/questions/360307/multicore-hyperthreading-ho... > > Note that if you benchmark manually setting processor affinity vs. not, note > that benchmarking this with programs that use very little memory (e.g. an > infinite loop that just counts iterations) will likely not show as much > difference as a benchmark that has significant usage of the on-chip CPU > instruction and/or data cache, so that switching the scheduling of the > thread to a different CPU core actually causes significant cache misses > after being "moved". > > Andy > > On Thu, Oct 20, 2011 at 11:41 AM, Tim Robinson wrote: > > > > > > > > > This may not be a Clojure specific kind of question, but this is for > > my Clojure web app(s) so hopefully it's not too far off. > > > Currently when I deploy my web apps I run 1 app instance on 1 app > > server. Given these are multi-core servers I am thinking about running > > 4 app instances on a server to get max IO capabilities at a lower > > cost. (Note that I currently using nginx, to route requests to a > > Clojure/Ring+Jetty web app on a specified port. I am expecting that in > > order to run 4 app instances I will need to load balance within nginx > > to each port and also set the processor affinity for each app instance > > to ensure they are balanced across cores). > > > So here are my questions: > > > 1. Does this idea make sense? why/whynot? > > 2. Do you do currently do this for your web apps and can you provide > > any insight/experiences that could be helpful? > > 3. Is there a way to specify processor affinity within the > > application, such that I wouldn't need to manually set them > > afterwards? > > 4. Are there better ideas to accomplish the same kind of thing? > > > Thanks for any help/ideas. > > > Tim > > > -- > > You received this message because you are subscribed to the Google > > Groups "Clojure" group. > > To post to this group, send email to clojure@googlegroups.com > > 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
I've always felt that Clojure's treatment of nil was somehow inconsistent with the elegance of many other features of Clojure. Now I can finally articulate why: nil complects non-existence, false, and empty. The choice to make nil represent so many concepts was an "easy" choice, because it saves a few characters when you can write things like (when seq ) vs. (when (empty? seq) ...) and Clojure implements sequences in a way that the former expression is also a bit more performant. It is also easy in the sense that it is more similar to what Lisp users (as opposed to Scheme) are used to from past experience. But it is decidedly less simple to have these ideas complected. Over the past couple of years, I've seen numerous bugs along the lines of "Your function usually works great, but it breaks when the list/map/vector you pass in contains nil values." It seems clear to me that nil's complexity makes programs harder to analyze, because when you're writing your code, you might be thinking of nil as only representing non-existence or emptiness, for example, and forgetting that the system will treat nil as a false value as well. -- 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: leiningen: how to set compiled classes outputdir
I tried :compile-path and it worked, but it's not listed in https://github.com/technomancy/leiningen/blob/stable/sample.project.clj -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
If I understand your post correctly you feel that nil should ONLY represent the concept of a missing value. It should not represent false and empty. Having used lisp in many different forms over the last 40 years I think that the "complecting" of nil to represent all three concepts is one of the most brilliant aspects of the language. In fact it is one of the key flaws of scheme, in my opinion, that they added true and false. There is a fourth use of nil that is also very convenient. Lisp functions return it as a default value. This makes it possible to wrap functions with functions which other languages like C++ make very difficult. (e.g. if we have a C++ function void foo() we cannot wrap it with another bar(foo()) well, we can but we have to use the comma hack as in bar((foo(),1)) ) Java code is littered with checks for null before every iterator construct where the code could be so much cleaner if iterators just "did the right thing" with null, that is, end the iteration. The use of nil as a unified value for the many meanings leads to a lot of useful features. The context of the nil value completely defines the intended meaning. Tim Daly On Fri, 2011-10-21 at 09:50 -0700, Mark Engelberg wrote: > I've always felt that Clojure's treatment of nil was somehow > inconsistent with the elegance of many other features of Clojure. Now > I can finally articulate why: nil complects non-existence, false, and > empty. > > > > The choice to make nil represent so many concepts was an "easy" > choice, because it saves a few characters when you can write things > like (when seq ) vs. (when (empty? seq) ...) and Clojure > implements sequences in a way that the former expression is also a bit > more performant. It is also easy in the sense that it is more similar > to what Lisp users (as opposed to Scheme) are used to from past > experience. But it is decidedly less simple to have these ideas > complected. > > > Over the past couple of years, I've seen numerous bugs along the lines > of "Your function usually works great, but it breaks when the > list/map/vector you pass in contains nil values." It seems clear to > me that nil's complexity makes programs harder to analyze, because > when you're writing your code, you might be thinking of nil as only > representing non-existence or emptiness, for example, and forgetting > that the system will treat nil as a false value as well. > -- > 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: leiningen: how to set compiled classes outputdir
On Fri, Oct 21, 2011 at 10:33 AM, siyu798 wrote: > I tried :compile-path and it worked, but it's not listed > in https://github.com/technomancy/leiningen/blob/stable/sample.project.clj Good catch; I will add this. -Phil -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, Oct 21, 2011 at 10:38 AM, daly wrote: > If I understand your post correctly you feel that nil should > ONLY represent the concept of a missing value. It should not > represent false and empty. Yes, you correctly interpreted my post. That is my opinion. > The context of the nil value > completely defines the intended meaning. This is a point I disagree with. The context defines the meaning of nil intended by the person coding that function. It does nothing to ensure that the coder has thought about what the function will do if nil is used with another meaning, and it does nothing to ensure that consumers of that function will use nil in the way the coder intended. I have found this to be a relatively common source of bugs that pass test cases (because test cases are written by the coder who has a specific intention in mind) but show up in the field. > > Having used lisp in many different forms over the last 40 years > I think that the "complecting" of nil to represent all three > concepts is one of the most brilliant aspects of the language. That may be. If so, it undermines one of the messages in the video that complecting=bad. If this particular complection is brilliant, it naturally leads to a lot of deeper questions: When is complecting brilliant rather than bad? How does one tell the difference? -- 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: Tail Recursion In Erjang
On Fri, Oct 21, 2011 at 10:14 AM, Stuart Sierra wrote: > Clojure does tail-call elimination for simple cases with loop/recur. This is > by far the most common case. Most other tail-recursive situations can be > represented as lazy sequences, which are another way to handle recursive > functions without consuming stack space. For the final rare cases (e.g. > mutually recursive functions) Clojure has `trampoline`, which does something > similar to (on first glance) Erjang. I agree, it seems that Erjang is doing a form of trampoline automatically. Besides Clojure's solution being manual, another difference is that Clojure returns the data necessary to execute the next step while Erjang stores that data in a mutable spot that's used only by the current thread. > One nice thing about Clojure's approach is that any function can be invoked > from Java just like any other method. On a quick read, I can't tell if the > Erjang approach requires special handling from Java code. This is a critical question for Java. It looks like every Erjang function provides an .invoke() method than handles any required trampolining, so calling that from Java should be safe. > The underlying goal of Clojure's recursion semantics is to always be > explicit about where compilation strategies will differ. Loop/recur, lazy > seqs, and trampoline all have different performance characteristics. You > don't have to guess which method is being used. This, combined with the fact that together these techniques cover an overwhelming majority of use cases (and the fact that they're already done and work) means the cost/benefit of now adding something like Erjang does may not be so good. Hm, and besides performance there are implications for stack traces. Trampolines, either explicit in Clojure or automatic in Erjang, surely would make Java stack traces harder to understand as information about intermediate function calls would be completely missing. Might be an interesting experiment though. So... is a function call that could be either of two things (a loop/recur or a trampoline site) simple or complected? --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 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On 10/21/2011 06:50 PM, Mark Engelberg wrote: Now I can finally articulate why: nil complects non-existence, false, and empty. How does nil represent empty? '() does not equal nil. It is also easy in the sense that it is more similar to what Lisp users (as opposed to Scheme) are used to from past experience. But it is decidedly less simple to have these ideas complected. AFAIK, Common Lisp does treat nil and empty lists as equivalent. Looks like a clear difference, not "more similar" to me. -- Thorsten Wilms thorwil's design for free software: http://thorwil.wordpress.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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Collections often include false as a value. You will have to handle it by using some other value like ::not-found. David On Fri, Oct 21, 2011 at 12:50 PM, Mark Engelberg wrote: > I've always felt that Clojure's treatment of nil was somehow inconsistent > with the elegance of many other features of Clojure. Now I can finally > articulate why: nil complects non-existence, false, and empty. > > The choice to make nil represent so many concepts was an "easy" choice, > because it saves a few characters when you can write things like (when seq > ) vs. (when (empty? seq) ...) and Clojure implements sequences in a way > that the former expression is also a bit more performant. It is also easy > in the sense that it is more similar to what Lisp users (as opposed to > Scheme) are used to from past experience. But it is decidedly less simple > to have these ideas complected. > > Over the past couple of years, I've seen numerous bugs along the lines of > "Your function usually works great, but it breaks when the list/map/vector > you pass in contains nil values." It seems clear to me that nil's > complexity makes programs harder to analyze, because when you're writing > your code, you might be thinking of nil as only representing non-existence > or emptiness, for example, and forgetting that the system will treat nil as > a false value as well. > > -- > 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
> nil complects non-existence, false, and empty. Let's explore that a little further: * Non-existence - Accessing a local or var that has never been declared * False - (if nil :never-here :but-here) * Empty - (seq []) And maybe there is another? * Not set - (def x) - (:x {:a 1}) But which one should nil actually mean? Given a green-field scenario that is. I can definitely see where you're going, but I wonder if the use of nil in Clojure is the result of a cost/benefit analysis in relation to Java interop? -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, Oct 21, 2011 at 11:08 AM, Thorsten Wilms wrote: > On 10/21/2011 06:50 PM, Mark Engelberg wrote: >> >> Now I can finally articulate why: nil complects non-existence, false, >> and empty. > > How does nil represent empty? '() does not equal nil. (cons 1 nil) is one obvious example. The pattern of using first/next/nil? as a more efficient/compact alternative to first/rest/empty? is arguably another. -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, Oct 21, 2011 at 11:22 AM, David Nolen wrote: > Collections often include false as a value. You will have to handle it by > using some other value like ::not-found. > > David True, but the multiple meanings of nil creates additional complexity. Contrast, for example, (filter identity s) and (keep identity s). One strips nil and false values, the other just strips nil values. Why do we need both? Because sometimes we mean nil and false to be the same, and sometimes we don't. Have you ever gotten this wrong? I have, and I understand these issues pretty well. Maybe you haven't, maybe you can "juggle more balls" than I can. But as Rich pointed out in the video, simplicity is about respecting the fact that all of our brains have limitations and can get tripped up when things are complected. -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, Oct 21, 2011 at 11:43 AM, Mark Engelberg wrote: >> How does nil represent empty? '() does not equal nil. > > (cons 1 nil) is one obvious example. > > The pattern of using first/next/nil? as a more efficient/compact > alternative to first/rest/empty? is arguably another. > One more anecdote about this. One time, I wrote a function that looked like this: (defn f [s] (when s .)) At the time I wrote the function, I did the analysis, and realized that my function was always being called with sequences (specifically, sequences that had already been "seq-ified" at some prior point), so it was safe to use "when" as a way to screen out the empty things. So I opted for this easy, efficient way to express this. Somewhere along the line, as my application grew more complex, I needed to reuse f in another context, and when looking at the docs for f (which said something like "consumes a sequence and does ...", I thought I could safely pass in a lazy sequence. But I couldn't because when a lazy sequence is "empty" it is not "nil". My program was buggy and it took a while track down the source of the problem. Yes, it was my fault. In retrospect, I see that my program would have been more robust had I not made assumptions about s, and written it as (when (seq s) ...) or perhaps (when (not (empty? s)) ...) But I do think it's fair to pin at least some of the blame on the complexity of nil. Since nil can be used interchangeably with the concept of emptiness in so many circumstances, and was interchangeable in the initial context of my function, it was all too easy to rely on that behavior. -- 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: accessing clojurescript browser REPL remotely
Thanks for looking into it! Regarding the issue: "Cannot interact with Browser REPL running in iOS/ Webkit Mobile devices", I did try it locally on my development machine with the iOS simulator and it works fine. For both iPhone and iPad, and iOS version 4 and 5. Only on the actual devices, connecting through the wireless router, does it give errors. -pat On Oct 21, 8:53 am, David Nolen wrote: > Hmm I get no errors. But it doesn't work. I agree that would be a *real* > killer app for ClojureScript. Debugging JS on mobile browsers is a big pain. > > I will try looking into it if no one else gets to it first, ticket > createdhttp://dev.clojure.org/jira/browse/CLJS-92 > > David > > > > > > > > On Thu, Oct 20, 2011 at 6:10 PM, stratospark wrote: > > Is the clojurescript REPL set up to allow access from remote machines? > > My development box is all set up, and I'm able to connect to the REPL > > from OSX Safari and Simulated Mobile Safari. Everything is localhost, > > so it all works great. > > > I'm currently able to use my iPad and iPhone to access my devbox's web > > server on the local wireless network, so I thought the browser REPL > > would just work. When I turn on the iPad debug console, I get one or > > more of the following errors: > > > JavaScript: Error > > undefined > > TypeError: 'undefined' is not a constructor > > > I've tried turning off the firewall. I've tried changing the hostname > > to a number of ips and local network names, i.e. (repl/connect "http:// > > 0.0.0.0:9000/repl"). > > > Has anyone had success with this? I really sense a great environment > > for developing mobile web apps! > > > -pat > > > -- > > 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Just because we have dynamic types does not give us the freedom to not consider them. (when s ...) Does not communicate anything about collections - only nil, false or something else. (when (seq s) ...) (when (empty? s) ...) Clearly express a consideration about the types at play. David On Fri, Oct 21, 2011 at 3:36 PM, Mark Engelberg wrote: > On Fri, Oct 21, 2011 at 11:43 AM, Mark Engelberg > wrote: > >> How does nil represent empty? '() does not equal nil. > > > > (cons 1 nil) is one obvious example. > > > > The pattern of using first/next/nil? as a more efficient/compact > > alternative to first/rest/empty? is arguably another. > > > > One more anecdote about this. > > One time, I wrote a function that looked like this: > (defn f [s] > (when s .)) > > At the time I wrote the function, I did the analysis, and realized > that my function was always being called with sequences (specifically, > sequences that had already been "seq-ified" at some prior point), so > it was safe to use "when" as a way to screen out the empty things. So > I opted for this easy, efficient way to express this. > > Somewhere along the line, as my application grew more complex, I > needed to reuse f in another context, and when looking at the docs for > f (which said something like "consumes a sequence and does ...", I > thought I could safely pass in a lazy sequence. But I couldn't > because when a lazy sequence is "empty" it is not "nil". My program > was buggy and it took a while track down the source of the problem. > > Yes, it was my fault. In retrospect, I see that my program would have > been more robust had I not made assumptions about s, and written it as > (when (seq s) ...) > or perhaps > (when (not (empty? s)) ...) > > But I do think it's fair to pin at least some of the blame on the > complexity of nil. Since nil can be used interchangeably with the > concept of emptiness in so many circumstances, and was interchangeable > in the initial context of my function, it was all too easy to rely on > that behavior. > > -- > 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, Oct 21, 2011 at 12:41 PM, David Nolen wrote: > Just because we have dynamic types does not give us the freedom to not > consider them. Oh, I definitely considered the types when I wrote the function. It's just that at the time I wrote it, I was confident the input would already be seq-ified. nil, among its many purposes, is a key part of the "seq interface", and testing for nil is how you are expected to interact with seqs to determine emptiness. As my program grew, the assumption that the input would definitely be a seq was invalidated. This is exactly the inherent challenge of making evolving, maintainable programs that Rich speaks of in his video. If the only way to test for a seq to be empty were a general-purpose function like empty? that applied to all collections, my code would have worked in the new context. If the only to test for a seq to be empty were a seq-specific function like seq-empty? then when placed in the new context, my code would have broken in a very clear, easily diagnosable way. But because we test for seqs to be empty using nil, an object with many other purposes, my code appeared to work, but was semantically wrong -- always a hard thing to track down. I suppose one could also place some small portion of the blame on the problem of assigning clear linguistic labels to Clojure's types. Is something a sequence? A seq? A seqable? A collection? It's always been difficult to come up with clear definitions for these categories, and to specify the appropriate precondition with perfect clarity in a docstring. --Mark -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, 2011-10-21 at 12:36 -0700, Mark Engelberg wrote: > On Fri, Oct 21, 2011 at 11:43 AM, Mark Engelberg > wrote: > >> How does nil represent empty? '() does not equal nil. > > > > (cons 1 nil) is one obvious example. > > > > The pattern of using first/next/nil? as a more efficient/compact > > alternative to first/rest/empty? is arguably another. > > > > One more anecdote about this. > > One time, I wrote a function that looked like this: > (defn f [s] >(when s .)) > > At the time I wrote the function, I did the analysis, and realized > that my function was always being called with sequences (specifically, > sequences that had already been "seq-ified" at some prior point), so > it was safe to use "when" as a way to screen out the empty things. So > I opted for this easy, efficient way to express this. > > Somewhere along the line, as my application grew more complex, I > needed to reuse f in another context, and when looking at the docs for > f (which said something like "consumes a sequence and does ...", I > thought I could safely pass in a lazy sequence. But I couldn't > because when a lazy sequence is "empty" it is not "nil". My program > was buggy and it took a while track down the source of the problem. THIS is where the multiple meaning of nil in traditional lisp is brilliant. I believe that Clojure "got it wrong" in the design decision to make (seq s) and (not (empty? s)) have different semantics. This is the same mindset that causes (me) so much grief in Java... looping and iteration does the wrong thing with NULL and I have to check for NULL every time. Yet everyone, if given an empty list of things to shop for, will know NOT to go shopping. > > Yes, it was my fault. In retrospect, I see that my program would have > been more robust had I not made assumptions about s, and written it as > (when (seq s) ...) > or perhaps > (when (not (empty? s)) ...) Actually I don't think this is entirely your fault (modulo the fact that we need to understand our language semantics). I believe that this is due to a deep design flaw. You're not the only person to mis-handle an empty sequence. > > But I do think it's fair to pin at least some of the blame on the > complexity of nil. Since nil can be used interchangeably with the > concept of emptiness in so many circumstances, and was interchangeable > in the initial context of my function, it was all too easy to rely on > that behavior. > Tim Daly Literate Software -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
> (because test cases are written by the coder who has a > specific intention in mind) > Good observation. When I see figures of tests coverage I wonder how many flow paths aren't being covered simply because they don't exists but they should. -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, Oct 21, 2011 at 4:02 PM, Mark Engelberg wrote: > On Fri, Oct 21, 2011 at 12:41 PM, David Nolen > wrote: > > Just because we have dynamic types does not give us the freedom to not > > consider them. > > Oh, I definitely considered the types when I wrote the function. It's > just that at the time I wrote it, I was confident the input would > already be seq-ified. nil, among its many purposes, is a key part of > the "seq interface", and testing for nil is how you are expected to > interact with seqs to determine emptiness. As my program grew, the > assumption that the input would definitely be a seq was invalidated. > This is exactly the inherent challenge of making evolving, > maintainable programs that Rich speaks of in his video. Testing for nil is not how you determine emptiness unless locally you are using next. (rest '()) -> () (next '()) -> nil 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Fri, 2011-10-21 at 15:41 -0400, David Nolen wrote: > Just because we have dynamic types does not give us the freedom to not > consider them. If all of these dynamics types and all of the tests "respected nil" in its many meanings then (when s ..., (when (seq s)..., (when (empty? s)..., would not be an issue. (when s...) would "just work". > > > Clearly express a consideration about the types at play. Clojure was supposed to transparently substitute things like sequences and vectors everywhere that lisp used lists. That would be true if nil was respected but is not true now and this complicates the code without apparent benefit, in my opinion. In lisp you can ask what the type is (e.g. by calling consp, vectorp, etc) but these type-specific predicates are relatively rarely used. In fact, when they are used then you are struggling with data-level issue that could probably be abstracted away (e.g. a code smell). Clojure is a great language but the nil handling is, in my opinion, a design flaw. It forces the introduction of (empty?...) and an awareness of the data types into view unnecessarily. Tim Daly Literate Software -- 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
Potential bug: pmap vs chunked seqs
Hi: I found what I think might be considered a bug, but I'm not certain. The doc-string for `pmap' just says that the passed-in function is applied "in parallel," but the code as-written is pretty clearly intended to keep only (+ 2 #CPUS) future-wrapped function applications realized at a time. It works exactly that way for non-chunked seqs, but when called with a chunked seq instead keeps realized some arbitrary number of futures between (+ 2 #CPUS) and the next multiple of 32. Given that the code for `pmap' hasn't changed since chunked seqs were added to Clojure, this feels like a bug to me, but the parallelism semantics for `pmap' aren't exactly strictly defined. Is this worth opening a ticket for in the Clojure issue tracker? -Marshall -- 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: Array type hints in 1.3
Another annotation bug: Annotations on gen-class in an ns form, like (ns foo (:gen-class ^{Singleton {}} foo.ClassName)) don't seem to work. -- __ Herwig Hochleitner -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
This message is not specifically in reply to Tim, but to the thread in general. It can be very difficult to enumerate (or even remember :) all of the contending tradeoffs around something like Clojure's nil handling. The is no doubt nil punning is a form of complecting. But you don't completely remove all issues merely by using empty collections and empty?, you need something like Maybe and then things get really gross (IMO, for a concise dynamic language). I like nil punning, and find it to be a great source of generalization and reduction of edge cases overall, while admitting the introduction of edges in specific cases. I am with Tim in preferring CL's approach over Scheme's, and will admit to personal bias and a certain comfort level with its (albeit small) complexity. However, it couldn't be retained everywhere. In particular, two things conspire against it. One is laziness. You can't actually return nil on rest without forcing ahead. Clojure old timers will remember when this was different and the problems it caused. I disagree with Mark that this is remains significantly complected, nil is not an empty collection, nil is nothing. Second, unlike in CL where the only 'type' of empty collection is nil and cons is not polymorphic, in Clojure conj *is* polymorphic and there can only be one data type created for (conj nil ...), thus we have [], {}, and empty?. Were data structures to collapse to nil on emptying, they could not be refilled and retain type. At this point, this discussion is academic as nothing could possibly change in this area. The easiest way to think about is is that nil means nothing, and an empty collection is not nothing. The sequence functions are functions of collection to (possibly lazy) collection, and seq/next is forcing out of laziness. No one is stopping you from using rest and empty?, nor your friend from using next and conditionals. Peace! Rich On Oct 21, 2011, at 4:25 PM, daly wrote: > On Fri, 2011-10-21 at 15:41 -0400, David Nolen wrote: >> Just because we have dynamic types does not give us the freedom to not >> consider them. > > If all of these dynamics types and all of the tests "respected nil" > in its many meanings then > (when s ..., > (when (seq s)..., > (when (empty? s)..., > would not be an issue. (when s...) would "just work". > >> >> >> Clearly express a consideration about the types at play. > > Clojure was supposed to transparently substitute things like sequences > and vectors everywhere that lisp used lists. That would be true if nil > was respected but is not true now and this complicates the code without > apparent benefit, in my opinion. > > In lisp you can ask what the type is (e.g. by calling consp, vectorp, > etc) but these type-specific predicates are relatively rarely used. > In fact, when they are used then you are struggling with data-level > issue that could probably be abstracted away (e.g. a code smell). > > Clojure is a great language but the nil handling is, in my opinion, > a design flaw. It forces the introduction of (empty?...) and an > awareness of the data types into view unnecessarily. > > Tim Daly > Literate Software > > > > > -- > 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Bravo, bravo! Great speech, I'm already looking for such esseys. I'm already learning haskell and erlang for great good, because all things told about lisp has been already read. I'm also designing system. Because it has some well defined functionality, my first tought was, hey man I will use obect oriented approach to creat model of that system. It is easy to document in UML since I only concerned on fundamental operations. Complexity of diffrent configurations I wanted to hide in poliformism of java oo programing. But i have found it corrupted, nevertheless i will still document it in terms of objects. OO is broken because it require from me to build tree structure of impl. objects depending on types of processing, I would make it simpler by message dispatching but, I have choosed protocols. Still don't know if it will work, because never used them before, but from read materials that is its purpose. I don't need state of obj. because it is about processing input and spitting output. Btw. from built-in data structures I'm missing trees. On 21 Paź, 22:25, daly wrote: > On Fri, 2011-10-21 at 15:41 -0400, David Nolen wrote: > > Just because we have dynamic types does not give us the freedom to not > > consider them. > > If all of these dynamics types and all of the tests "respected nil" > in its many meanings then > (when s ..., > (when (seq s)..., > (when (empty? s)..., > would not be an issue. (when s...) would "just work". > > > > > Clearly express a consideration about the types at play. > > Clojure was supposed to transparently substitute things like sequences > and vectors everywhere that lisp used lists. That would be true if nil > was respected but is not true now and this complicates the code without > apparent benefit, in my opinion. > > In lisp you can ask what the type is (e.g. by calling consp, vectorp, > etc) but these type-specific predicates are relatively rarely used. > In fact, when they are used then you are struggling with data-level > issue that could probably be abstracted away (e.g. a code smell). > > Clojure is a great language but the nil handling is, in my opinion, > a design flaw. It forces the introduction of (empty?...) and an > awareness of the data types into view unnecessarily. > > Tim Daly > Literate Software -- 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
Flattening a tree
I'm a bit unsure as to the best way to solve this. Assuming I have the following tree: {:parent1 {:relationship1 {:child1 1} {:child2 2}} {:relationship2 {child3 3}} {:_meta}} I want to get: [:parent1 :relationship1 :child1] [:parent1 :relationship1 :child2] [:parent1 :relationship2 :child3] How do I got about getting this? Notice how I also want to filter out all :_meta nodeswhat I want is to get a sequence of vectors where each vector consists of all the lowest child keys along with the path required to get to that key. Thanks for the help, Timothy -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
Rich, My apologies that what I have said about nil punning came across as criticism directed at you. That was not intentional. I have the highest respect for your design work. You're doing an amazing job and I continue to learn from you. I understand the lazy vs empty issue and I think you made a good tradeoff. I'm just bemoaning the fact that nil-punning is really vital in keeping data-type issues out of my lisp life and that won't work in Clojure. Ultimately this is cured by deep learning of the language semantics. I still have a way to go. Tim Daly Literate Software On Fri, 2011-10-21 at 17:03 -0400, Rich Hickey wrote: > This message is not specifically in reply to Tim, but to the thread in > general. > > It can be very difficult to enumerate (or even remember :) all of the > contending tradeoffs around something like Clojure's nil handling. > > The is no doubt nil punning is a form of complecting. But you don't > completely remove all issues merely by using empty collections and empty?, > you need something like Maybe and then things get really gross (IMO, for a > concise dynamic language). > > I like nil punning, and find it to be a great source of generalization and > reduction of edge cases overall, while admitting the introduction of edges in > specific cases. I am with Tim in preferring CL's approach over Scheme's, and > will admit to personal bias and a certain comfort level with its (albeit > small) complexity. > > However, it couldn't be retained everywhere. In particular, two things > conspire against it. One is laziness. You can't actually return nil on rest > without forcing ahead. Clojure old timers will remember when this was > different and the problems it caused. I disagree with Mark that this is > remains significantly complected, nil is not an empty collection, nil is > nothing. > > Second, unlike in CL where the only 'type' of empty collection is nil and > cons is not polymorphic, in Clojure conj *is* polymorphic and there can only > be one data type created for (conj nil ...), thus we have [], {}, and empty?. > Were data structures to collapse to nil on emptying, they could not be > refilled and retain type. > > At this point, this discussion is academic as nothing could possibly change > in this area. > > The easiest way to think about is is that nil means nothing, and an empty > collection is not nothing. The sequence functions are functions of collection > to (possibly lazy) collection, and seq/next is forcing out of laziness. No > one is stopping you from using rest and empty?, nor your friend from using > next and conditionals. Peace! > > Rich > > On Oct 21, 2011, at 4:25 PM, daly wrote: > > > On Fri, 2011-10-21 at 15:41 -0400, David Nolen wrote: > >> Just because we have dynamic types does not give us the freedom to not > >> consider them. > > > > If all of these dynamics types and all of the tests "respected nil" > > in its many meanings then > > (when s ..., > > (when (seq s)..., > > (when (empty? s)..., > > would not be an issue. (when s...) would "just work". > > > >> > >> > >> Clearly express a consideration about the types at play. > > > > Clojure was supposed to transparently substitute things like sequences > > and vectors everywhere that lisp used lists. That would be true if nil > > was respected but is not true now and this complicates the code without > > apparent benefit, in my opinion. > > > > In lisp you can ask what the type is (e.g. by calling consp, vectorp, > > etc) but these type-specific predicates are relatively rarely used. > > In fact, when they are used then you are struggling with data-level > > issue that could probably be abstracted away (e.g. a code smell). > > > > Clojure is a great language but the nil handling is, in my opinion, > > a design flaw. It forces the introduction of (empty?...) and an > > awareness of the data types into view unnecessarily. > > > > Tim Daly > > Literate Software > > > > > > > > > > -- > > 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: accessing clojurescript browser REPL remotely
Turns out this works just fine. You need to make sure that you change: (repl/connect "http://localhost:9000/repl";) In your source to be the correct IP. David On Fri, Oct 21, 2011 at 3:39 PM, stratospark wrote: > Thanks for looking into it! > > Regarding the issue: "Cannot interact with Browser REPL running in iOS/ > Webkit Mobile devices", I did try it locally on my development machine > with the iOS simulator and it works fine. For both iPhone and iPad, > and iOS version 4 and 5. Only on the actual devices, connecting > through the wireless router, does it give errors. > > -pat > > On Oct 21, 8:53 am, David Nolen wrote: > > Hmm I get no errors. But it doesn't work. I agree that would be a *real* > > killer app for ClojureScript. Debugging JS on mobile browsers is a big > pain. > > > > I will try looking into it if no one else gets to it first, ticket > createdhttp://dev.clojure.org/jira/browse/CLJS-92 > > > > David > > > > > > > > > > > > > > > > On Thu, Oct 20, 2011 at 6:10 PM, stratospark wrote: > > > Is the clojurescript REPL set up to allow access from remote machines? > > > My development box is all set up, and I'm able to connect to the REPL > > > from OSX Safari and Simulated Mobile Safari. Everything is localhost, > > > so it all works great. > > > > > I'm currently able to use my iPad and iPhone to access my devbox's web > > > server on the local wireless network, so I thought the browser REPL > > > would just work. When I turn on the iPad debug console, I get one or > > > more of the following errors: > > > > > JavaScript: Error > > > undefined > > > TypeError: 'undefined' is not a constructor > > > > > I've tried turning off the firewall. I've tried changing the hostname > > > to a number of ips and local network names, i.e. (repl/connect "http:// > > > 0.0.0.0:9000/repl"). > > > > > Has anyone had success with this? I really sense a great environment > > > for developing mobile web apps! > > > > > -pat > > > > > -- > > > 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 > -- 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: Flattening a tree
The example tree was not accepted as a valid data structure, so I used this instead. Hopefully it represents what you had in mind: (def tree {:parent1 {:relationship1 {:child1 1 :child2 2} :relationship2 {:child3 3} :_meta 4}}) I wanted to use clojure.walk to do this, but couldn't figure out how, so this is what I ended up with instead. 'excluded' should be a set of keys you want to exclude on the walk. (defn walk-tree [tree excluded] (let [f (fn f [m path] (apply concat (for [[k v] m] (cond (excluded k) nil (map? v) (f v (conj path k)) :else (list (conj path k))] (f tree []))) user=> (walk-tree tree #{:_meta}) ([:parent1 :relationship1 :child1] [:parent1 :relationship1 :child2] [:parent1 :relationship2 :child3]) Note that if a path ends with an empty map, that path will not be printed. Don't know if this is acceptable or not. (def tree2 {:parent1 {:relationship1 {:child1 {} :child2 2} :relationship2 {:child3 3} :_meta 4}}) user=> (walk-tree tree2 #{:_meta}) ([:parent1 :relationship1 :child2] [:parent1 :relationship2 :child3]) -- 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: Array type hints in 1.3
Hello Herwig, I checked the patch you linked to in your original post, and it doesn't seem that type hinting for native arrays of Objects is supported, that is the [L type. Native arrays of native types work quite well. (definterface Name (^"[S" method [])) ;;returns array of shorts (def p (proxy [Name] [] (method [] (short-array [(short 10) (short 1)] ;;method returns short[2] (.method p) ;; returns # Cheers, Ivan. On 21 October 2011 23:02, Herwig Hochleitner wrote: > Another annotation bug: > > Annotations on gen-class in an ns form, like (ns foo (:gen-class > ^{Singleton {}} foo.ClassName)) don't seem to work. > > -- > __ > Herwig Hochleitner > > -- > 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: Clojure jar files.
On Fri, 2011-10-21 at 09:19 +0530, Baishampayan Ghose wrote: > If you are going to upload your library to any Maven (or similar) repo > that's accessible through Leiningen, then you may choose to not > include a project.clj file; in any case, if you yourself are using > Leiningen, you should include that file. FWIW, Leiningen can generate > pom.xml files from project.clj as well. Moreover, Leiningen can deploy to Maven repos. So it is probably easier to accept whatever `lein jar', `lein install', or `lein deploy', depending on your preference, gives you, rather than reinventing that part of Leiningen. -- Stephen Compall ^aCollection allSatisfy: [:each|aCondition]: less is better -- 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: Clojure 1.3 treatment of integers and longs
Yea let's chat on IRC. I'll ping you when I see you online. -Nathan On Oct 21, 4:24 am, Stuart Halloway wrote: > > Luc, what you're saying sounds to me like "this is the way it is so > > deal with it". Can you give me some concrete code snippets showing why > > it's better to box ints as Longs? Do you really think the following is > > at all intuitive? > > > user=> (class (Integer/parseInt "1")) > > java.lang.Long > > user=> (class (Integer/valueOf "1")) > > java.lang.Integer > > > -Nathan > > If you box Ints and Longs separately then collection keys stop working, as I > said at the start of this thread. > > There is no such thing as intuitive. The behavior above follows from a clear > rule that can be followed locally in all cases. What you propose, in addition > to breaking collections, requires more contextual reasoning to understand > code in a bunch of scenarios. > > Could we meet on IRC and discuss this later today? Feel like we are going in > circles. > > 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: Potential bug: pmap vs chunked seqs
Why do you think, there is a bug? You are referring to the /code/, i.e. the implementation, of things, which is not a defined interface. At the same time, the /documentation/ describes the actual behavior quite well. Chunked seqs are supposed to realize more elements than you consume. That's for performance reasons. But since you will only ever apply side-effect-free functions to seqs, that will make no difference, no? To me, all this is perfectly fine behavior. So, I'd say no, please don't open a ticket. Unless I misunderstood something obvious, that is. Kind regards, Stefan -- 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: accessing clojurescript browser REPL remotely
Thanks, it works with a hardcoded IP address. I had tried using our Bonjour network hostnames, but that doesn't seem to work. The important thing is now I have a REPL to my iPad! -pat On Oct 21, 2:53 pm, David Nolen wrote: > Turns out this works just fine. You need to make sure that you change: > > (repl/connect "http://localhost:9000/repl";) > > In your source to be the correct IP. > > David > > > > > > > > On Fri, Oct 21, 2011 at 3:39 PM, stratospark wrote: > > Thanks for looking into it! > > > Regarding the issue: "Cannot interact with Browser REPL running in iOS/ > > Webkit Mobile devices", I did try it locally on my development machine > > with the iOS simulator and it works fine. For both iPhone and iPad, > > and iOS version 4 and 5. Only on the actual devices, connecting > > through the wireless router, does it give errors. > > > -pat > > > On Oct 21, 8:53 am, David Nolen wrote: > > > Hmm I get no errors. But it doesn't work. I agree that would be a *real* > > > killer app for ClojureScript. Debugging JS on mobile browsers is a big > > pain. > > > > I will try looking into it if no one else gets to it first, ticket > > createdhttp://dev.clojure.org/jira/browse/CLJS-92 > > > > David > > > > On Thu, Oct 20, 2011 at 6:10 PM, stratospark wrote: > > > > Is the clojurescript REPL set up to allow access from remote machines? > > > > My development box is all set up, and I'm able to connect to the REPL > > > > from OSX Safari and Simulated Mobile Safari. Everything is localhost, > > > > so it all works great. > > > > > I'm currently able to use my iPad and iPhone to access my devbox's web > > > > server on the local wireless network, so I thought the browser REPL > > > > would just work. When I turn on the iPad debug console, I get one or > > > > more of the following errors: > > > > > JavaScript: Error > > > > undefined > > > > TypeError: 'undefined' is not a constructor > > > > > I've tried turning off the firewall. I've tried changing the hostname > > > > to a number of ips and local network names, i.e. (repl/connect "http:// > > > > 0.0.0.0:9000/repl"). > > > > > Has anyone had success with this? I really sense a great environment > > > > for developing mobile web apps! > > > > > -pat > > > > > -- > > > > 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 -- 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
Function to generate a SQL IN clause from a list of values
Hi I wrote the following function to create a SQL IN clause from a list of values. Essentially the function creates a single string which is a comma separated quoted list of the values surrounded by parenthesis. user=> (def xs [1 2 3 4 5]) user=>(str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) "')") "('1', '2', '3', '4', '5')" user=> (def xs ["ab" "cd" "ef" "gh"]) user=> (str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) "')") "('ab', 'cd', 'ef', 'gh')" I am wondering if there is a better/easier/more elegant way to write this function. Or if I can make use of a more suitable function from the clojure core library to achieve this? Thanks Shoeb -- 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: Rich Hickey: "Simple Made Easy" from Strange Loop 2011
On Oct 21, 2011, at 5:37 PM, daly wrote: > Rich, > > My apologies that what I have said about nil punning came across > as criticism directed at you. It certainly didn't come across that way - no worries :-) Rich -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Function to generate a SQL IN clause from a list of values
user=> (str "('" (apply str (interpose "', '" [1 2 3 4 5])) "')") "('1', '2', '3', '4', '5')" Would be a way to do it. Interpose returns a lazy sequence so you need to apply str to realize the sequence. Luc P. On Fri, 21 Oct 2011 17:54:41 -0700 (PDT) Shoeb Bhinderwala wrote: > Hi > > I wrote the following function to create a SQL IN clause from a list > of values. Essentially the function creates a single string which is a > comma separated quoted list of the values surrounded by parenthesis. > > user=> (def xs [1 2 3 4 5]) > > user=>(str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > "')") > "('1', '2', '3', '4', '5')" > > user=> (def xs ["ab" "cd" "ef" "gh"]) > > user=> (str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > "')") > "('ab', 'cd', 'ef', 'gh')" > > I am wondering if there is a better/easier/more elegant way to write > this function. Or if I can make use of a more suitable function from > the clojure core library to achieve this? > > Thanks > Shoeb > -- Luc P. The rabid Muppet -- 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: Function to generate a SQL IN clause from a list of values
Augh don't do this, you are begging for SQL injection attacks. I'll set one of the elements in your list to: '); DROP TABLE users; -- On Oct 21, 5:54 pm, Shoeb Bhinderwala wrote: > Hi > > I wrote the following function to create a SQL IN clause from a list > of values. Essentially the function creates a single string which is a > comma separated quoted list of the values surrounded by parenthesis. > > user=> (def xs [1 2 3 4 5]) > > user=>(str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > "')") > "('1', '2', '3', '4', '5')" > > user=> (def xs ["ab" "cd" "ef" "gh"]) > > user=> (str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > "')") > "('ab', 'cd', 'ef', 'gh')" > > I am wondering if there is a better/easier/more elegant way to write > this function. Or if I can make use of a more suitable function from > the clojure core library to achieve this? > > Thanks > Shoeb -- 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: Potential bug: pmap vs chunked seqs
Stefan Kamphausen writes: > Chunked seqs are supposed to realize more elements than you > consume. That's for performance reasons. But since you will only ever > apply side-effect-free functions to seqs, that will make no > difference, no? Sorry, yes, I'm talking about within the code of `pmap'. It creates a lazy seq of futures of application of the passed-in function to the passed-in collection via (map #(future (f %)) coll). Realizing elements of *that* seq has the side-effect of allocating/spawning a thread from the futures thread-pool. If `coll' can be turned into a chunked seq, then the futures will be realized -- and threads allocated or spawned -- in chunks of 32. If `coll' cannot be turned into chunked seq, then only (+ 2 #CPUS) threads will be allocated/spawned at a time. I think clarifying that has convinced me that this is definitely bug, just because the side-effects are inconsistent. I don't think that the chunkability (chunkiness?) of the collection argument should affect the degree of parallelism. -Marshall -- 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: Array type hints in 1.3
Just found another one: You can't annotate constructors of gen-class. 2011/10/22 Ivan Koblik : > Hello Herwig, > I checked the patch you linked to in your original post, and it doesn't seem > that type hinting for native arrays of Objects is supported, that is the [L > type. Yes. It should be. > Native arrays of native types work quite well. > (definterface Name (^"[S" method [])) ;;returns array of shorts > (def p (proxy [Name] [] > (method [] (short-array [(short 10) (short 1)] ;;method returns > short[2] > (.method p) ;; returns # Interesting, I didn't actually check the runtime behavior. Decompiler says, the emitted class names are bogus. JVM probably doesn't cast on return, so it slips through. Have you tried hinting an argument? kind regards -- __ Herwig Hochleitner -- 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: Function to generate a SQL IN clause from a list of values
It all depends if you sanitize the arguments yourself before building the SQL string... Luc On Fri, 21 Oct 2011 19:23:22 -0700 (PDT) Alan Malloy wrote: > Augh don't do this, you are begging for SQL injection attacks. I'll > set one of the elements in your list to: > '); DROP TABLE users; -- > > On Oct 21, 5:54 pm, Shoeb Bhinderwala > wrote: > > Hi > > > > I wrote the following function to create a SQL IN clause from a list > > of values. Essentially the function creates a single string which > > is a comma separated quoted list of the values surrounded by > > parenthesis. > > > > user=> (def xs [1 2 3 4 5]) > > > > user=>(str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > > "')") > > "('1', '2', '3', '4', '5')" > > > > user=> (def xs ["ab" "cd" "ef" "gh"]) > > > > user=> (str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest > > xs)) "')") > > "('ab', 'cd', 'ef', 'gh')" > > > > I am wondering if there is a better/easier/more elegant way to write > > this function. Or if I can make use of a more suitable function from > > the clojure core library to achieve this? > > > > Thanks > > Shoeb > -- Luc P. The rabid Muppet -- 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: Function to generate a SQL IN clause from a list of values
Thanks. It is so much cleaner with interpose. On Oct 21, 9:24 pm, Luc Prefontaine wrote: > user=> (str "('" (apply str (interpose "', '" [1 2 3 4 5])) "')") > "('1', '2', '3', '4', '5')" > > Would be a way to do it. Interpose returns a lazy sequence so you need to > apply str to realize the sequence. > > Luc P. > > On Fri, 21 Oct 2011 17:54:41 -0700 (PDT) > > > > > > > > > > Shoeb Bhinderwala wrote: > > Hi > > > I wrote the following function to create a SQL IN clause from a list > > of values. Essentially the function creates a single string which is a > > comma separated quoted list of the values surrounded by parenthesis. > > > user=> (def xs [1 2 3 4 5]) > > > user=>(str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > > "')") > > "('1', '2', '3', '4', '5')" > > > user=> (def xs ["ab" "cd" "ef" "gh"]) > > > user=> (str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > > "')") > > "('ab', 'cd', 'ef', 'gh')" > > > I am wondering if there is a better/easier/more elegant way to write > > this function. Or if I can make use of a more suitable function from > > the clojure core library to achieve this? > > > Thanks > > Shoeb > > -- > Luc P. > > > The rabid Muppet -- 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: Function to generate a SQL IN clause from a list of values
clojure.string/join On Oct 21, 8:54 pm, Shoeb Bhinderwala wrote: > Thanks. It is so much cleaner with interpose. > > On Oct 21, 9:24 pm, Luc Prefontaine > wrote: > > > > > > > > > user=> (str "('" (apply str (interpose "', '" [1 2 3 4 5])) "')") > > "('1', '2', '3', '4', '5')" > > > Would be a way to do it. Interpose returns a lazy sequence so you need to > > apply str to realize the sequence. > > > Luc P. > > > On Fri, 21 Oct 2011 17:54:41 -0700 (PDT) > > > Shoeb Bhinderwala wrote: > > > Hi > > > > I wrote the following function to create a SQL IN clause from a list > > > of values. Essentially the function creates a single string which is a > > > comma separated quoted list of the values surrounded by parenthesis. > > > > user=> (def xs [1 2 3 4 5]) > > > > user=>(str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > > > "')") > > > "('1', '2', '3', '4', '5')" > > > > user=> (def xs ["ab" "cd" "ef" "gh"]) > > > > user=> (str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest xs)) > > > "')") > > > "('ab', 'cd', 'ef', 'gh')" > > > > I am wondering if there is a better/easier/more elegant way to write > > > this function. Or if I can make use of a more suitable function from > > > the clojure core library to achieve this? > > > > Thanks > > > Shoeb > > > -- > > Luc P. > > > > > The rabid Muppet -- 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: Function to generate a SQL IN clause from a list of values
On Fri, Oct 21, 2011 at 5:54 PM, Shoeb Bhinderwala wrote: > I wrote the following function to create a SQL IN clause from a list > of values. Essentially the function creates a single string which is a > comma separated quoted list of the values surrounded by parenthesis. If you're using clojure.java.jdbc, you could generate a lit of ? for the SQL and just using the vector directly... something like this (off the top of my head, completely untested): (def qs (clojure.string/join "," (repeat (count xs) "?"))) (def sql (str "select * from table where id in (" qs ")")) (clojure.java.jdbc/with-query-result conn rows [ sql xs ] (do-something-to rows)) Sorry, don't have a REPL open right now to test this... -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Railo Technologies, Inc. -- http://www.getrailo.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: Function to generate a SQL IN clause from a list of values
Always forgetting this one :) It performs better than the other solutions... On Fri, 21 Oct 2011 21:15:51 -0700 (PDT) Alan Malloy wrote: > clojure.string/join > > On Oct 21, 8:54 pm, Shoeb Bhinderwala > wrote: > > Thanks. It is so much cleaner with interpose. > > > > On Oct 21, 9:24 pm, Luc Prefontaine > > wrote: > > > > > > > > > > > > > > > > > user=> (str "('" (apply str (interpose "', '" [1 2 3 4 5])) "')") > > > "('1', '2', '3', '4', '5')" > > > > > Would be a way to do it. Interpose returns a lazy sequence so you > > > need to apply str to realize the sequence. > > > > > Luc P. > > > > > On Fri, 21 Oct 2011 17:54:41 -0700 (PDT) > > > > > Shoeb Bhinderwala wrote: > > > > Hi > > > > > > I wrote the following function to create a SQL IN clause from a > > > > list of values. Essentially the function creates a single > > > > string which is a comma separated quoted list of the values > > > > surrounded by parenthesis. > > > > > > user=> (def xs [1 2 3 4 5]) > > > > > > user=>(str "('" (first xs) (reduce #(str %1 "', '" %2) "" (rest > > > > xs)) "')") > > > > "('1', '2', '3', '4', '5')" > > > > > > user=> (def xs ["ab" "cd" "ef" "gh"]) > > > > > > user=> (str "('" (first xs) (reduce #(str %1 "', '" %2) > > > > "" (rest xs)) "')") > > > > "('ab', 'cd', 'ef', 'gh')" > > > > > > I am wondering if there is a better/easier/more elegant way to > > > > write this function. Or if I can make use of a more suitable > > > > function from the clojure core library to achieve this? > > > > > > Thanks > > > > Shoeb > > > > > -- > > > Luc P. > > > > > > > > The rabid Muppet > -- Luc P. The rabid Muppet -- 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: Function to generate a SQL IN clause from a list of values
Can't repeat this strongly enough. Do not, ever, decide you can escape/ sanitize the strings yourself so you don't need a parameterized query. Maybe it works, but one of these days you'll slip up and get something wrong. Just prepare a statement with the right number of ?s in it, and then ask the SQL driver/server to fill in the blanks. They'll never get it wrong, and it will be more efficient to boot if you can reuse a parameterized query later. On Oct 21, 9:22 pm, Sean Corfield wrote: > On Fri, Oct 21, 2011 at 5:54 PM, Shoeb Bhinderwala > > wrote: > > I wrote the following function to create a SQL IN clause from a list > > of values. Essentially the function creates a single string which is a > > comma separated quoted list of the values surrounded by parenthesis. > > If you're using clojure.java.jdbc, you could generate a lit of ? for > the SQL and just using the vector directly... something like this (off > the top of my head, completely untested): > > (def qs (clojure.string/join "," (repeat (count xs) "?"))) > > (def sql (str "select * from table where id in (" qs ")")) > > (clojure.java.jdbc/with-query-result conn rows > [ sql xs ] > (do-something-to rows)) > > Sorry, don't have a REPL open right now to test this... > -- > Sean A Corfield -- (904) 302-SEAN > An Architect's View --http://corfield.org/ > World Singles, LLC. --http://worldsingles.com/ > Railo Technologies, Inc. --http://www.getrailo.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: clojure starter package for aichallenge ?
Hm? My starter package is there: http://aichallenge.org/starter_packages.php They changed the game at the end and I didn't have time to update it for hills, but it actually works just fine as is. Also, it should be fairly trivial for someone to add that bit... Cheers, Chris. On Oct 20, 11:58 am, faenvie wrote: > hi clojure community, > > at the moment there seems to be no applicable > clojure starter package for thehttp://aichallenge.org/ > > though some work has be done on it by chris granger, i > think:https://github.com/ibdknox/aichallenge > > are there any plans to get a clojure starter package out ? > it would be nice to see clojure-programs participate in the > challenge. > > have a successful day -- 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: Array type hints in 1.3
I reread your original post, sorry I saw that you managed to declare type constrained methods. Then, what was your question about? Type hinting for arguments works as well: (definterface Name (^"[S" method [^"[S" short-arg])) (def p (proxy [Name] [] (method [^"[S" short-arg] short-arg))) (.method p (short-array [(short 10) (short 11)])) Interesting, I didn't actually check the runtime behavior. Decompiler > says, the emitted class names are bogus. > Do you mean the interface name? > JVM probably doesn't cast on return, so it slips through. Have you > tried hinting an argument? > I'm not sure what happens in case of arrays, but for simple return types it definitely does the check. (def p (proxy [Comparable] [] (^int compareTo [arg] arg) ;;doesn't matter (^String toString [] 10))) ;;will throw ClassCastException on invocation. Cheers, Ivan. -- 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