Padding missing elements in a sequence of identical K/V maps
Hi all, I have a sequence of {:key K :value V} maps. There is no guarantee that there is one map for every known K. I need to ensure that there is a map for each known K. Imagine the sequence represents a distribution between 1 and 5. The initial sequence might only be [{:key 3 :value 30} {:key 4 :value 40}]. I want it to be [{:key 1 :value nil} {:key 2 :value nil} {:key 3 :value 30} {:key 4 :value 40} {:key 5 :value nil}]. (There is a sensible reason for {:key K :value V} rather than {K V} by the way, but it would be possible to temporarily represent the sequence as [K1 V1 K2 V2] and then convert it back.) In Java I would do something like: // create a convenient look up to avoid nasty N^2 lookups MapObject, Object keyToValue = new HashMap for (MapObject, Object kvMap: kvSequence) keyToValue.put(kvMap.get(key), kvMap.put(value)); ListObject allKeys = calculateAllKeys(); ListMapObject, Object results = new Array for (Object key: allKeys) Object result = keyToValue.get(key); // null is fine for missing keys results.put(key, result); return results; What is the (far more elegant and succinct!) way in Clojure? My intuition says something like create a map of K/V (i.e. {k1 nil k2 nil}) for all known keys, convert the existing sequence of maps into a flattened map, merge them together allowing the original sequence to take precedence and then group them back into [{:key k1 :value v1} {:key k2 :value v2}]. Any hints/clues - is this the right approach? Thanks a bunch! Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Padding missing elements in a sequence of identical K/V maps
Great stuff - thanks Jim. (not sure why my previous post got lost) On Tuesday, November 19, 2013 11:48:17 AM UTC, Jim foo.bar wrote: On 19/11/13 11:42, Jim - FooBar(); wrote: On 19/11/13 11:29, Colin Yates wrote: Imagine the sequence represents a distribution between 1 and 5. The initial sequence might only be [{:key 3 :value 30} {:key 4 :value 40}]. I want it to be [{:key 1 :value nil} {:key 2 :value nil} {:key 3 :value 30} {:key 4 :value 40} {:key 5 :value nil}]. (def map-seq [{:key 3 :value 30} {:key 4 :value 40}]) (def mandatory-keys (range 1 6)) (sort-by :key (reduce #(if (some #{%2} (map :key %)) % (conj % {:key %2 :value nil})) map-seq mandatory-keys)) = ({:key 1, :value nil} {:key 2, :value nil} {:key 3, :value 30} {:key 4, :value 40} {:key 5, :value nil}) Jim of course if the keys are known in advance, you don't want to calculate them every single time: (let [ks (map :key map-seq)] (sort-by :key (reduce #(if (some #{%2} ks) % (conj % {:key %2 :value nil})) map-seq mandatory-keys))) Jim -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: cider status
That's the culprit - I was wondering why nrepl wouldn't disappear! For me, cider has been rock solid with midje-mode, but I am not really exercising it too much. On Tuesday, November 19, 2013 2:56:05 PM UTC, Phillip Lord wrote: I discovered one of the reasons for my issues with stability yesterday. The version of clojure-test-mode on marmalade still depends on nrepl (rather than cider), so, despite my best efforts to remove nrepl.el it was still getting pulled back in. Fun and games! Phil Phillip Lord philli...@newcastle.ac.uk javascript: writes: I have tried it a couple of times and keep reverting back to nrepl. One of the biggest issues is nrepl-ritz which depends on nrepl and not nrepl-client. So switching to cider appears to mean ditching ritz. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: configure leiningen to use library when repl starts
Something that works is putting :injections [(require 'clojure.repl)] in .lein/profiles.clj. It works (as evidenced by (doc ...) working in lein repl) but I don't know if that is the correct approach. On Tuesday, November 19, 2013 4:57:48 PM UTC, Andy Smith wrote: Hi, total newbie here and have come unstuck with the repl configuration. How can I configure my leiningen project's clj file to call '(use 'clojure.math.numeric-tower)' when the repl is started with 'lein repl'? I have tried adding the command to the repl-options but I get a java exception when I start the repl : (defproject test 1.0.0-SNAPSHOT :description FIXME: write description :dependencies [[org.clojure/clojure 1.3.0] [org.clojure/math.numeric-tower 0.0.2]]) :repl-options { :init (clojure.core/use 'clojure.math.numeric-tower)} andy@Aspire-V3-571:~/projects/clojure/test$ lein repl Exception in thread main java.lang.ClassNotFoundException: org.clojure (project.clj:1) at clojure.lang.Compiler.analyze(Compiler.java:5206) at clojure.lang.Compiler.analyze(Compiler.java:5152) at clojure.lang.Compiler$VectorExpr.parse(Compiler.java:2592) at clojure.lang.Compiler.analyze(Compiler.java:5193) at clojure.lang.Compiler.analyze(Compiler.java:5152) at clojure.lang.Compiler$VectorExpr.parse(Compiler.java:2592) at clojure.lang.Compiler.analyze(Compiler.java:5193) at clojure.lang.Compiler.analyze(Compiler.java:5152) at clojure.lang.Compiler$MapExpr.parse(Compiler.java:2499) at clojure.lang.Compiler.analyze(Compiler.java:5195) at clojure.lang.Compiler.analyze(Compiler.java:5152) at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:4671) at clojure.lang.Compiler$FnMethod.parse(Compiler.java:4329) at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3174) at clojure.lang.Compiler.analyzeSeq(Compiler.java:5368) at clojure.lang.Compiler.analyze(Compiler.java:5191) at clojure.lang.Compiler.eval(Compiler.java:5422) at clojure.lang.Compiler.load(Compiler.java:5858) at clojure.lang.Compiler.loadFile(Compiler.java:5821) at clojure.lang.RT$3.invoke(RT.java:296) at leiningen.core$read_project$fn__2167.invoke(core.clj:127) at leiningen.core$read_project.invoke(core.clj:126) at leiningen.core$read_project.invoke(core.clj:130) at leiningen.core$_main.doInvoke(core.clj:320) at clojure.lang.RestFn.invoke(RestFn.java:410) at clojure.lang.AFn.applyToHelper(AFn.java:161) at clojure.lang.RestFn.applyTo(RestFn.java:132) at clojure.core$apply.invoke(core.clj:542) at leiningen.core$_main.invoke(core.clj:332) at user$eval73.invoke(NO_SOURCE_FILE:1) at clojure.lang.Compiler.eval(Compiler.java:5425) at clojure.lang.Compiler.eval(Compiler.java:5392) at clojure.core$eval.invoke(core.clj:2382) at clojure.main$eval_opt.invoke(main.clj:235) at clojure.main$initialize.invoke(main.clj:254) at clojure.main$script_opt.invoke(main.clj:270) at clojure.main$main.doInvoke(main.clj:354) at clojure.lang.RestFn.invoke(RestFn.java:457) at clojure.lang.Var.invoke(Var.java:377) at clojure.lang.AFn.applyToHelper(AFn.java:172) at clojure.lang.Var.applyTo(Var.java:482) at clojure.main.main(main.java:37) Caused by: java.lang.ClassNotFoundException: org.clojure at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:61) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:270) at clojure.lang.RT.classForName(RT.java:1566) at clojure.lang.Compiler$HostExpr.maybeClass(Compiler.java:852) at clojure.lang.Compiler$HostExpr.access$300(Compiler.java:654) at clojure.lang.Compiler.analyzeSymbol(Compiler.java:5572) at clojure.lang.Compiler.analyze(Compiler.java:5173) ... 41 more Thanks for your help Andy -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit
Re: Do web apps need Clojure?
this. The ease of which data can be mangled and transformed was the primary reason I chose Clojure over Java, Groovy and Scala. That, and the fact the language is just so darn expressive. On Thursday, November 14, 2013 8:56:59 AM UTC, Islon Scherer wrote: For me it's about 1 thing: Data. A web application is about taking data from the user, transform it and store it on the database and take data from the database, transform it and show it to the user. Clojure is the best language I used to work with data, it just gives you a composable set of tools and then get out of your way, and there's always macros for the more complex use cases. We have a web application that serves edn data to our clojurescript frontend, our webdevelopers created a new site for mobile in backbone.js that used json, I had just to create a function (ring middleware) that transformed my edn data to json based on the accept header. My 2¢ On Thursday, November 14, 2013 9:11:04 AM UTC+1, Bastien Guerry wrote: Marcus Blankenship mar...@creoagency.com writes: Brian, that’s really interesting. I think we’re seeing something similar, and are going to look at Pedestal and Caribou as options for a project we’re working on. Are their others we should consider? Perhaps you should consider starting from scratch, in parallel. Maybe that's because I'm a beginner in both the language and in web development, but so far I've found it's the best way to understand the choices behind framaworks. Otherwise I would confuse web development with those choices, and I feel the richness of the Clojure ecosystem is precisely to open your mind about web development. 2 cents, -- Bastien -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Padding missing elements in a sequence of identical K/V maps
Thanks all. This just highlights one of the nice things about Clojure to me - the code gets out of the way to allow the algorithm to shine through. Lovely. By the way, this implementation is closest to my initial although I didn't use juxt at the repl, but I did lose my repl history and can't recall what I did. For me personally, I am learning with each new post so please keep them coming! On Wednesday, November 20, 2013 1:26:43 AM UTC, Joshua Ballanco wrote: In an attempt to be slightly more elegant (whatever that means ;-) ): -8-8- (def start [{:key 3 :value 10} {:key 6 :value 30}]) (into [] (map (fn [[k v]] {:key k :value v}) (merge (into {} (for [x (range 6)] {x nil})) (into {} (map (juxt :key :value) start) ;;= [{:key 6, :value 30} {:key 0, :value nil} {:key 1, :value nil} {:key 2, :value nil} {:key 3, :value 10} {:key 4, :value nil} {:key 5, :value nil}] -8-8- Cheers, Josh On Tuesday, November 19, 2013 at 2:00 PM, Jim - FooBar(); wrote: On 19/11/13 11:29, Colin Yates wrote: In Java I would do something like: // create a convenient look up to avoid nasty N^2 lookups MapObject, Object keyToValue = new HashMap for (MapObject, Object kvMap: kvSequence) keyToValue.put(kvMap.get(key), kvMap.put(value)); ListObject allKeys = calculateAllKeys(); ListMapObject, Object results = new Array for (Object key: allKeys) Object result = keyToValue.get(key); // null is fine for missing keys results.put(key, result); return results; this code doesn't do any sorting of keys so I'm not sure it would give you the exact desired result you posted... Jim -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript:(mailto: clo...@googlegroups.com javascript:) Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: (mailto: clojure+u...@googlegroups.com javascript:) 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript: (mailto: clojure+u...@googlegroups.com javascript:). For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: java.jdbc DSLs (java.jdbc.sql / java.jdbc.ddl)
Hi Sean, First - I hugely appreciate the work you have done and use java.jdbc daily. However, as a complete newbie I found the included DSL very unhelpful. The java.jdbc API is very wide and navigating it was hard, Particularly as it was in a transition from using bound *db* to not, so effectively there seemed two APIs. I started using the DSL and it didn't meet the expectation I think anybody would have for a DSL in that it wasn't complete or expressive enough. There were moments where the combined experience was very very negative and not representative of the quality of the work you have put in. It also made it unclear what the library was supposed to do (regardless of what the documentation says :)). Treating java.jdbc without the DSL and the DSL as separate projects (I realise they are separate namespaces already) would be a much stronger statement of intent I think. To put it another way, at the moment the risk is to interpret java.jdbc as a DSL on top of JDBC with some low level utilities around managing connections. That clearly isn't true and the project comes off looking very poor. Please hear me - I write this only because I think my experience will be very similar to a lot of other people's experiences when they start adopting the library whilst picking up Clojure at the same time! For me, the combination of honeysql and java.jdbc is close to perfect, but my point again is that I came very close many times to throwing java.jdbc out because of the experience of a very wide API which was effectively two APIs and a DSL which didn't meet a reasonable definition of a full 'DSL' (even if the documentation states it is minimal). Moving the DSL into a separate project makes things much simpler. Just my 2 pennies from a very grateful user who wants to avoid other people missing the point. Col On Wednesday, November 20, 2013 3:05:34 AM UTC, Sean Corfield wrote: In response to the (very reasonable) question from Alex Hudek in a recent thread, here are some of my responses to questions that have arisen about the inclusion of the minimal DSLs in the java.jdbc contrib library: Just wondering if the intention is to make the DSL the primary way to work with the API or if clojure.java.jdbc.sql will be completely optional? Completely optional. The idea is just to provide some (optional) sugar for common operations. I have no intention of going particularly deep on the DSL. If folks want a full DSL for SQL in Clojure, I'd suggest https://github.com/jkk/honeysql or http://sqlkorma.com - the former is a DSL to generate SQL that is compatible with clojure.java.jdbc, the latter is a DSL that wraps clojure.java.jdbc. Using the latest release of java.jdbc, does anybody know how I can construct a where clause when I want to check if the value is one of many values? clojure.java.jdbc.sql is a deliberately minimal DSL - Justin Kramer's HoneySQL is what I recommend for more expressive SQL construction (that's the official recommendation based on discussions Justin and I had about java.jdbc and HoneySQL at Clojure/conj 2012). I want to generate sql string using clojure.java.jdbc.sql for eg. SELECT B.ID , B.TITLE ,B.AUTHOR , C.CATEGORY , S.STATUS FROM BOOK B ,CATEGORY C , STATUS S WHERE (B.CATEGORY_ID=C.ID) AND (B.STATUS_ID = B.ID) AND (B.TITLE LIKE %TOM%) How to do this using clojure.java.jdbc.sql dsl functions? The basic DSL cannot do 'like' so you probably want to look at HoneySQL which is the recommended way to extend clojure.java.jdbc. === The justification for the DSL at all is that it provides some sugar for simple, common usage and also provides a template for other more expansive DSLs that the community might write, by showing what the primary API expects in terms of SQL strings and parameter vectors. At World Singles, we use the basic DSL to support a lot of CRUD operations that are doing simple lookups, basic joins, and so on - and we rely on HoneySQL for our reporting queries and anything that is substantially more complex than the basic DSL offers. Will the DSL be expanded to support some additional common SQL operations? Perhaps, based on user feedback - assuming people want something between raw strings and the sophistication of HoneySQL (or any other DSL that the community may produce). -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to
Re: java.jdbc DSLs (java.jdbc.sql / java.jdbc.ddl)
Perfect. --- Original Message --- From: Sean Corfield seancorfi...@gmail.com Sent: 24 November 2013 05:26 To: clojure@googlegroups.com Subject: Re: java.jdbc DSLs (java.jdbc.sql / java.jdbc.ddl) On Sat, Nov 23, 2013 at 8:27 PM, Keith Irwin ke...@devtrope.com wrote: Personally, the DSL doesn’t bother me at all. (Just a data point.) I get where you’re going with it, and support the idea, FWIW, but if it were gone, I wouldn’t notice. My needs are 1) so simple, strings work, or 2) so complicated, a (or any) DSL is just extra headache. (Reading them out of a separately maintained data file, for instance, is one way to go.) Thank you. The mixture of the old API and the new API is problematic, mainly because it’s difficult for me (anyway) to look down the list of functions and figure out which are old and which are new. I agree. Might you be able to publish a parallel version of the API *documentation* with all the deprecated stuff removed for those folks new to the library who are uninterested in the old API? Even users of the old API might appreciate it for the same reasons. I think, given that I am retiring the DSL namespaces and making them available in a separate project (that change is already committed, although the docstrings have yet to catch up), the least confusing thing to do at this point for 0.3.0-beta2 onward will be to create a java.jdbc.deprecated namespace containing the entirety of the 0.2.3 API and remove all of the deprecated functions from java.jdbc itself? That would clearly separate the API documentation into two namespaces: one the modern API going forward, one the deprecated API provided for backward compatibility. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/4vx6rlBdrX8/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Good learning resources for Clojure novice but with a long background i programming, both OO and some Fp?
For me (a similarly entrenched OO guy) I found it very challenging. Nothing to do with the syntax, but you are moving from a world of locked up bits of data behind a (hopefully) impenetrable API to a world full of lightweight data with a myriad of tiny functions which pretty much all perform data transformations. Let your data free! is the battle cry it seems. After a number of years people start to become unconsciously competent which is where the pain lives - you need to deconstruct your intuition and gut feel, figure out the decisions you are taking and then challenge them. At least for me I found a lot of the intuitively good solutions were actually quite poor when compared to the benefits and freedom FP brings. They were still good solutions/implementations in the locked down Java land, but not over in FP land. This is particularly prevalent because a lot of people don't separate out 'design' and 'implementation'. Does the solution require encapsulation? Yep, but that doesn't mean reaching for a class (or protocols or multi-methods for that matter). And so on. For me, forcing myself to learn Clojure (and Scala before hand) has made me a much better developer in general, even when working on OO implementations. It is worth mentioning that 99% of the battle is changing the way you think, it has little to do with the tools. Go watch every single Rich Hickey video. Go watch them again. Particularly the simple made easy and the one where he talks about time. Pick up a really simple 'Clojure syntax' book or tutorial and then read 'Joy of Clojure'. Now read through the core API. You need to internalise that API and the code is pretty idiomatic (arguably by definition given the authors). Keep going though - it really really is worth it. On Friday, 10 January 2014 12:52:53 UTC, christian jacobsen wrote: I have +10 years experience of OO programming (C++, C# and a little Java) and a couple of years of FP programming (mainly F#, some Scala and a little Haskell). Are there any resources for learning Clojure that are particular good for someone with the above background? -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
How can I improve this?
I have a sequence of file names and I want to make them unique. (uniquify [a b c a]) = [a b c a_1]) This is what I have come up with, but surely there is a better way? What would you all do? Feedback welcome (including the word 'muppet' as I am sure I have missed something simple) :) (defn uniquify Return a sequence, in the same order as s containing every element of s. If s (which is presumed to be a string) occurs more than once then every subsequent occurrence will be made unique. Items will be updated to include an incrementing numeric count using the specified formatter function. The formatter function will be given the name and the number and should return a combination of the two. The set of unique s's in the returned sequence will be the count of s's in s. ([s] (uniquify s (fn [item duplicates] (str item _ duplicates ([s formatter] (let [occurrences (atom {}) register-occurrence (fn [item] (if (get @occurrences item) (swap! (get @occurrences item) inc) (swap! occurrences assoc item (atom 1))) @(get @occurrences item)) process (fn [item] (let [duplicates (dec (register-occurrence item))] (if ( duplicates 0) (formatter item duplicates) item))) unique-s (map process s)] unique-s))) -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
RE: How can I improve this?
The missing context is that distinct removes duplicates, I want duplicates to be made unique by changing them in some way: (uniquify [a b c a]) = [a b c a_1]) *not* (uniquify [a b c a]) = [a b c]) Not sure what else to put that isn't in the original post to be honest... Date: Fri, 10 Jan 2014 07:10:22 -0800 Subject: Re: How can I improve this? From: grd...@gmail.com To: clojure@googlegroups.com Hi Colin, Clojure has a distinct function that does this. I may be missing some context on what you what out of your new method that 'distinct' does not provide. The distinct functions source code is a good reference. Thanks On Fri, Jan 10, 2014 at 6:59 AM, Colin Yates colin.ya...@gmail.com wrote: I have a sequence of file names and I want to make them unique. (uniquify [a b c a]) = [a b c a_1]) This is what I have come up with, but surely there is a better way? What would you all do? Feedback welcome (including the word 'muppet' as I am sure I have missed something simple) :) (defn uniquify Return a sequence, in the same order as s containing every element of s. If s (which is presumed to be a string) occurs more than once then every subsequent occurrence will be made unique. Items will be updated to include an incrementing numeric count using the specified formatter function. The formatter function will be given the name and the number and should return a combination of the two. The set of unique s's in the returned sequence will be the count of s's in s.([s] (uniquify s (fn [item duplicates] (str item _ duplicates ([s formatter] (let [occurrences (atom {}) register-occurrence (fn [item] (if (get @occurrences item) (swap! (get @occurrences item) inc) (swap! occurrences assoc item (atom 1))) @(get @occurrences item)) process (fn [item] (let [duplicates (dec (register-occurrence item))] (if ( duplicates 0) (formatter item duplicates) item))) unique-s (map process s)] unique-s))) -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/rt-l_X3gK-I/unsubscribe. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How can I improve this?
Good call. I keep discounting reduce as I am not 'reducing' anything, only transforming (i.e. map) it - my mistake. Thanks. Col On Friday, 10 January 2014 15:12:27 UTC, Alex Miller wrote: I would not use an atom. Think about it as doing a reduce while passing along a set of the names you've seen so far. You might also look at the implementation of distinct in clojure.core which is similar (you want to detect duplicates in the same way, but emit new names instead of omitting dupes). On Friday, January 10, 2014 8:59:10 AM UTC-6, Colin Yates wrote: I have a sequence of file names and I want to make them unique. (uniquify [a b c a]) = [a b c a_1]) This is what I have come up with, but surely there is a better way? What would you all do? Feedback welcome (including the word 'muppet' as I am sure I have missed something simple) :) (defn uniquify Return a sequence, in the same order as s containing every element of s. If s (which is presumed to be a string) occurs more than once then every subsequent occurrence will be made unique. Items will be updated to include an incrementing numeric count using the specified formatter function. The formatter function will be given the name and the number and should return a combination of the two. The set of unique s's in the returned sequence will be the count of s's in s. ([s] (uniquify s (fn [item duplicates] (str item _ duplicates ([s formatter] (let [occurrences (atom {}) register-occurrence (fn [item] (if (get @occurrences item) (swap! (get @occurrences item) inc) (swap! occurrences assoc item (atom 1))) @(get @occurrences item)) process (fn [item] (let [duplicates (dec (register-occurrence item))] (if ( duplicates 0) (formatter item duplicates) item))) unique-s (map process s)] unique-s))) -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How can I improve this?
Love it. Much more readable without any nasty persistent state. On Friday, 10 January 2014 15:19:03 UTC, Ray Miller wrote: On 10 January 2014 14:59, Colin Yates colin...@gmail.com javascript:wrote: I have a sequence of file names and I want to make them unique. (uniquify [a b c a]) = [a b c a_1]) This is what I have come up with, but surely there is a better way? I would do something like: (defn uniquify ([xs] (uniquify xs (fn [x n] (str x _ n ([xs formatter] (letfn [(uniquify* [xs seen] (lazy-seq (when (not-empty xs) (let [x (first xs) n (seen x 0)] (if ( n 0) (cons (formatter x n) (uniquify* (rest xs) (assoc seen x (inc n (cons x (uniquify* (rest xs) (assoc seen x (inc n)] (uniquify* xs {} -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How can I improve this?
I did consider that but I want to preserve the order of the incoming sequence. On Friday, 10 January 2014 15:22:29 UTC, Laurent PETIT wrote: Hi, Use frequencies to get a map of path = nb of occurrences, then for each entry of the map, create unique names. Cannot provide an impl on the uPhine, sorry Le vendredi 10 janvier 2014, Colin Yates a écrit : I have a sequence of file names and I want to make them unique. (uniquify [a b c a]) = [a b c a_1]) This is what I have come up with, but surely there is a better way? What would you all do? Feedback welcome (including the word 'muppet' as I am sure I have missed something simple) :) (defn uniquify Return a sequence, in the same order as s containing every element of s. If s (which is presumed to be a string) occurs more than once then every subsequent occurrence will be made unique. Items will be updated to include an incrementing numeric count using the specified formatter function. The formatter function will be given the name and the number and should return a combination of the two. The set of unique s's in the returned sequence will be the count of s's in s. ([s] (uniquify s (fn [item duplicates] (str item _ duplicates ([s formatter] (let [occurrences (atom {}) register-occurrence (fn [item] (if (get @occurrences item) (swap! (get @occurrences item) inc) (swap! occurrences assoc item (atom 1))) @(get @occurrences item)) process (fn [item] (let [duplicates (dec (register-occurrence item))] (if ( duplicates 0) (formatter item duplicates) item))) unique-s (map process s)] unique-s))) -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How can I improve this?
This and Jonas' are my current favourites, for what that's worth. Keep the suggestions coming! On Friday, 10 January 2014 17:29:20 UTC, Laurent PETIT wrote: What about this one? Inspired by Stefan's, with more destructuring in loop, format-fn as a function, initial call to (seq) then (next) instead of (rest), placing the exit argument first so that it's not lost at the end of the function, renamed word as item since this function does not depend on the type of items. (defn uniquify [in format-fn] (loop [[item :as in] (seq in) {n item :as item-nbrs} {} out []] (if-not in out (let [format-fn (if n format-fn (constantly item))] (recur (next in) (update-in item-nbrs [item] (fnil inc 0)) (conj out (format-fn item n))) 2014/1/10 Laurent PETIT lauren...@gmail.com javascript: no you have a bug in this last version, it now skips the last result 2014/1/10 Stefan Kanev stefan...@gmail.com javascript: Somehow I totally forgot I could use destructuring. Here's a slightly shorter version: (defn uniquify [words] (loop [encountered {} result [] [word remaining] words] (if (seq remaining) (let [occurences (get encountered word) modified (if occurences (str word _ occurences) word)] (recur (update-in encountered [word] (fnil inc 0)) (conj result modified) remaining)) result))) -- Stefan Kanev ¦ @skanev ¦ http://skanev.com/ You can measure a programmer's perspective by noting his attitude on the continuing vitality of FORTRAN. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Good learning resources for Clojure novice but with a long background i programming, both OO and some Fp?
At the risk of self promotion*, have a read of https://groups.google.com/d/msg/clojure/rt-l_X3gK-I/K80axT77XzwJ - it is an excellent example of iterative compared to functional. You can see at least 4 distinct approaches to solving a fairly straight forward problem. It is a startlingly clear example of how elegant Clojure can become. * it isn't self promotion at all! It is self deprecation - my solution is clearly lame, hence the original post :). On Friday, 10 January 2014 12:52:53 UTC, christian jacobsen wrote: I have +10 years experience of OO programming (C++, C# and a little Java) and a couple of years of FP programming (mainly F#, some Scala and a little Haskell). Are there any resources for learning Clojure that are particular good for someone with the above background? -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How can I improve this?
way to take the wind out of our sails! Well spotted :). On Friday, 10 January 2014 19:39:45 UTC, puzzler wrote: Technically, all these solutions are flawed. With the input [a a a_1] you'll get back [a a_1 a_1] To truly address this, you need to also add the newly formatted filename into the seen map, which none of the suggested solutions do. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How can I improve this?
I thought I would have a go myself without copying (although having read them earlier) the other functions and this is what I came up with: (first (reduce (fn [[results seen] item] (let [occurrences ((fnil identity 0) (get seen item)) seen (assoc seen item (inc occurrences)) item (if ( occurrences 0) (format-fn item occurrences) item)] [(conj results item) seen])) [[] {}] (seq items))) This doesn't solve the problem you mention, but baby steps. Being really anal I could claim the original a_2 should remain a_2 and the third instance of a jump to being a_3. I thought about this and couldn't see how to do this with reduce because I really want to say oh, I have a new name, recurse into the function again with the new proposed name, i.e. loop the generation of the proposed name until it is unique, but I haven't got that far yet (without potentially blowing the stack!) Then I saw your 'recur' used outside of a loop which points the way... Thanks! On Friday, 10 January 2014 20:16:28 UTC, puzzler wrote: On Fri, Jan 10, 2014 at 11:52 AM, Colin Yates colin...@gmail.comjavascript: wrote: way to take the wind out of our sails! Well spotted :). It's not too hard to fix. Here's an adapted version of Jonas' solution that should do the trick: (defn uniqueify [items] (first (reduce (fn [[results count-map] item] (let [n (count-map item 0)] (if (zero? n) [(conj results item) (assoc count-map item (inc n))] (recur [results (assoc count-map item (inc n))] (str item \_ n) [[] {}] items))) = (uniqueify [a a a a b a_2 a_3 a_3_1 a_3_1 a]) [a a_1 a_2 a_3 b a_2_1 a_3_1 a_3_1_1 a_3_1_2 a_4] -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How can I improve this?
Gosh - my public humiliation continues. Here is one that actually works: (first (reduce (fn [[results seen] item] (let [cnt (get seen item 0)] [(conj results (if ( cnt 0) (format-fn item cnt) item)) (assoc seen item (inc cnt))])) [[] {}] items)) (fact strings can be made unique (s/uniquify [a b c]) = [a b c] (s/uniquify [a b a c b b b b a]) = [a b a_1 c b_1 b_2 b_3 b_4 a_2]) On Friday, 10 January 2014 20:59:00 UTC, Colin Yates wrote: Sorry - wrong c/p: (first (reduce (fn [[results seen] item] (let [cnt (get seen item 0) item (if ( cnt 0) (format-fn item cnt) item)] [(conj results item) (assoc seen item (inc cnt))])) [[] {}] items)) On Friday, 10 January 2014 20:55:04 UTC, Colin Yates wrote: I thought I would have a go myself without copying (although having read them earlier) the other functions and this is what I came up with: (first (reduce (fn [[results seen] item] (let [occurrences ((fnil identity 0) (get seen item)) seen (assoc seen item (inc occurrences)) item (if ( occurrences 0) (format-fn item occurrences) item)] [(conj results item) seen])) [[] {}] (seq items))) This doesn't solve the problem you mention, but baby steps. Being really anal I could claim the original a_2 should remain a_2 and the third instance of a jump to being a_3. I thought about this and couldn't see how to do this with reduce because I really want to say oh, I have a new name, recurse into the function again with the new proposed name, i.e. loop the generation of the proposed name until it is unique, but I haven't got that far yet (without potentially blowing the stack!) Then I saw your 'recur' used outside of a loop which points the way... Thanks! On Friday, 10 January 2014 20:16:28 UTC, puzzler wrote: On Fri, Jan 10, 2014 at 11:52 AM, Colin Yates colin...@gmail.comwrote: way to take the wind out of our sails! Well spotted :). It's not too hard to fix. Here's an adapted version of Jonas' solution that should do the trick: (defn uniqueify [items] (first (reduce (fn [[results count-map] item] (let [n (count-map item 0)] (if (zero? n) [(conj results item) (assoc count-map item (inc n))] (recur [results (assoc count-map item (inc n))] (str item \_ n) [[] {}] items))) = (uniqueify [a a a a b a_2 a_3 a_3_1 a_3_1 a]) [a a_1 a_2 a_3 b a_2_1 a_3_1 a_3_1_1 a_3_1_2 a_4] -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Any libraries for creating Powerpoint and Excel files
Hi all, Any one broken that ground before? Thanks, Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Any libraries for creating Powerpoint and Excel files
Cheers Ragnar. On Wednesday, 15 January 2014 10:00:12 UTC, Ragnar Dahlén wrote: Hi Colin, For Excel, there's docjure (https://github.com/ative/docjure) which provides a quite nice interface to Apache POIs (http://poi.apache.org/) Excel capabilities. Apache POI also has support for Power Point, but I don't know to what extent. Ragnar On Wednesday, 15 January 2014 09:08:09 UTC, Colin Yates wrote: Hi all, Any one broken that ground before? Thanks, Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How to organize clojure functions? A clojure newbie here...
I think the right (or maybe idiomatic is a better word) organisation is an effect of a very important cause - changing the way you think about a software system. Simplistically, OO promises to be a world full of chunks of knowledge and behaviour that politely ask other chunks to behave in a certain way. You have relatively narrow but very deep 'shapes' as levels of abstraction increase. Realistically we all know how that goes :). In FP the form the structure of the knowledge itself is your primary chunk with a many little chunks of functionality that all know how to transform one shape to another. You have a relatively wide and shallow 'shapes' that all work on a few core chunks of knowledge (i.e. state). To put it another way, I find it really helpful in Clojure to phrase the question 'what shape data do I need and which transformations are necessary'. It isn't quite on its head, but close. You can absolutely still address encapsulation, domain abstractions etc. (http://thinkrelevance.com/blog/2009/08/12/rifle-oriented-programming-with-clojure-2) but start with the shapes of knowledge. All of the above is incredibly simplistic, 'wrong' for some definition of wrong but it is something I wish somebody had told me when I was first starting out :). On Monday, 3 February 2014 08:47:09 UTC, Aravindh S wrote: Hi All, I am new to clojure and have been working with the language for the past one week. I have got a basic hold of the constructs in clojure. I have been programming for 4 years in C# now. One thing I am not able to comprehend is how clojure programs are structured. In an OO world, I know what are the entities that the program should have, how they will be related etc. I am not able to do the same wit clojure. I agree that words like classes, methods dont make much sense in functional programming. I am precisely looking for a program written in clojure ( A medium level program say about 200 - 300 LOC) which clearly tells how a problem domain should be approached in a functional manner using clojure, how the functions should be organized. A specific solution for specific problem will be helpful. Thanks Aravindh.S -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Coverage tools in Clojure
I don't know. But maybe the lack of coverage tools is itself interesting? My (not quite formed/making this up as I go) view is that maybe coverage tools are there to address the implicit complexity in other mainstream languages and/or to help mitigate the risk of the potentially large and hard-to-identify 'impact analysis' you get in OO systems when you change state. In other words, coverage is necessary because we want to feel safe that all combinations of our code are extensively tested. Why don't we feel safe? Because the system is hard to reason about. Functional programming on the other hand is full of much smaller discrete and independent chunks of functionality. Ideally these small focused 'bricks' are pure/referentially transparent so the *only* context you need when reasoning about them is their parameters and the logic inside. Assembling these bricks introduces interactions that need to be tested, sure, but there are very few 'call this and watch the change cascade'/'this code is sensitive (i.e. coupled) to that data over there'. My ramblings are to say, maybe the root cause of coverage tools is to solve a problem (hard to reason about systems) which shouldn't be much less of a problem in FP when FP is done right. OO + mutable state = hard to reason about. FP + immutable state + pure/referentially transparent functions = much easier to reason about. Or not. Just my 2 pence :). On Sunday, 2 February 2014 21:34:29 UTC, Aaron France wrote: Hi, I'm looking for coverage reporting in Clojure. I've been using Cloverage[1] but I'm just wondering if there are any other coverage tools? Aaron [1] https://github.com/lshift/cloverage -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Coverage tools in Clojure
Comments in line. On Tuesday, 4 February 2014 11:23:36 UTC, Aaron France wrote: I don't want to seem rude but I think you've drank a bit too much kool-aid. You know the phrase I don't want to seem rude doesn't actually do anything right? :) To say that functional programming and war against state means that your application doesn't need to be tested thoroughly is a joke. And a very bad one. I agree, but who is saying that? I certainly didn't cover how much testing is necessary. I thoroughly test my Clojure systems using midje, which regularly rocks my world. My point is that the coverage is much *much* easier to reason about in FP than in OO (for the reasons I gave). Coverage doesn't just aid you in seeing which parts of state caused which branches to be hit, it also gives you notice if there are any logical errors in your code which cause the branches to not be hit. And why are those logical errors which cause the branches to not be hit not immediately obvious? Why do you need a tool to tell you that? I know my Clojure code has around 100% coverage using white box testing for the functions and mocking the interactions. I would challenge you to put ego/emotion to one side, stop finding non-existent points to argue against and re-read my post. By all means come back and justify why all the points I raised which reduce the need for coverage are invalid. Don't attribute stupid statements (like 'FP doesn't need testing') to me - I can come up with my own stupid statements thank you. If it helps, my stand point is from 20 years of building non-trivial Enterprise applications (primarily Java) using the current best of breed technology stacks (i.e Spring/Hibernate/AspectJ) with the best of breed process (agile, TDD, DBC, BDD, most other TLAs etc.). Using Clojure for the past year or so has opened my eyes to exactly how many problems we solve, and infrastructure we use is to pamper to complexity introduced by the tool-chain not the problem domain. I am suggesting maybe coverage tools are one of those. Aaron On Tue, Feb 04, 2014 at 03:19:05AM -0800, Colin Yates wrote: I don't know. But maybe the lack of coverage tools is itself interesting? My (not quite formed/making this up as I go) view is that maybe coverage tools are there to address the implicit complexity in other mainstream languages and/or to help mitigate the risk of the potentially large and hard-to-identify 'impact analysis' you get in OO systems when you change state. In other words, coverage is necessary because we want to feel safe that all combinations of our code are extensively tested. Why don't we feel safe? Because the system is hard to reason about. Functional programming on the other hand is full of much smaller discrete and independent chunks of functionality. Ideally these small focused 'bricks' are pure/referentially transparent so the *only* context you need when reasoning about them is their parameters and the logic inside. Assembling these bricks introduces interactions that need to be tested, sure, but there are very few 'call this and watch the change cascade'/'this code is sensitive (i.e. coupled) to that data over there'. My ramblings are to say, maybe the root cause of coverage tools is to solve a problem (hard to reason about systems) which shouldn't be much less of a problem in FP when FP is done right. OO + mutable state = hard to reason about. FP + immutable state + pure/referentially transparent functions = much easier to reason about. Or not. Just my 2 pence :). On Sunday, 2 February 2014 21:34:29 UTC, Aaron France wrote: Hi, I'm looking for coverage reporting in Clojure. I've been using Cloverage[1] but I'm just wondering if there are any other coverage tools? Aaron [1] https://github.com/lshift/cloverage -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- You 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
Re: Lessons Learned from Adopting Clojure
Is there going to be online access during/after the event? I would greatly value seeing this, but probably not enough to travel from the UK to Chicago :). On Tuesday, 4 February 2014 12:06:06 UTC, Jay Fields wrote: tl; dr: I'm presenting Lessons Learned from Adopting Clojure in Chicago on Feb 11th: http://www.eventbrite.com/e/goto-night-with-jay-fields-tickets-10366768283?aff=eorgf Five years ago DRW Trading was primarily a Java shop, and I was primarily developing in Ruby. Needless to say, it wasn't a match made in heaven. Fast forward five years, Clojure is the second most used language in the firm, and the primary language for several teams (including mine). Clojure wasn't the first language that I've introduced to an organization; however, it's unquestionably the most successful adoption I've ever been a part of. The use of Clojure has had many impacts on the firm: culturally, politically, and technically. My talk will discuss general ideas around language selection and maintenance trade-offs, and specific examples of what aspects of Clojure made it the correct choice for us. A few highlights - Where to first introduce a new language and your role as the language care-taker. - REPL driven development, putting TDD's 'rapid feedback' to shame. - Operations impact of adding a language - i.e. get ready for some DevOps. - Functional programming, the Lisp Advantage, and their impact on maintainability. Of course, no good experience report is all roses. The adoption has seen several hurdles along the way, and I'll happily to describe those 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Coverage tools in Clojure
+1 I still force myself to write those tests simply for the confidence they give me in replacing my hack with idiomatic code as I/colleagues get more familiar down the road. I can absolutely see dramatically reducing the number of 'safety rails' type tests pretty soon; most of the code uses the core abstractions. It is quite humbling/interesting how little new code I actually need to write as oppose to picking one/assembling some off the shelf. On Tuesday, 4 February 2014 12:22:57 UTC, Gary Trakhman wrote: In clojure, generally I've found Unit-tests are often significantly harder to write than the corresponding implementing code, idiomatic code rarely has silly problems, and integration tests are enough to shake out bad behavior. So, the end result is constraining our codebase at API boundaries with integration tests does pretty well, and unit tests are most likely to get written only when I'm doing something weird and nasty. On Tue, Feb 4, 2014 at 7:14 AM, Korny Sietsma ko...@sietsma.comjavascript: wrote: My 2c - on my last project it would have been handy to have some test coverage tools, they can be useful to sanity check your testing. However, it's worth noting that compared to a java project, we had far fewer lines of code, so manually reviewing code for tests was a lot easier. And there were cases where some careful integration tests were more useful than unit testing everything, which ties in to Colin's point I think. And integration tests tend to break coverage metrics. (and I'm not sure how you'd do coverage for macros, but that's probably a digression) - Korny On 4 Feb 2014 11:23, Aaron France aaron.l...@gmail.com javascript: wrote: I don't want to seem rude but I think you've drank a bit too much kool-aid. To say that functional programming and war against state means that your application doesn't need to be tested thoroughly is a joke. And a very bad one. Coverage doesn't just aid you in seeing which parts of state caused which branches to be hit, it also gives you notice if there are any logical errors in your code which cause the branches to not be hit. Aaron On Tue, Feb 04, 2014 at 03:19:05AM -0800, Colin Yates wrote: I don't know. But maybe the lack of coverage tools is itself interesting? My (not quite formed/making this up as I go) view is that maybe coverage tools are there to address the implicit complexity in other mainstream languages and/or to help mitigate the risk of the potentially large and hard-to-identify 'impact analysis' you get in OO systems when you change state. In other words, coverage is necessary because we want to feel safe that all combinations of our code are extensively tested. Why don't we feel safe? Because the system is hard to reason about. Functional programming on the other hand is full of much smaller discrete and independent chunks of functionality. Ideally these small focused 'bricks' are pure/referentially transparent so the *only* context you need when reasoning about them is their parameters and the logic inside. Assembling these bricks introduces interactions that need to be tested, sure, but there are very few 'call this and watch the change cascade'/'this code is sensitive (i.e. coupled) to that data over there'. My ramblings are to say, maybe the root cause of coverage tools is to solve a problem (hard to reason about systems) which shouldn't be much less of a problem in FP when FP is done right. OO + mutable state = hard to reason about. FP + immutable state + pure/referentially transparent functions = much easier to reason about. Or not. Just my 2 pence :). On Sunday, 2 February 2014 21:34:29 UTC, Aaron France wrote: Hi, I'm looking for coverage reporting in Clojure. I've been using Cloverage[1] but I'm just wondering if there are any other coverage tools? Aaron [1] https://github.com/lshift/cloverage -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated
Re: Coverage tools in Clojure
This has turned into an unconstructive argument and for whatever reason we don't seem to be communicating clearly. Shame as I (and probably most people on here) only want to help. You seem to be reacting quite strongly to my thoughts - not sure why. If I may, I will just make/rephrase two points: - I think you would find value in watching Rick Hickey's videos on Simple Made Easy and also the one where he talks about Hammock Driven Development. - when I started using Clojure I immediately looked for equivalents of all the supporting infrastructure I used in good old Java land. I have no idea of your situation, but if you are there you have a wonderful opportunity to re-examine and build up a whole new toolchain/approach to development that IME is significantly lighter and more powerful. Peace. On Tuesday, 4 February 2014 13:49:49 UTC, Aaron France wrote: On Tue, Feb 04, 2014 at 04:18:30AM -0800, Colin Yates wrote: Comments in line. On Tuesday, 4 February 2014 11:23:36 UTC, Aaron France wrote: I don't want to seem rude but I think you've drank a bit too much kool-aid. You know the phrase I don't want to seem rude doesn't actually do anything right? :) I genuinely don't want to offend. People allow themselves to become vested in their viewpoint. If that has happened to you, I'm sorry. To say that functional programming and war against state means that your application doesn't need to be tested thoroughly is a joke. And a very bad one. I agree, but who is saying that? I certainly didn't cover how much testing is necessary. I thoroughly test my Clojure systems using midje, which regularly rocks my world. My point is that the coverage is much *much* easier to reason about in FP than in OO (for the reasons I gave). I'm not following how you translate this into information which explains how your system is being tested. Coverage doesn't just aid you in seeing which parts of state caused which branches to be hit, it also gives you notice if there are any logical errors in your code which cause the branches to not be hit. And why are those logical errors which cause the branches to not be hit not immediately obvious? Why do you need a tool to tell you that? I know my Clojure code has around 100% coverage using white box testing for the functions and mocking the interactions. And what's the harm in getting this information from an automated tool? With your 20 years industry knowledge you should know that you cannot rely on humans to think and act reliably. It's just not a good way to plan systems. *Especially* when it comes to asking someone how correct their system is. I would challenge you to put ego/emotion to one side, stop finding non-existent points to argue against and re-read my post. By all means come back and justify why all the points I raised which reduce the need for coverage are invalid. Don't attribute stupid statements (like 'FP doesn't need testing') to me - I can come up with my own stupid statements thank you. You hand waved the need to use tools such as coverage reports simply on the virtue of some hard to quantify statements. I find that unscientific. If it helps, my stand point is from 20 years of building non-trivial Enterprise applications (primarily Java) using the current best of breed technology stacks (i.e Spring/Hibernate/AspectJ) with the best of breed process (agile, TDD, DBC, BDD, most otherTLAs etc.). Arguments from authority mean nothing on the internet. Using Clojure for the past year or so has opened my eyes to exactly how many problems we solve, and infrastructure we use is to pamper to complexity introduced by the tool-chain not the problem domain. I am suggesting maybe coverage tools are one of those. Coverage helps nothing on its own. It's a tool to aid in knowing which aspects of your system remain untested. It's fine to *believe* you're testing 100% of your system, but how do you actually know this? If you wander into a codebase you're not familiar with, what's the coverage? How do you know you're hitting all codepaths? You just cannot know this without reading all the code and the tests. Coverage helps to discover this information. My point isn't to eschew all other forms of testing in favour of coverage reports but to use them in tandem with the others to aid me in *knowing* which parts of the system are being tested and which are not. Aaron Aaron On Tue, Feb 04, 2014 at 03:19:05AM -0800, Colin Yates wrote: I don't know. But maybe the lack of coverage tools is itself interesting? My (not quite formed/making this up as I go) view is that maybe coverage tools are there to address the implicit complexity in other mainstream languages and/or to help mitigate the risk
Re: Coverage tools in Clojure
I have no idea why you aren't gushing. I'm not gushing, and haven't gushed about anything technical for years because everything is a trade off and has its own compromises/ceremony. I can see (and highly value) the benefits of Clojure, sure. If you want to write of my point of view as 'gushing' and not bother to read it correctly then fine. However, what is your objective in posting your statement to a public forum if not to start an argument? If you insist on sending more flame bait/trying to get a rise then let's take this offline and keep this list low noise. My email address is colin full stop yates @ Google's mailing servers.com. On Tuesday, 4 February 2014 14:17:25 UTC, Aaron France wrote: I don't come from 'Java-land'. I'm primarily an Erlang developer, which already is a very similar language to Clojure. Perhaps this is why I'm not gushing about functional programming's panacea? Aaron On Tue, Feb 04, 2014 at 06:12:18AM -0800, Colin Yates wrote: This has turned into an unconstructive argument and for whatever reason we don't seem to be communicating clearly. Shame as I (and probably most people on here) only want to help. You seem to be reacting quite strongly to my thoughts - not sure why. If I may, I will just make/rephrase two points: - I think you would find value in watching Rick Hickey's videos on Simple Made Easy and also the one where he talks about Hammock Driven Development. - when I started using Clojure I immediately looked for equivalents of all the supporting infrastructure I used in good old Java land. I have no idea of your situation, but if you are there you have a wonderful opportunity to re-examine and build up a whole new toolchain/approach to development that IME is significantly lighter and more powerful. Peace. On Tuesday, 4 February 2014 13:49:49 UTC, Aaron France wrote: On Tue, Feb 04, 2014 at 04:18:30AM -0800, Colin Yates wrote: Comments in line. On Tuesday, 4 February 2014 11:23:36 UTC, Aaron France wrote: I don't want to seem rude but I think you've drank a bit too much kool-aid. You know the phrase I don't want to seem rude doesn't actually do anything right? :) I genuinely don't want to offend. People allow themselves to become vested in their viewpoint. If that has happened to you, I'm sorry. To say that functional programming and war against state means that your application doesn't need to be tested thoroughly is a joke. And a very bad one. I agree, but who is saying that? I certainly didn't cover how much testing is necessary. I thoroughly test my Clojure systems using midje, which regularly rocks my world. My point is that the coverage is much *much* easier to reason about in FP than in OO (for the reasons I gave). I'm not following how you translate this into information which explains how your system is being tested. Coverage doesn't just aid you in seeing which parts of state caused which branches to be hit, it also gives you notice if there are any logical errors in your code which cause the branches to not be hit. And why are those logical errors which cause the branches to not be hit not immediately obvious? Why do you need a tool to tell you that? I know my Clojure code has around 100% coverage using white box testing for the functions and mocking the interactions. And what's the harm in getting this information from an automated tool? With your 20 years industry knowledge you should know that you cannot rely on humans to think and act reliably. It's just not a good way to plan systems. *Especially* when it comes to asking someone how correct their system is. I would challenge you to put ego/emotion to one side, stop finding non-existent points to argue against and re-read my post. By all means come back and justify why all the points I raised which reduce the need for coverage are invalid. Don't attribute stupid statements (like 'FP doesn't need testing') to me - I can come up with my own stupid statements thank you. You hand waved the need to use tools such as coverage reports simply on the virtue of some hard to quantify statements. I find that unscientific. If it helps, my stand point is from 20 years of building non-trivial Enterprise applications (primarily Java) using the current best of breed technology stacks (i.e Spring/Hibernate/AspectJ) with the best of breed process (agile, TDD, DBC, BDD, most otherTLAs etc.). Arguments from authority mean nothing on the internet. Using Clojure for the past year or so has opened my eyes to exactly how many problems we solve
Re: Coverage tools in Clojure
I said that coverage tools answer a specific question; 'how much of my code is executed when I do this', where 'this' is typically running a set of tests. People use that answer to infer how 'safe' their system is because they equate test coverage and safety (which is often a flawed inference). In some environments there is so much incidental complexity that these metrics are hard to calculate by hand (mutating state, deep object hierarchies etc.). FP has a number of different design decisions which can significantly reduce that incidental complexity, so if a tool is still needed maybe the cause is somewhere else - too much coupling/not enough ignorance etc. I think we fundamentally come from different places as I do think you can trust people and I would choose a couple of decent engineers (although they are as rare as hen's teeth) without any tools over all the tools in the world. To be clear, I am not saying I don't see the need for code coverage, I am saying it should be much easier to keep track of code coverage in an FP system done well primarily due to the wonderfully low level of influence referential transparency gives you (for example). On the other hand I absolutely see the need for an automated tool in other environments because of the implicit complexity. If you thoroughly test all your code when you write it why do you need a tool to tell you you missed something? Again, note I am talking only about calculating test coverage and not about testing or how much there should be. Not sure how many ways I can say the same thing, but let's try one more; I never said it was Clojure automatically doing anything, I said it is possible for a good engineer to know the coverage and safety of their systems themselves in a well designed and implemented system. Some environments are full of complexity which make it heard, hence the need for a tool. I am not categorically saying I can't imagine a world where I would need said tool in a FP system, but my first question would be am I using a tool to solve a symptom of poor design. In terms of analysing a new system? When I was a consultant reviewing other's work the best tool I used was a whiteboard, a pen and their architect. I found that if their system *needed* a coverage tool the tests were probably so poorly written as to add very little value. I would genuinely like you/others to prove/disprove these points as this is an area I am still thinking/learning about (as evidenced by my first and last sentence in the original post) and would love to have a useful discussion. You haven't bought anything to the table other than little jibes and emotive statements unfortunately. Let's agree to disagree, and if you can resist having a dig on a public forum (feel free to continue over personal email) let's draw this to a close. On Tuesday, 4 February 2014 14:30:29 UTC, Aaron France wrote: I took issue with you maintaining that Clojure automatically somehow gives you insight into the coverage of your tests. Which it does not. You still maintain this. On Tue, Feb 04, 2014 at 06:28:51AM -0800, Colin Yates wrote: I have no idea why you aren't gushing. I'm not gushing, and haven't gushed about anything technical for years because everything is a trade off and has its own compromises/ceremony. I can see (and highly value) the benefits of Clojure, sure. If you want to write of my point of view as 'gushing' and not bother to read it correctly then fine. However, what is your objective in posting your statement to a public forum if not to start an argument? If you insist on sending more flame bait/trying to get a rise then let's take this offline and keep this list low noise. My email address is colin full stop yates @ Google's mailing servers.com. On Tuesday, 4 February 2014 14:17:25 UTC, Aaron France wrote: I don't come from 'Java-land'. I'm primarily an Erlang developer, which already is a very similar language to Clojure. Perhaps this is why I'm not gushing about functional programming's panacea? Aaron On Tue, Feb 04, 2014 at 06:12:18AM -0800, Colin Yates wrote: This has turned into an unconstructive argument and for whatever reason we don't seem to be communicating clearly. Shame as I (and probably most people on here) only want to help. You seem to be reacting quite strongly to my thoughts - not sure why. If I may, I will just make/rephrase two points: - I think you would find value in watching Rick Hickey's videos on Simple Made Easy and also the one where he talks about Hammock Driven Development. - when I started using Clojure I immediately looked for equivalents of all the supporting infrastructure I used in good old Java land. I have no idea of your situation, but if you are there you have a wonderful opportunity
Re: lispy.el - a vi-like Paredit. Some Clojure features added.
This looks excellent! Desperately trying to suppress the whole emacs/vi battle raging inside which has is now rising up again :). On Sunday, 2 February 2014 13:44:12 UTC, Oleh wrote: Hi all, I've recently added some Clojure support to https://github.com/abo-abo/lispy. A short description of the package is that it's all the Paredit functions (and more) bound to unprefixed keys, e.g. a, c, 1, 2 etc. Nothing to do with evil package. Keys call commands instead of self-inserting when the point is in positions called special (marked here with |): |(defn sqr |[x]| |(* x x)|)| This comes together nicely since you rarely want to self-insert in those positions. Just to show how succinct the usage can be, you can transform from this: |(defn sqr [x] (* x x)) with just 4c to this: |(defn sqr [x] (* x x)) (defn sqr [x] (* x x)) (defn sqr [x] (* x x)) (defn sqr [x] (* x x)) (defn sqr [x] (* x x)) and further with 3j to this: (defn sqr [x] (* x x)) (defn sqr [x] (* x x)) (defn sqr [x] (* x x)) |(defn sqr [x] (* x x)) (defn sqr [x] (* x x)) and further with 2; to this: (defn sqr [x] (* x x)) (defn sqr [x] (* x x)) (defn sqr [x] (* x x)) ;; (defn sqr [x] (* x x)) ;; (defn sqr [x] (* x x)) Here's another example that shows how to transform |(map sqr (filter odd? [1 2 3 4 5])) to (- [1 2 3 4 5] (map sqr) (filter odd?))| I show it in a run-able test form (many more tests at github): (should (string= (lispy-with |(map sqr (filter odd? [1 2 3 4 5])) 2(-]]]wwlM) (- [1 2 3 4 5]\n (map sqr)\n (filter odd?))|)) The steps are: 1. 2( - wrap with parens. 2. - - self-insert (because point isn't special). 3. ] - forward list - point becomes special. 4. - barf. 5. ]] - forward, barf, forward. 6. ww - move sexp up twice. 7. l - exit list forwards. 8. M - transform sexp to multi-line. 9. you can e - eval to see if code works. Full description and some screenshots can be found at https://github.com/abo-abo/lispy. Here's a list of Clojure-specific features (cider is used for most): - look up doc inline in an overlay with C-1 - look up function arguments inline with C-2 - eval with e - eval and insert with E - goto symbol in file with g (clojure-semantic required) - goto definition with F The package is available in MELPA if you want to give it a go. Feedback welcome. regards, Oleh -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Lessons Learned from Adopting Clojure
Jay - in your demo I can't determine whether the (+ 2 2) expression is evaluated and the results pasted inline or whether you have manually pasted them? I see you are using emacs, can you detail how you have configured emacs? On Tuesday, 4 February 2014 16:33:44 UTC, Jay Fields wrote: On Tuesday, February 4, 2014 8:17:44 AM UTC-5, Magomimmo wrote: thanks for the report. I only have few doubts about REPL making TDD to shame. In this blog entry - http://blog.jayfields.com/2014/01/repl-driven-development.html - I demonstrate (very briefly, by design) my workflow. I also give my thoughts on TDD. On Tuesday, February 4, 2014 7:24:21 AM UTC-5, Rafael Peixoto de Azevedo wrote: +1 from Melbourne :) I actually gave the talk in Melbourne, as part of YOW!. It was recorded and will be online at some point. On Tuesday, February 4, 2014 7:22:06 AM UTC-5, Colin Yates wrote: Is there going to be online access during/after the event? I would greatly value seeing this, but probably not enough to travel from the UK to Chicago :). This talk will not be recorded (afaik), but it's the same as the YOW! version, and that should be online soon. On Tuesday, February 4, 2014 8:02:28 AM UTC-5, ajlopez wrote: A question: did you abandon TDD? why? IMO, TDD is a workflow that pushes for simplicity TDD, yes, for the most part. However, I still write a large number of tests. YMMV though, as you may find that TDD gives you better design direction. Assuming that's the case, I'd never try to convince you to do something else. This is an experience report, not a prescription for adopting Clojure. =) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Lessons Learned from Adopting Clojure
Without starting a flame war - how are you finding LightTable for production? Moving away from emacs and paredit would be quite hard and every time I look at LightTable I get really excited until I actually download and try it... That is almost certainly because I don't have the time to invest in learning it and I expect it to do everything out of the box immediately and just the way I like it :) On Tuesday, 4 February 2014 17:13:04 UTC, Sean Corfield wrote: Discussions around TDD / RDD (REPL-Driven-Development) probably need a separate thread but... On Feb 4, 2014, at 5:17 AM, Mimmo Cosenza mimmo@gmail.comjavascript: wrote: thanks for the report. I only have few doubts about REPL making TDD to shame. I'm a strong advocate of TDD (well, BDD specifically) and I agree with Jay's comment insofar as you write a test expression in the REPL and it evaluates immediately. That's always faster than writing a test and running a test, by definition. That's all I took his comment to mean. The REPL is great, that's for sure, but IMHO it does not relegate TDD feedback/loop in a niche, because you can complement one with the other. Indeed you can - and Jay does - and so do I. Especially now I'm using LightTable and can evaluate code in place in amongst my production code in one tabset and my expectations in another tabset. I have C-c , bound to evaluate a run-tests expression in my namespace so I can quickly evaluate and execute tests. Even so, live evaluation of test code is still a faster feedback loop. Many of my test expressions become long-lived unit tests (expectations). Or they become production code. I still write expectations to clarify how to design APIs in the small (and APIs in the large as needed), but most of the red-green-refactor loop of TDD/BDD now comes from the REPL experiments for me. Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Lessons Learned from Adopting Clojure
Interesting - thanks all. My experience of Light Table is quite close to Norman's, although I discounted that *in my case* to not spending enough time with it. Knowing a little about who Sean is (from following your blog/comments/clojure.jdbc, not stalking! :)) I put a lot of weight behind his opinion. Brian's too, whose emacs's environment is similar to mine. I happen to run midge :autotest in a separate console rather than in emacs with xmonad as my desktop manager (I mention xmonad because if you haven't checked it out you should - you will love it or hate it). Guess I just need to carve out some time to play with it myself. On Wednesday, 5 February 2014 06:09:38 UTC, Sean Corfield wrote: On Tue, Feb 4, 2014 at 6:07 PM, Brian Marick mar...@exampler.comjavascript: wrote: I always grate at the need to then immortalize the core of what I did in the REPL in repeatable tests. That's actually one of the things that bothered me in the Emacs REPL world: working in the REPL was separate from working in my production source and my test source. It's one of the things that has me really hooked on LightTable. I have my source and test namespaces both open. I have them both connected to a REPL. I can evaluate any code, in place, in either file. If I grow some code in the source file, I can put (defn some-name [args]) in front of it and M-) slurps it into a function - done! If I grow some code in the test file, I can put (expect result-value) in front of it and M-) slurps it into a test - done! Since I moved to LightTable, I've found myself doing even more REPL-Driven-Development than before because it's so much easier to turn the experiments into code - or tests - in place. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Confused by Clojure floating-point differences (compared to other languages)
Did I see a thread a while ago where doing this caught some people out because it wiped out some other performance switches? I can't find the thread. Apologies if I am spreading FUD On Wednesday, 5 February 2014 23:05:18 UTC, Alex Miller wrote: To override the default tiered compilation, add this to your project.clj: :jvm-opts ^:replace [] I would also recommend using a newer JDK (preferably 7, but at least 6). On Wednesday, February 5, 2014 4:34:12 PM UTC-6, David Nolen wrote: You need to make sure that you are running with server settings. If you are using lein, it's likely that this is not the case unless you have overridden lein's defaults in your project.clj. On Wed, Feb 5, 2014 at 5:30 PM, Glen Fraser hola...@gmail.com wrote: Thanks, yes, the version starting with 0.0 in the loop (rather than 0) does run faster. In my case, about 13% faster (19.7 seconds -- for the code you pasted below, with *unchecked-math*, type hints and starting x of 0.0 -- vs 22.7 seconds for my original version). But if you start with x of 0 (integer), the type-hinted version runs notably slower. In all cases, though, at least you get the same final answer… (-; So I don't see that 50% speedup you're seeing, but I do see improvement. I'm on Clojure 1.5.1, and Java 1.7.0_51 on OS X 10.8.5, running in an nREPL (cider) in Emacs. Possibly other JDK versions have more optimizations? Thanks Glen. On Feb 5, 2014, at 10:56 PM, David Nolen dnolen...@gmail.com wrote: (set! *unchecked-math* true) (defn g ^double [^double x] (+ (Math/sin (* 2.3 x)) (Math/cos (* 3.7 x (time (loop [i 1 x 0.0] (if (pos? i) (recur (dec i) (g x)) x))) This is nearly 50% faster than the original version on my machine. Note that x is bound to 0.0 in the loop, which allows the optimized g to be invoked. On Wed, Feb 5, 2014 at 4:41 PM, Glen Fraser hola...@gmail.com wrote: Thanks to both of you for these suggestions, they're good to know. In my specific case, setting the *unchecked-math* flag true did indeed speed things up slightly (by about 6%). The other change, though, with the double type hints (I assume that's what those are), actually ran notably slower (over 20% slower!). Glen. On Feb 5, 2014, at 8:13 PM, David Nolen dnolen...@gmail.com wrote: Also: (defn g ^double [^double x] (+ (Math/sin (* 2.3 x)) (Math/cos (* 3.7 x On Wed, Feb 5, 2014 at 2:07 PM, Alex Miller al...@puredanger.comwrote: Others have answered with many useful bits but I would mention that it would possibly make a significant performance difference if you added this to your code: (set! *unchecked-math* true) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@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+u...@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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Alternative - macro for threading sequences?
To be honest I prefer the first although I get your point about the over simplification. If I were going anywhere with this it would be to generalise it into a provided processor, something like: (- :processor map things wrangle ... ) but I am not sure the cognitive load of the extra syntax buys us much. On Thursday, 6 February 2014 14:40:50 UTC, Korny wrote: Hi folks, I seem to regularly find myself writing - threaded code that follows similar patterns: (- things (map wrangle) (map pacify) (filter effable) (map #(aggravate % :bees :sharks)) (reduce mapinate {}) i.e. all stages of the code actually operate on a collection rather than a single value - usually with a call to map at each stage. This example is over simplified - often many of the calls to map are inline functions, which makes this even more verbose. I wonder if there would be value in (yet another) variant on '-' that assumes you are threading a collection and calling 'map' by default. I'm not sure of the syntax that would work though. Something like: ([]- things wrangle pacify [:filter effable] (aggravate :bees :sharks) [:reduce mapinate {}]) I'm not sure about the syntax for non-map functions, I'm not even sure if this is worthwhile. Thoughts? - Korny -- Kornelis Sietsma korny at my surname dot com http://korny.info .fnord { display: none !important; } -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: every? expected behavior
Depends who is doing the expecting as to whether that behaviour is correct. Formal logicians, mathematicians, computer scientists etc. would respond sure, it is vacously true. For almost everybody else it feels wrong but is then true when you think about it a bit. I would suggest the question you are trying to ask is (and (not (empty? nil)) (every? #(= 77 %) nil)). For more info check out http://en.wikipedia.org/wiki/Vacuous_truth. On Tuesday, 8 April 2014 07:08:56 UTC+1, Jeff Mad wrote: Hi, I am new to Clojure, so please forgive me if this does not make sense. I was surprised to find out in the REPL that every? returns true if you pass in an empty or nil collection. user= (every? #(= 77 %) nil) true user= (every? #(= 77 %) '()) true I looked at the source for every? and it made sense to me why this happens given that every? is recursive and the termination condition is when coll runs out of items to process. Would it make more sense to define every? with a loop, or is the caller expected to know better than to call it with nil? Thanks, --jeff (defn every2? Returns true if (pred x) is logical true for every x in coll, else false. {:tag Boolean :added 1.0 :static true} [pred coll] (if (empty? coll) false (loop [c coll] (cond (nil? (seq c)) true (pred (first c)) (recur (next c)) :else false -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
where as clojure-fill-docstring gone?
I upgraded my emacs and clojure-fill-docstring seems to have disappeared. clojure-mode is still there and activated but no clojure-fill-docstring. Before I spend time hunting through changelogs has anybody else noticed? Is this expected? -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: where as clojure-fill-docstring gone?
Hi Bastian, sucks being sick. You mention it was unnecessary - can you let me know the thing that made it redundant? I tried fill-paragraph but that doesn't quite work... On Tuesday, 8 April 2014 20:28:52 UTC+1, Bastien Guerry wrote: Hi Colin, Colin Yates colin...@gmail.com javascript: writes: Before I spend time hunting through changelogs has anybody else noticed? Is this expected? `clojure-fill-docstring' behavior was somewhat wrong and the whole function not necessary, I removed it recently. That said, there are some quirks. I'm sick now and cannot fix those problems, but please report them as github issues if any. -- Bastien -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
RE: where as clojure-fill-docstring gone?
Yep - that issue covers the issue. I don't have any other problems other than that issue. I shall watch that issue closely :) From: bastiengue...@gmail.com To: colin.ya...@gmail.com CC: clojure@googlegroups.com Subject: Re: where as clojure-fill-docstring gone? Date: Tue, 8 Apr 2014 21:37:33 +0200 Colin Yates colin.ya...@gmail.com writes: Hi Bastian, sucks being sick. You mention it was unnecessary - can you let me know the thing that made it redundant? It was less redundant than weird. I tried fill-paragraph but that doesn't quite work... Can you explicit what does not work? There is this issue: https://github.com/clojure-emacs/clojure-mode/issues/228 If there are others, please add an issue on github. Thanks! -- Bastien -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Real World Example
Hello back! We are using Clojure on the JVM as the implementation language for a platform that will underpin our applications for the next decade. It is relatively new and so far we have implemented the analysis module which is essentially a generic charting engine. So far we have 5547 lines of production code (including comments) and 2600 lines of production code (including comments). That doesn't sound like much but I can tell you it is replacing a similar, but slightly smaller in scope analysis module written in Java which was around 40K lines of production code. Our architecture is Clojure on the back end exporting a number of JSON end points. It is backed by MS SQL using the fantastic https://github.com/jkk/honeysql library. For me, it is a dream coming from Java (and to a much lesser extent Scala), but it does have its costs. Moving from an OO world to an FP world isn't easy, particularly in the shapes your solutions end up with. I am also feeling the pain of not having types - everything is a sequence. This is a joy but it also means a whole bunch of information (i.e. type information) is lost. One of the wins in OO languages is the many number of places to hang semantic information - the name of the class, the structure of the class, the names of the methods etc. I also find many more intermediary variables in OO where as in Clojure it seems more idiomatic to have pipelines of transformation. I am feeling the lost of static types as I refactor APIs particularly. This is undoubtedly my failing not Clojure's and I just need to absorb more good FP paradigms. Would I give up my emacs and Clojure and paredit combination? Not a chance :). Col On Tuesday, 8 April 2014 20:23:06 UTC+1, Anthony Ortiz wrote: Hello world! I'm a C# developer who recently went to an interview at a major bank here in NYC and found that they've been using Clojure for their business logic for over a year already and that got me curious, so I find myself on unfamiliar territory learning how to program in a functional language. So far so good, Moxley Stratton's online tutorial combined with Try Clojure (the online interpreter) has been very helpful (kudos to you guys!) and I'm now going through the book 'Programming Clojure'. So far I've seen a lot of utility/academic examples such as fibonacci but little in the way of an actual real-world example of a top-to-bottom desktop application built using Clojure on either the JVM or CLR, something simple that would demonstrate how Clojure fits into the event-driven model on the client-side behind, let's say, WPF, and how it would interact with more Clojure on the service-side via, let's say, WCF. Does anyone know of an example they can direct me to? Many thanks! Anthony -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Real World Example
Gah - 5547 production, 2600 of tests. A lot of that discrepancy is down to the very extensive documentation that https://github.com/gdeer81/marginalia allows you to write. Please forgive any other mistakes, working on less than an hours sleep due to my lovely kids. On Wednesday, 9 April 2014 09:14:38 UTC+1, Colin Yates wrote: Hello back! We are using Clojure on the JVM as the implementation language for a platform that will underpin our applications for the next decade. It is relatively new and so far we have implemented the analysis module which is essentially a generic charting engine. So far we have 5547 lines of production code (including comments) and 2600 lines of production code (including comments). That doesn't sound like much but I can tell you it is replacing a similar, but slightly smaller in scope analysis module written in Java which was around 40K lines of production code. Our architecture is Clojure on the back end exporting a number of JSON end points. It is backed by MS SQL using the fantastic https://github.com/jkk/honeysql library. For me, it is a dream coming from Java (and to a much lesser extent Scala), but it does have its costs. Moving from an OO world to an FP world isn't easy, particularly in the shapes your solutions end up with. I am also feeling the pain of not having types - everything is a sequence. This is a joy but it also means a whole bunch of information (i.e. type information) is lost. One of the wins in OO languages is the many number of places to hang semantic information - the name of the class, the structure of the class, the names of the methods etc. I also find many more intermediary variables in OO where as in Clojure it seems more idiomatic to have pipelines of transformation. I am feeling the lost of static types as I refactor APIs particularly. This is undoubtedly my failing not Clojure's and I just need to absorb more good FP paradigms. Would I give up my emacs and Clojure and paredit combination? Not a chance :). Col On Tuesday, 8 April 2014 20:23:06 UTC+1, Anthony Ortiz wrote: Hello world! I'm a C# developer who recently went to an interview at a major bank here in NYC and found that they've been using Clojure for their business logic for over a year already and that got me curious, so I find myself on unfamiliar territory learning how to program in a functional language. So far so good, Moxley Stratton's online tutorial combined with Try Clojure (the online interpreter) has been very helpful (kudos to you guys!) and I'm now going through the book 'Programming Clojure'. So far I've seen a lot of utility/academic examples such as fibonacci but little in the way of an actual real-world example of a top-to-bottom desktop application built using Clojure on either the JVM or CLR, something simple that would demonstrate how Clojure fits into the event-driven model on the client-side behind, let's say, WPF, and how it would interact with more Clojure on the service-side via, let's say, WCF. Does anyone know of an example they can direct me to? Many thanks! Anthony -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Real World Example
Hi Fergal, Thanks for those links. I started using protocols and defrecords but I (maybe mistakenly) got the impression that they were frowned upon. As it turns out, maps (typically with a :type key) and multi methods go a long long way, but I still end up with fairly deep nesting of maps. Maybe that is the key - deep nesting of maps maybe cries out one object [data model] to rule them all and I need to decompose it further. Without types almost all the type hints would be either the map of sequence interface. It isn't so much the structure that is obscure, but the semantics of what that structure is modelling. As I hinted at, I am sure it is because my implementation model is still influenced too much by my OO background. Onwards and upwards as they say. Col On Wednesday, 9 April 2014 11:37:52 UTC+1, Fergal Byrne wrote: Hi Anthony, I'm building a fairly large real-world system called Clortex [1], which is a rewrite of the Numenta Platform for Intelligent Computing (NuPIC) [2]. As it's a greenfield project, I've chosen to use Clojure components all the way through instead of fitting in with Java-based or .Net-based frameworks. There are good reasons why you should do this if you can, but obviously that doesn't help you directly with your question. There are many people introducing Clojure as a component in an existing ecosystem, as Colin explains, but usually this is done deep inside a big Java or .Net shop, and they're not showing the world the code. One possible route would be to see if any of the big Java or CLR Open Source apps are looking at doing some subsystems in Clojure. Colin, Great to hear your experiences. I'm no expert, but it's likely that you could ease much of the pain using protocols, type hints and deftypes or records. Also, Typed Clojure [3] is definitely worth looking at. [1] Clortex will be public on Github shortly, see http://fergalbyrne.github.io for docs, http://inbits.com for blog. [2] http://numenta.org [3] https://github.com/clojure/core.typed Regards, Fergal Byrne On Wed, Apr 9, 2014 at 10:18 AM, Aditya Athalye aditya@gmail.comjavascript: wrote: Welcome, Anthony. I'm not aware of complete applications that fit your requirement, however I think you'll find value in the newly-minted Clojure Cookbook http://clojure-cookbook.com/ ... many, many examples of real-world problems, across domains, solved by Clojure practitioners. All the examples and solutions are available here: https://github.com/clojure-cookbook/clojure-cookbook Cheers, and once again, welcome! On Wednesday, April 9, 2014 12:53:06 AM UTC+5:30, Anthony Ortiz wrote: Hello world! I'm a C# developer who recently went to an interview at a major bank here in NYC and found that they've been using Clojure for their business logic for over a year already and that got me curious, so I find myself on unfamiliar territory learning how to program in a functional language. So far so good, Moxley Stratton's online tutorial combined with Try Clojure (the online interpreter) has been very helpful (kudos to you guys!) and I'm now going through the book 'Programming Clojure'. So far I've seen a lot of utility/academic examples such as fibonacci but little in the way of an actual real-world example of a top-to-bottom desktop application built using Clojure on either the JVM or CLR, something simple that would demonstrate how Clojure fits into the event-driven model on the client-side behind, let's say, WPF, and how it would interact with more Clojure on the service-side via, let's say, WCF. Does anyone know of an example they can direct me to? Many thanks! Anthony -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- Fergal Byrne, Brenter IT Author, Real Machine Intelligence with Clortex and NuPIC https://leanpub.com/realsmartmachines http://www.examsupport.iehttp://inbits.com - Better Living through Thoughtful Technology http://ie.linkedin.com/in/fergbyrne/ https://github.com/fergalbyrne e:fergalby...@gmail.com javascript: t:+353 83 4214179 Formerly of Adnet edi...@adnet.ie javascript: http://www.adnet.ie -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this
Re: Real World Example
lein-midje-doc really does look excellent. I went with marginalia but if that had been around at the time I would have jumped on it without a doubt. On Wednesday, 9 April 2014 13:20:51 UTC+1, Fergal Byrne wrote: Hi Colin, Cheers. I had exactly the same problem, so I've been trying out a few other ideas. One is to use datalog (or cascalog etc) and represent objects with entities and relationships between objects with refs (for datalog). I have some enormous data structures (2-300m synapses per layer, for example) but I find that Datomic and datalog are great for modelling really big and complex structures. There's a datomic wrapper library called adi [1] which adds a nice map-like interface on top of datalog. It's perfect for getting your schema right (you start off with a big map and it automagically does the schema), and you can do some really long link-following, but I'm not using it extensively yet (because everything is data, you can use adi for schema design and some queries, and raw datomic for the rest). I'll be writing extensively about each library or tool I've used on my blog (see sig). I'm writing about lein-midje-doc (also by zcaudate) at the moment, it's just wonderful. [1] https://github.com/zcaudate/adi Regards, Fergal Byrne On Wed, Apr 9, 2014 at 12:22 PM, Colin Yates colin...@gmail.comjavascript: wrote: Hi Fergal, Thanks for those links. I started using protocols and defrecords but I (maybe mistakenly) got the impression that they were frowned upon. As it turns out, maps (typically with a :type key) and multi methods go a long long way, but I still end up with fairly deep nesting of maps. Maybe that is the key - deep nesting of maps maybe cries out one object [data model] to rule them all and I need to decompose it further. Without types almost all the type hints would be either the map of sequence interface. It isn't so much the structure that is obscure, but the semantics of what that structure is modelling. As I hinted at, I am sure it is because my implementation model is still influenced too much by my OO background. Onwards and upwards as they say. Col On Wednesday, 9 April 2014 11:37:52 UTC+1, Fergal Byrne wrote: Hi Anthony, I'm building a fairly large real-world system called Clortex [1], which is a rewrite of the Numenta Platform for Intelligent Computing (NuPIC) [2]. As it's a greenfield project, I've chosen to use Clojure components all the way through instead of fitting in with Java-based or .Net-based frameworks. There are good reasons why you should do this if you can, but obviously that doesn't help you directly with your question. There are many people introducing Clojure as a component in an existing ecosystem, as Colin explains, but usually this is done deep inside a big Java or .Net shop, and they're not showing the world the code. One possible route would be to see if any of the big Java or CLR Open Source apps are looking at doing some subsystems in Clojure. Colin, Great to hear your experiences. I'm no expert, but it's likely that you could ease much of the pain using protocols, type hints and deftypes or records. Also, Typed Clojure [3] is definitely worth looking at. [1] Clortex will be public on Github shortly, see http://fergalbyrne.github.io for docs, http://inbits.com for blog. [2] http://numenta.org [3] https://github.com/clojure/core.typed Regards, Fergal Byrne On Wed, Apr 9, 2014 at 10:18 AM, Aditya Athalye aditya@gmail.comwrote: Welcome, Anthony. I'm not aware of complete applications that fit your requirement, however I think you'll find value in the newly-minted Clojure Cookbook http://clojure-cookbook.com/ ... many, many examples of real-world problems, across domains, solved by Clojure practitioners. All the examples and solutions are available here: https://github.com/clojure-cookbook/clojure-cookbook Cheers, and once again, welcome! On Wednesday, April 9, 2014 12:53:06 AM UTC+5:30, Anthony Ortiz wrote: Hello world! I'm a C# developer who recently went to an interview at a major bank here in NYC and found that they've been using Clojure for their business logic for over a year already and that got me curious, so I find myself on unfamiliar territory learning how to program in a functional language. So far so good, Moxley Stratton's online tutorial combined with Try Clojure (the online interpreter) has been very helpful (kudos to you guys!) and I'm now going through the book 'Programming Clojure'. So far I've seen a lot of utility/academic examples such as fibonacci but little in the way of an actual real-world example of a top-to-bottom desktop application built using Clojure on either the JVM or CLR, something simple that would demonstrate how Clojure fits into the event-driven model on the client-side behind, let's say, WPF, and how it would interact with more
Re: Advice for building backend REST services from scratch using clojure
As others have said - a more focused question would help. Our back end runs on ring + compojure using https://github.com/jkk/honeysql for querying and straight https://github.com/clojure/java.jdbc for writes. We use https://github.com/marick/Midje/wiki rather than clojure.test and https://github.com/gdeer81/marginalia for documentation. This is the first major Clojure app, so lots of lessons have been learnt. Things I wish I knew: - read the ring spec - it is all just a map, phenomenally powerful. Now read it again - consider using https://github.com/zcaudate/lein-midje-doc as well as/instead of marginalia - consider using https://github.com/jaycfields/expectations instead of midje. Midje is fantastic, but expectations, particularly the 'diffing' looks like a real win - consider using something like https://github.com/prismatic/schema to document your API from day one. - you can fight it as hard as you like but you will eventually end up using emacs, clojure-mode, cider, paredit and magit and then wonder how you ever lived without it, but not without spending at least a month or two cursing anything to do with emacs :). Just my random, off the cuff thoughts. Hope they help. On Thursday, April 10, 2014 3:13:19 PM UTC+1, Kashyap CK wrote: Hi, I have the opportunity to build a set of services from scratch. I plan to use clojure for this. I'd like to experiment with options available out there - options such as - what webserver, what database etc. I'd like it very much if you could share some of your experiences in this and possibly some pitfalls to avoid. Regards, Kashyap -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Advice for building backend REST services from scratch using clojure
Colin - you are right - I shouldn't throw out such inflammatory marks, particularly when they do a disservice to the excellent work done in Cursive Clojure, Lighttable and Counter Clockwise (and others that I am not aware off). For me personally, after years of using Eclipse then IntelliJ and (to a much lesser degree) Sublime I am forcing my team to use emacs. And yes, forcing is the word as they are utterly sold on sublime and really don't like me much at the moment :). It is the classical short term/long term win, and emacs is worth the investment for us. But it absolutely is an investment. Disclaimer - I haven't looked at any of the other editors for months if not years. On Friday, April 11, 2014 10:20:37 AM UTC+1, Colin Fleming wrote: you can fight it as hard as you like but you will eventually end up using emacs, clojure-mode, cider, paredit and magit and then wonder how you ever lived without it, but not without spending at least a month or two cursing anything to do with emacs :). As the developer of Cursive, I'd like to politely disagree with this point. I think that Cursive provides a very competitive feature set but without the swearing :-). Of course I'm totally biased, so take with a grain of salt, but I think particularly for Clojure newbies it's worth a look - learning Emacs at the same time as Clojure can be a recipe for frustration. Of course, it doesn't have to be Cursive, there are other options in case Emacs gives you hives. On 11 April 2014 20:17, Colin Yates colin...@gmail.com javascript:wrote: As others have said - a more focused question would help. Our back end runs on ring + compojure using https://github.com/jkk/honeysql for querying and straight https://github.com/clojure/java.jdbc for writes. We use https://github.com/marick/Midje/wiki rather than clojure.test and https://github.com/gdeer81/marginalia for documentation. This is the first major Clojure app, so lots of lessons have been learnt. Things I wish I knew: - read the ring spec - it is all just a map, phenomenally powerful. Now read it again - consider using https://github.com/zcaudate/lein-midje-doc as well as/instead of marginalia - consider using https://github.com/jaycfields/expectations instead of midje. Midje is fantastic, but expectations, particularly the 'diffing' looks like a real win - consider using something like https://github.com/prismatic/schemato document your API from day one. - you can fight it as hard as you like but you will eventually end up using emacs, clojure-mode, cider, paredit and magit and then wonder how you ever lived without it, but not without spending at least a month or two cursing anything to do with emacs :). Just my random, off the cuff thoughts. Hope they help. On Thursday, April 10, 2014 3:13:19 PM UTC+1, Kashyap CK wrote: Hi, I have the opportunity to build a set of services from scratch. I plan to use clojure for this. I'd like to experiment with options available out there - options such as - what webserver, what database etc. I'd like it very much if you could share some of your experiences in this and possibly some pitfalls to avoid. Regards, Kashyap -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Extending a data model
Multimethods are fantastic and do indeed work across namespaces if by across namespaces you mean you can defmethod in ns2 a defmulti in ns1. On Tuesday, April 15, 2014 2:56:30 AM UTC+1, Andrew Chambers wrote: An update, I read about protocols and multimethods. I think multimethods are a decent way to go (cant use protocols without a defrecord) provided they work across namespaces. On Tuesday, April 15, 2014 11:52:36 AM UTC+12, Andrew Chambers wrote: Hi everyone, I'm new to clojure and in order to learn I'm working on making some compiler tools which converts a lightweight IR code into assembly. My data model for an IR function is along the lines of (def code { :entry [[:loadaddr :x global_label] [:loadconst 1 :y] [:add :x :y :z] [:jmp :exit]] :exit [[:ret :z]] }) This, when translated to assembly and after register allocation would turn into something like (ignoring calling conventions etc): (def assembly-code { :entry [[:x86.lea :eax global_label] [:x86.loadimm 1, :eax] [:x86.add32 :ebx :eax] [:jmp :exit]] :exit [[:ret]] }) The problem arises when I have to query the IR code for things like accesses-memory? or get-output-vars in an extensible way so that multiple target architectures can be supported. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:x86.add :a :b]) - :b ;; the input and output positions are opcode specific (get-output-vars [:x86.add :a :b]) - :b (get-output-vars [:divmod :a :b :c :d]) - :c :d (accesses-memory? :x86.add) - false (accesses-memory? :x86.load) - true (accesses-memory? :loadconst) -false I have to be able to write these functions in a way that knows about the format of the basic IR opcodes, but can also be extended to handle opcodes of architectures that don't exist in my code yet, the extensions would exist within the namespaces of that specific architecture and shouldn't need to modify the code for the built in opcodes. What is the most seamless and efficient way to achieve this sort of function extension in clojure? Also, how would I allow sharing of implementations where instructions have similar layouts. e.g. (get-output-vars [:add :a :b :c]) - :c (get-output-vars [:sub :a :b :c]) - :c -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Style question (predicates)
My 2p - I interpret the contract as being boolean. Truthy values are 'polymorphically' equivalent*1 so sure. The concern would be people relying on the implementation and treating the values as none-truthy (i.e. in your example relying on the fact it is a string being returned, so (= someString (is-nsf-code? someString))) I should reduce it to 1p really as I am only contributing in an abstract design sense, not in the specifics of the coding standards you mentioned. *1 If this doesn't hold (i.e. caller depends upon receiving a java.lang.Boolean or associated primitive) then I think the caller has bigger problems. On Thursday, April 17, 2014 5:33:42 PM UTC+1, Sean Corfield wrote: The library coding standards[1] say: * Use '?' suffix for predicates. - N.B. - predicates return booleans and the community Clojure style guide[2] says: * The names of predicate methods (methods that return a boolean value) should end in a question mark. (i.e.even?). Both of these imply that if you have a function that returns a boolean (and that is intended for use as a predicate), it should be named to end in '?'. Fair enough. My question is about the reverse implication: * Should a function whose name ends in '?' return a (strict) boolean value? Looking at the docstrings of a random selection of functions found by (apropos ?), they all seem to return specifically true or false. I did not do an exhaustive check. Is the intent that foo? implies a result of true or false - or could foo? return any truthy / falsey value (and therefore any Clojure value). Concrete example that spurred this discussion from some code at work: (defn is-nsf-code? Given an error code, return truthy if it is NSF. [code] (#{BE1 BE2} code)) Clearly the result here could be nil or a string but it's definitely meant to be used as a predicate. Similarly: (defn nsf? Given the result of an SBW sale, return true if it failed with NSF. [result] (and (= failure (:result result)) (some is-nsf-code? (:errors result Again, the result could be false or nil or a string but is meant to be used as a predicate. As an aside, for core.typed, we annotate the first as [String - Boolean] with ^:no-check so it type checks as a true/false predicate and then we annotate the second as [SBWResult - (Nilable Boolean)] and that's all fine... but is it good style? [1] http://dev.clojure.org/display/community/Library+Coding+Standards [2] https://github.com/bbatsov/clojure-style-guide#naming Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Style - Keyword access or accessors?
(This has been discussed before but as this is fairly subjective I am interested in whether people's opinion has changed) What are people's experiences around using keywords or defined accessors for navigating data structures in Clojure (assuming the use of maps)? Do people prefer using raw keywords or do people define accessors. For example, given {:my-property 10} would people inline my-property or define a (defn my-property [m] (:my-property m))? If you use keywords then do you alias them (i.e. (def my-property :my-property)? My experience is that accessors become painful and restrictive really quickly (navigating nested maps for example) so keywords are the way to go. I tend to have a domain.clj which documents my domain and defines all the important abstractions (i.e. (def my-property :my-property). I find this very useful, combined with marginalia for documentation purposes. It also offers some aid in refactoring as multiple abstractions might resolve to the same keyword (i.e. value-group and bracket-group might resolve to :group). But, to be blunt, it can be a little cumbersome. I also refer :as the namespace, so instead of (get-in m [:a :b]) it is (get-in m [dom/a dom/b]). What are your thoughts (and any other hints/tips for maintaining large Clojure code bases?) -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Style - Keyword access or accessors?
Thanks Dan, One benefit is compile time safety and the refactoring I mentioned. But yes, I am coming around to the notion of just using raw keywords... On Tuesday, April 22, 2014 10:49:33 AM UTC+1, Dan Kersten wrote: I've personally always used keywords. I don't see any value in aliasing :foo to foo. For navigating nested maps, get-in, update-in and assoc-in with keywords seem natural and practical to me. On 22 April 2014 10:43, Colin Yates colin...@gmail.com javascript:wrote: (This has been discussed before but as this is fairly subjective I am interested in whether people's opinion has changed) What are people's experiences around using keywords or defined accessors for navigating data structures in Clojure (assuming the use of maps)? Do people prefer using raw keywords or do people define accessors. For example, given {:my-property 10} would people inline my-property or define a (defn my-property [m] (:my-property m))? If you use keywords then do you alias them (i.e. (def my-property :my-property)? My experience is that accessors become painful and restrictive really quickly (navigating nested maps for example) so keywords are the way to go. I tend to have a domain.clj which documents my domain and defines all the important abstractions (i.e. (def my-property :my-property). I find this very useful, combined with marginalia for documentation purposes. It also offers some aid in refactoring as multiple abstractions might resolve to the same keyword (i.e. value-group and bracket-group might resolve to :group). But, to be blunt, it can be a little cumbersome. I also refer :as the namespace, so instead of (get-in m [:a :b]) it is (get-in m [dom/a dom/b]). What are your thoughts (and any other hints/tips for maintaining large Clojure code bases?) -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/d/optout. -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: Style - Keyword access or accessors?
Nice. On Tuesday, April 22, 2014 11:36:06 AM UTC+1, Jim foo.bar wrote: there is really no reason to use `get-in` with keywords/symbols as they know how to look themselves up...in other words, you don't need to pay for any polymorphic calls : (get-in [:a :b :c :d] someMap) = (- someMap :a :b :c :d) Jim On 22/04/14 10:49, Daniel Kersten wrote: For navigating nested maps, get-in, update-in and assoc-in with keywords seem natural and practical to me. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: emacs - how to wean me off the family of Java IDEs
So a few months after using emacs, I gotta say I love it. First I absolutely hated it with a passion, and it really highlights my (fast but) poor typing skills :). Like Clojure I guess it requires a very different mindset. My constant frustration now is deciding whether to spend the time improving my emacs skills (at the level of mainly implementing keybindings) or improving my lein and Clojure skills. Nice problem to have though coming from the Enterprise Java world where the biggest problem was remembering to stop and think rather than just cntrl-spacing the application. I jest of course. The biggest 'ah - got it' for me was when I realised IDEs are great for navigating huge object models which are relatively narrow but deep (i.e. lots of nested relationships). This requires a special set of navigation skills (cntrl-click to go to declaration, autocompletion etc). Clojure (and I guess FP) code tends to be a much wider and shallower surface (i.e. lots of sibling functions with a few well defined data structures). The other huge win is the REPL. Trying things out, viewing the doc or source of functions etc. is just such a liberating experience. Loving it. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: emacs - how to wean me off the family of Java IDEs
Without static typing, I guess grep is the best? On 1 May 2013 12:13, Ulises ulises.cerv...@gmail.com wrote: The biggest 'ah - got it' for me was when I realised IDEs are great for navigating huge object models which are relatively narrow but deep (i.e. lots of nested relationships). This requires a special set of navigation skills (cntrl-click to go to declaration, autocompletion etc). Clojure (and I guess FP) code tends to be a much wider and shallower surface (i.e. lots of sibling functions with a few well defined data structures). The other huge win is the REPL. Trying things out, viewing the doc or source of functions etc. is just such a liberating experience. Try M-. (and M-,) on a symbol. If your nrepl is set up correctly, etc. that should take you to the code for a function/macro and back. The one thing I sorely miss in nrepl is a 'who-calls' type of functionality. Is this implemented and I just haven't found it yet? 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 --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/Uhe5Wjmkb5s/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Struggling with encapsulation
(newbie, but trying hard!) I am designing a Woobly. A Woobly is non-trivial and has a number of internal data structures (queues, worker threads etc.). You can 'add' and 'remove' jobs from a Woobly. In OO land I might have a Woobly interface with the various methods which provides a public API. I might also have a factory or more likely builder somewhere which creates Wooblies. The part I am struggling with is how to create a Woobly without exposing its internals. Let's imagine that Woobly uses an internal LinkedBlockingQueue of a certain size. Option 1 - a big bag of data. I could create a map of config/state/data that comprises the implementation and have the creator function return that. Consumers can then call other methods passing back that bag of config/state, but what stops them simply diving into that bag themselves? For example: [code] (defn create-woobly ([] (create-woobly 100) ([queue-size] {:queue (java.util.concurrent.LinkedBlockingQueue queue-size)})) (defn add-job [woobly job] ) ;; nothing stopping me diving into that state... (.clear (:queue (create-wobbly))) [/code] Option 2 - protocol and deftype Alternatively I could implement an IWoobly protocol and create a single deftype which is instantiated and returned from the 'create-woobly' function? I am not sure I like this as it is really back to OO isn't it? I want to retain the notion of create returning a handle which is the first argument in the other public functions, but the first way just feels far too dangerous. Am I overthinking this - what do you all do to address this? Thanks a bunch. Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Struggling with encapsulation
Thanks for all the helpful responses. One reason I want to hide the internals is that I don't want people to add jobs directly to the queue. (add-job) will put a map containing the provided function onto the queue. Not really relevant, but this is so that I can track queue timings that I can later on use to determine how much capacity the system can handle. I am nervous as well about expose internals but trust people to do the right thing because in this case, if I was a consumer and saw that queue, particularly given the emphasis about data being the contract etc. then why would I think *not* to use it. I do appreciate the point about not needlessly obfuscating information - this is a slightly different case. Sounds like in this case, either reify is the way to go or maybe return a bad of data but have this stuff in an 'internal' map (i.e. {:internal {:queue...}}) Thanks a bunch - really helpful. On 9 May 2013 17:30, James Reeves ja...@booleanknot.com wrote: On 9 May 2013 17:07, Colin Yates colin.ya...@gmail.com wrote: The part I am struggling with is how to create a Woobly without exposing its internals. To what end? What's the benefit? If you take a look at some internal data structures Clojure uses, like zippers or protocols, you'll notice that they're just maps. In general there's no need to try and obfuscate data to stop people from diving into the internals; just don't provide a public API for the internal parts and people will get the hint. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/D2OBBPTxGfY/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Struggling with encapsulation
Hi James - thanks for your response. I am still trying to wrap my head around this as I cannot agree. To re-frame, woobly allows you to add a job. The internal implementation of this is that it is decorates that job and puts the *decorated job* onto an internal LBQ. The implementation also depends upon being the only user of that LBQ as well. It is critical that jobs are added using the 'add-job' function. I try and write software that is 'easy to do the right thing, hard to do the wrong thing', and exposing the LBQ makes it trivial to do the wrong thing. Indeed - if I was using the woobly library (I could just say 'scheduler' right? :)) why wouldn't I think 'hey, I've got the LBQ, that is probably how I enter the pipeline' and 'great, now I can dequeue my jobs by calling .clear' etc. Documentation - sure, but documentation will never win a war when it is fighting the 'I know you can do this in the code but don't' fight. The 'bad thing' is that I have exposed too much. And please don't think I am making the 'code should stop bad programmers doing the wrong thing' argument, I'm not (been there, lost). I just know that if I released a scheduler library and the main construct was a map containing a LBQ (or in fact any sequence) then I would be inundated with a bunch of 'I did X to the queue and it broke' Is it really 'good Clojure' to expose internals which allow a user to easily and trivially break things? Please don't think I am nit-picking or splitting hairs, I genuinely want to improve my Clojure intuition. On 9 May 2013 21:05, James Reeves ja...@booleanknot.com wrote: On 9 May 2013 18:03, Colin Yates colin.ya...@gmail.com wrote: I am nervous as well about expose internals but trust people to do the right thing because in this case, if I was a consumer and saw that queue, particularly given the emphasis about data being the contract etc. then why would I think *not* to use it. If this were a problem in general I think we'd find more people poking at the internals of protocols, but I've never seen that happen. You could use namespaced keywords, like :woobly.internal/queue, to give people more of a hint that the data shouldn't be used without the API, but I really think you're borrowing trouble with this. Encapsulation is like inheritance, in that it's one of those ideas that's nice on paper, but ultimately not very useful in practise. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/D2OBBPTxGfY/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Struggling with encapsulation
Thanks Korny. Ok, the over-ridding theme seems to be: expose state, even if it is dangerous, but expect consumers to 'do the right thing' and read the documentation. I can see that. I guess I have worked (and to be honest, been guilty myself) with too many people who don't read the documentation, use auto-complete to find something that looks like it might work and then move on to the next chunk of wiring things up in XML :). I think I also got hung up on the 'data as a contract'. The point here is that I am not returning data, rather I am defining a service. A subtle difference but an important one I think. Keep the comments coming! On 10 May 2013 11:37, Korny Sietsma ko...@sietsma.com wrote: I would generally handle this sort of encapsulation at the namespace level. Put (create-woobly) and (add-job) and all the other woobly-related functions into a woobly namespace. Also add any functions that access info from a woobly bag-o-state, or mutate a woobly to make a woobly-with-extras. Functions that might dangerously expose internals of a woobly can be made private, or possibly you can just document them in a way to warn folks away from bad behaviour. While external users of (woobly/create-woobly) can in theory dig into the internals of the woobly object, but it should be relatively obvious that this isn't a good idea. I'd defer making protocols until you actually need polymorphism. - Korny On 10 May 2013 03:03, Colin Yates colin.ya...@gmail.com wrote: Thanks for all the helpful responses. One reason I want to hide the internals is that I don't want people to add jobs directly to the queue. (add-job) will put a map containing the provided function onto the queue. Not really relevant, but this is so that I can track queue timings that I can later on use to determine how much capacity the system can handle. I am nervous as well about expose internals but trust people to do the right thing because in this case, if I was a consumer and saw that queue, particularly given the emphasis about data being the contract etc. then why would I think *not* to use it. I do appreciate the point about not needlessly obfuscating information - this is a slightly different case. Sounds like in this case, either reify is the way to go or maybe return a bad of data but have this stuff in an 'internal' map (i.e. {:internal {:queue...}}) Thanks a bunch - really helpful. On 9 May 2013 17:30, James Reeves ja...@booleanknot.com wrote: On 9 May 2013 17:07, Colin Yates colin.ya...@gmail.com wrote: The part I am struggling with is how to create a Woobly without exposing its internals. To what end? What's the benefit? If you take a look at some internal data structures Clojure uses, like zippers or protocols, you'll notice that they're just maps. In general there's no need to try and obfuscate data to stop people from diving into the internals; just don't provide a public API for the internal parts and people will get the hint. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/D2OBBPTxGfY/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Kornelis Sietsma korny at my surname dot com http://korny.info .fnord { display: none !important; } -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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
Not using dependency injection - how do I share services around?
(newbie, getting better each day!) I assume we all know DI. Through the use of a central registry I can register a service (a bean in a Spring bean factory for example). I also define consumers of that service in the same registry passing in the configured *instance* of that service. In Clojure I have a service (i.e. a datasource) defined in its own namespace. What is idiomatic Clojure?: 1) to use (defonce *data-source*...) so that every body who requires that ns gets the same instance? 2) to provide a 'get-ds' accessor which returns a new instance and rely on passing that service along to every function that needs it? 3) some other way I don't know about Option 1 seems to be less-typing, but now functions aren't pure - they depend upon state defined elsewhere. I can change the binding through 'with-XYZ' type functions, but that isn't solving the non-explicit dependency between the function and the state. Option 2 means functions are still pure, but how do you prevent huge lists of services - i.e. if func-a calls func-b which calls func-c and func-c needs service-a then func-a and func-b need to access service-a. Yuck. It also means the main entry point to my application needs to assemble all of these services up in one go. To be more explicit - DI containers provide a graphs of logic coupled with state - the state being the instances of the collaborators (i.e. I will have ConsumerA with an instance of SimpleServiceA please). Clojure has very strong opinions about how to manage state. How does the Clojure community handle this use case of separating out the definition of a service, the configuration of that service and providing that service as a collaborator to a consumer? Thanks a bunch. Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Struggling with encapsulation
Thanks John. To be explicit - the add method shouldn't be private - it is the only way users should add to the queue. I think this is what you meant but you wrote ..and `add` and `clear` are your private fns... Again, this paradigm shift of 'trust your users' is unfortunately alien to me based on my experience with most of the Java devs I have come across :). I say that not be snarky, but to highlight how much it really does change things. The open-closed principle now becomes much simpler to realise for example. Thanks again. On 10 May 2013 12:44, John D. Hume duelin.mark...@gmail.com wrote: I agree with the advice you've gotten, but since no one has mentioned it, I wanted to point out that you can have encapsulation w/o protocols with something like this. Assume a queue is your only state and `add` and `clear` are your private fns that take a queue as first argument. (defn new-scheduler [] (let [queue (...)] {:add (partial add queue) :clear (partial clear queue)})) There are several disadvantages to this, however. The biggest in my book is that it achieves your goal, and you're limited in the same way your users are. You can't add behavior to an already created scheduler (unless it's built on adding and clearing). Furthermore, if you dynamically recompile `add` or `clear`, it won't change the behavior of an already created scheduler, since partial has the fns, not the symbols or vars that point at them. (These same disadvantages apply to a reified protocol.) As others have recommended, just return a map. Keep in mind that the documentation is just a `(doc new-scheduler)` away and that auto-completion will tend to send people back into your ns's fns rather than into the internals of a data structure. On May 10, 2013 5:51 AM, Colin Yates colin.ya...@gmail.com wrote: Thanks Korny. Ok, the over-ridding theme seems to be: expose state, even if it is dangerous, but expect consumers to 'do the right thing' and read the documentation. I can see that. I guess I have worked (and to be honest, been guilty myself) with too many people who don't read the documentation, use auto-complete to find something that looks like it might work and then move on to the next chunk of wiring things up in XML :). I think I also got hung up on the 'data as a contract'. The point here is that I am not returning data, rather I am defining a service. A subtle difference but an important one I think. Keep the comments coming! On 10 May 2013 11:37, Korny Sietsma ko...@sietsma.com wrote: I would generally handle this sort of encapsulation at the namespace level. Put (create-woobly) and (add-job) and all the other woobly-related functions into a woobly namespace. Also add any functions that access info from a woobly bag-o-state, or mutate a woobly to make a woobly-with-extras. Functions that might dangerously expose internals of a woobly can be made private, or possibly you can just document them in a way to warn folks away from bad behaviour. While external users of (woobly/create-woobly) can in theory dig into the internals of the woobly object, but it should be relatively obvious that this isn't a good idea. I'd defer making protocols until you actually need polymorphism. - Korny On 10 May 2013 03:03, Colin Yates colin.ya...@gmail.com wrote: Thanks for all the helpful responses. One reason I want to hide the internals is that I don't want people to add jobs directly to the queue. (add-job) will put a map containing the provided function onto the queue. Not really relevant, but this is so that I can track queue timings that I can later on use to determine how much capacity the system can handle. I am nervous as well about expose internals but trust people to do the right thing because in this case, if I was a consumer and saw that queue, particularly given the emphasis about data being the contract etc. then why would I think *not* to use it. I do appreciate the point about not needlessly obfuscating information - this is a slightly different case. Sounds like in this case, either reify is the way to go or maybe return a bad of data but have this stuff in an 'internal' map (i.e. {:internal {:queue...}}) Thanks a bunch - really helpful. On 9 May 2013 17:30, James Reeves ja...@booleanknot.com wrote: On 9 May 2013 17:07, Colin Yates colin.ya...@gmail.com wrote: The part I am struggling with is how to create a Woobly without exposing its internals. To what end? What's the benefit? If you take a look at some internal data structures Clojure uses, like zippers or protocols, you'll notice that they're just maps. In general there's no need to try and obfuscate data to stop people from diving into the internals; just don't provide a public API for the internal parts and people will get the hint. - James -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post
Re: Struggling with encapsulation
On 10 May 2013 14:10, James Reeves ja...@booleanknot.com wrote: Have you tried it? :) I've authored about 40 Clojure libraries over 5 years, some with data structures with internal components. The number of times someone has said I did X to this internal data and it broke is exactly zero. It's never ever happened. So I think you're probably borrowing trouble, and I'd certainly be very surprised if you have any support requests like the one you describe. This is all about changing my mindset from 15-odd years of Java dev by learning from others, so let's give it a go. Years of enterprise Java dev have gotten their cynical, 'data is precious and should be hidden away', 'other devs will do the wrong thing' etc. claws into me though, so it is with trepidation I set out on this gloriously liberating new path :). -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not using dependency injection - how do I share services around?
Thanks both - some good suggestions. After years of Java I am loving how 'symmetrical' everything is in Clojure (I guess in Lisp). Thanks for the library references. On 10 May 2013 14:14, Ben Mabey b...@benmabey.com wrote: Hi Colin, On 5/10/13 5:04 AM, Colin Yates wrote: 1) to use (defonce *data-source*...) so that every body who requires that ns gets the same instance? While this has been done I view this as an antipattern. The big problem with this approach is that you now can only have a single *data-source* for your entire application. Testing becomes hard, stopping and restarting is difficult, etc... While this approach is easy the resulting workarounds introduce incidental complexity. 2) to provide a 'get-ds' accessor which returns a new instance and rely on passing that service along to every function that needs it? Propagating the dependency like this is as much as an antipattern in Clojure as it is in OO languages[1] IMO. As you point out it is also just as much fun. :) 3) some other way I don't know about The way I've been doing DI like stuff is with Prismatic's graph[2] and similar libraries. While graph doesn't explicitly say it is a DI library it certainly is solving the same problem. What is interesting about graph is how small it is and how it can solve problems in the large (like an application) but also on a much smaller scale (e.g. computations with a handful of functions). While graph's approach may not be as powerful as the huge DI frameworks in Java (I'm assuming, I haven't used them personally much) I think you can get 90% of the value with 1% of the code. I've been using a graph-like library for a number of months in my more complex applications and it has been fantastic. HTH, Ben 1. http://picocontainer.codehaus.**org/propagating-dependency-** antipattern.htmlhttp://picocontainer.codehaus.org/propagating-dependency-antipattern.html 2. http://blog.getprismatic.com/**blog/2012/10/1/prismatics-** graph-at-strange-loop.htmlhttp://blog.getprismatic.com/blog/2012/10/1/prismatics-graph-at-strange-loop.html https://github.com/Prismatic/**plumbinghttps://github.com/Prismatic/plumbing -- -- You 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+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/** topic/clojure/keid7IGzKjk/**unsubscribe?hl=enhttps://groups.google.com/d/topic/clojure/keid7IGzKjk/unsubscribe?hl=en . To unsubscribe from this group and all its topics, send an email to clojure+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com . For more options, visit https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out . -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Struggling with encapsulation
I get your point, but Java's LinkedBlockingQueue is mutable. Of course, I should replace it with a plain sequence or Clojure's persistent queue but I really want the blocking semantics. That's tomorrow's job :). On 10 May 2013 15:37, Jim - FooBar(); jimpil1...@gmail.com wrote: On 10/05/13 14:20, Colin Yates wrote: This is all about changing my mindset from 15-odd years of Java dev by learning from others, so let's give it a go. Years of enterprise Java dev have gotten their cynical, 'data is precious and should be hidden away', 'other devs will do the wrong thing' etc. claws into me though, so it is with trepidation I set out on this gloriously liberating new path :). the mindset you're describing is a direct consequence of unrestrained mutability ...nothing bad can happen to your *immutable* clojure data :)... very liberating indeed! Jim -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/D2OBBPTxGfY/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not using dependency injection - how do I share services around?
Thanks Timo; Interesting links. Loving Clojure, but boy is it challenging the stuff I have been doing for the past how-ever many years :). On 10 May 2013 20:14, Timo Mihaljov t...@mihaljov.info wrote: On 10.05.2013 14:04, Colin Yates wrote: 2) to provide a 'get-ds' accessor which returns a new instance and rely on passing that service along to every function that needs it? For what it's worth, some people in the OO community, most notably Nat Pryce and Steve Freeman of Growing Object-Oriented Software[1] fame, advocate[2][3] this approach over using an IoC container. Option 2 means functions are still pure, but how do you prevent huge lists of services - i.e. if func-a calls func-b which calls func-c and func-c needs service-a then func-a and func-b need to access service-a. Yuck. It also means the main entry point to my application needs to assemble all of these services up in one go. Here's the punchline from [3]: If I later find that I can’t get access to some component that I think I need, that’s not necessarily a bad thing. It’s telling me that I’m introducing a new dependency and sometimes that’s a hint that a component is in the wrong place, or that I’m trying to use it from the wrong place. The coding bump is a design feedback mechanism that I miss when I can just pull objects out of a container. If I do a good job, I should find that, most of the time, I have just the right components at the time that I need them. [1] http://www.growing-object-oriented-software.com/ [2] http://www.natpryce.com/articles/000783.html [3] http://www.higherorderlogic.com/2011/07/is-dependency-injection-like-facebook/ -- Timo -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/keid7IGzKjk/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not using dependency injection - how do I share services around?
Yes it does, thanks. It is amazing how much you can do in the typical spring/hibernate stack with a decent IDE without engaging your brain :). Clojure involves far less ceremony and really does expose you to the raw elements of your problem domain and make you think. This is of course a good thing, but boy is it quite humbling :). No more procrastinating by setting up JPA and thinking long and hard about Java, Annotations or good old XML?. I am definitely at the stage where I think Clojure's simplicity is very hard (according to Rich's simple made easy talk). Not implying Clojure's simplicity is only the lack of ceremonial frameworks! Loving it, and yes, looking back I can see how easy it is to lose your solution amongst the staggering amount of incidental complexity. I guess my (rambling) point is to reiterate that it is very easy to plaster over symptoms/effects using the very powerful framework beasts. The lack of them forces you to think, and hopefully remove the cause. Finally, I have worked with some fantastic developers who happen to use Java to build incredibly elegant and transparent solutions. I have just worked with far more code monkeys, myself being one of them :). On 11 May 2013 08:21, Sean Corfield seancorfi...@gmail.com wrote: Korny mentioned java.jdbc and I figured that was a good in to talk about how we use it at World Singles. Even with the old API we used a function in a specific namespace that returned the data source (in fact it returned a pooled data source, using c3p0). Behind the scenes, we actually use an atom to provide a cached, singleton instance. with-redefs allows us to mock that for testing, if needed :) I haven't missed DI at all since moving to Clojure - after decades of OO - and I still use it in the non-Clojure, OO code that could be considered our legacy system that wraps our Clojure code. Clojure makes me think about my dependencies and organize them in a very clean top-to-bottom tree, with very clear divisions between subsystems. In the OO world, DI makes you sloppy... You can have circular dependencies. You can easily add whatever dependencies you need. You don't have to think about it, you can work around problems that crop up. Does that help Colin? Sean On Fri, May 10, 2013 at 4:04 AM, Colin Yates colin.ya...@gmail.com wrote: (newbie, getting better each day!) I assume we all know DI. Through the use of a central registry I can register a service (a bean in a Spring bean factory for example). I also define consumers of that service in the same registry passing in the configured *instance* of that service. In Clojure I have a service (i.e. a datasource) defined in its own namespace. What is idiomatic Clojure?: 1) to use (defonce *data-source*...) so that every body who requires that ns gets the same instance? 2) to provide a 'get-ds' accessor which returns a new instance and rely on passing that service along to every function that needs it? 3) some other way I don't know about Option 1 seems to be less-typing, but now functions aren't pure - they depend upon state defined elsewhere. I can change the binding through 'with-XYZ' type functions, but that isn't solving the non-explicit dependency between the function and the state. Option 2 means functions are still pure, but how do you prevent huge lists of services - i.e. if func-a calls func-b which calls func-c and func-c needs service-a then func-a and func-b need to access service-a. Yuck. It also means the main entry point to my application needs to assemble all of these services up in one go. To be more explicit - DI containers provide a graphs of logic coupled with state - the state being the instances of the collaborators (i.e. I will have ConsumerA with an instance of SimpleServiceA please). Clojure has very strong opinions about how to manage state. How does the Clojure community handle this use case of separating out the definition of a service, the configuration of that service and providing that service as a collaborator to a consumer? Thanks a bunch. Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles
Re: Not using dependency injection - how do I share services around?
Not specifically, nope. On 11 May 2013 10:37, Jimmy jimmy.co...@gmail.com wrote: Do any of the clojure books cover this topic? -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/keid7IGzKjk/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
idiomatic terminating infinite loops
Hi all, I have a scheduler which creates a future that basically does a (while true (let [next-job (.take queue)]...)), where queue is a LinkedBlockingQueue. The problem is that once it is running, because futures aren't daemon threads it hangs lein. It will ultimately run inside a compojure web app where, whist it doesn't stop the web server being shut down, it should do it more elegantly by explicitly being told to shut down. It is necessarily a singleton because it is sized to allow the maximum amount of concurrency. Starting up more than one scheduler would swamp the system. What is the idiomatic way of managing this? In terms of accessing the singleton I could: - use a root level *binding* which smells of global state - pass in the instance to the consumers of the scheduler. Fine, but that means threading it through from the bootstrapping code all the way down the call stack to the function that needs it. - add a (get-scheduler) accessor in the scheduler ns In terms of controlling the lifecycle I could: - add a with-scheduler construct which starts it, delegates to the delegate in a try/finally and then closes it in the finally clause. Given that this is infrastructural and will be used in lots of places I would need to wrap the whole application inside with-scheduler. - add (start-engine) and (stop-engine) functions in the scheduler ns which are then called from the relevant parts in the Compojure/testing framework lifecycle I could also not use a future and use a deamon thread instead but this feels like I am working against Clojure a little. It also side steps this question which I want to resolve. I am trying to separate the 'lifecycle' concerns from the 'getting hold of it' concern as they are orthogonal I think. the with-scheduler pattern seems to combine both concerns. I am currently deciding between: - expose a (start-engine) which delegates to an internal (defonce). This is called on compojure's start up - expose an (get-engine) in the scheduler namespace which delegates to an internal (defonce) - expose a (shutdown) function/shutdown protocol method in the scheduler namespace which is called on Compojure's shut down - create a test utility (def with-scheduler [delegate] ...) or use pre/post setup hooks which manages the lifecycle of the scheduler or - expose a (with-scheduler) which is integrated into Compojure's lifecycle such that it wraps Compojure's lifecycle. Not sure this is even possible. - expose a (get-engine) in the scheduler namespace which delegates to an internal (defonce) - use the (with-scheduler) for testing Any and all advice is welcome. Thanks, Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not using dependency injection - how do I share services around?
Thanks Jason, I will take a look. On Sunday, 12 May 2013 01:27:11 UTC+1, Jason Wolfe wrote: Hi Colin, This is one of the reasons we created graph: https://github.com/prismatic/plumbing which is a general declarative mechanism for describing complex function compositions. There's not an awesome public example yet, but we use Graph at Prismatic to build our production services, where each node builds a single component of a service, based on other named other components and parameters. This ends up looking somewhat similar to dependency injection, although the details are rather different. Basically you get the advantages of your second option (no global state), but hopefully without the 'yuck'. If you're interested, I'm happy to answer questions here or on the plumbing mailing list: https://groups.google.com/forum/#!forum/prismatic-plumbing Cheers, Jason On Friday, May 10, 2013 4:04:20 AM UTC-7, Colin Yates wrote: (newbie, getting better each day!) I assume we all know DI. Through the use of a central registry I can register a service (a bean in a Spring bean factory for example). I also define consumers of that service in the same registry passing in the configured *instance* of that service. In Clojure I have a service (i.e. a datasource) defined in its own namespace. What is idiomatic Clojure?: 1) to use (defonce *data-source*...) so that every body who requires that ns gets the same instance? 2) to provide a 'get-ds' accessor which returns a new instance and rely on passing that service along to every function that needs it? 3) some other way I don't know about Option 1 seems to be less-typing, but now functions aren't pure - they depend upon state defined elsewhere. I can change the binding through 'with-XYZ' type functions, but that isn't solving the non-explicit dependency between the function and the state. Option 2 means functions are still pure, but how do you prevent huge lists of services - i.e. if func-a calls func-b which calls func-c and func-c needs service-a then func-a and func-b need to access service-a. Yuck. It also means the main entry point to my application needs to assemble all of these services up in one go. To be more explicit - DI containers provide a graphs of logic coupled with state - the state being the instances of the collaborators (i.e. I will have ConsumerA with an instance of SimpleServiceA please). Clojure has very strong opinions about how to manage state. How does the Clojure community handle this use case of separating out the definition of a service, the configuration of that service and providing that service as a collaborator to a consumer? Thanks a bunch. Col -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Not using dependency injection - how do I share services around?
Nice videos - thanks for the heads up. On Saturday, 11 May 2013 11:40:04 UTC+1, abp wrote: Well, you could also watch Stuart Sierras talks on structuring functional programs: Clojure in the Large http://vimeo.com/46163090 Thinking in Data Functional Design Patterns http://www.infoq.com/author/Stuart-Sierra On Saturday, May 11, 2013 10:48:02 AM UTC+2, Colin Yates wrote: Yes it does, thanks. It is amazing how much you can do in the typical spring/hibernate stack with a decent IDE without engaging your brain :). Clojure involves far less ceremony and really does expose you to the raw elements of your problem domain and make you think. This is of course a good thing, but boy is it quite humbling :). No more procrastinating by setting up JPA and thinking long and hard about Java, Annotations or good old XML?. I am definitely at the stage where I think Clojure's simplicity is very hard (according to Rich's simple made easy talk). Not implying Clojure's simplicity is only the lack of ceremonial frameworks! Loving it, and yes, looking back I can see how easy it is to lose your solution amongst the staggering amount of incidental complexity. I guess my (rambling) point is to reiterate that it is very easy to plaster over symptoms/effects using the very powerful framework beasts. The lack of them forces you to think, and hopefully remove the cause. Finally, I have worked with some fantastic developers who happen to use Java to build incredibly elegant and transparent solutions. I have just worked with far more code monkeys, myself being one of them :). On 11 May 2013 08:21, Sean Corfield seanco...@gmail.com wrote: Korny mentioned java.jdbc and I figured that was a good in to talk about how we use it at World Singles. Even with the old API we used a function in a specific namespace that returned the data source (in fact it returned a pooled data source, using c3p0). Behind the scenes, we actually use an atom to provide a cached, singleton instance. with-redefs allows us to mock that for testing, if needed :) I haven't missed DI at all since moving to Clojure - after decades of OO - and I still use it in the non-Clojure, OO code that could be considered our legacy system that wraps our Clojure code. Clojure makes me think about my dependencies and organize them in a very clean top-to-bottom tree, with very clear divisions between subsystems. In the OO world, DI makes you sloppy... You can have circular dependencies. You can easily add whatever dependencies you need. You don't have to think about it, you can work around problems that crop up. Does that help Colin? Sean On Fri, May 10, 2013 at 4:04 AM, Colin Yates colin...@gmail.com wrote: (newbie, getting better each day!) I assume we all know DI. Through the use of a central registry I can register a service (a bean in a Spring bean factory for example). I also define consumers of that service in the same registry passing in the configured *instance* of that service. In Clojure I have a service (i.e. a datasource) defined in its own namespace. What is idiomatic Clojure?: 1) to use (defonce *data-source*...) so that every body who requires that ns gets the same instance? 2) to provide a 'get-ds' accessor which returns a new instance and rely on passing that service along to every function that needs it? 3) some other way I don't know about Option 1 seems to be less-typing, but now functions aren't pure - they depend upon state defined elsewhere. I can change the binding through 'with-XYZ' type functions, but that isn't solving the non-explicit dependency between the function and the state. Option 2 means functions are still pure, but how do you prevent huge lists of services - i.e. if func-a calls func-b which calls func-c and func-c needs service-a then func-a and func-b need to access service-a. Yuck. It also means the main entry point to my application needs to assemble all of these services up in one go. To be more explicit - DI containers provide a graphs of logic coupled with state - the state being the instances of the collaborators (i.e. I will have ConsumerA with an instance of SimpleServiceA please). Clojure has very strong opinions about how to manage state. How does the Clojure community handle this use case of separating out the definition of a service, the configuration of that service and providing that service as a collaborator to a consumer? Thanks a bunch. Col -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@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+u...@googlegroups.com For more options, visit this group at http
Re: idiomatic terminating infinite loops
Thanks both, good suggestions. On 15 May 2013 23:38, Stuart Sierra the.stuart.sie...@gmail.com wrote: Colin Yates wrote: I have a scheduler which creates a future that basically does a (while true (let [next-job (.take queue)]...)), where queue is a LinkedBlockingQueue. The problem is that once it is running, because futures aren't daemon threads it hangs lein. Instead of .take, you can use .poll with a timeout, then have your loop check if it's been told to shut down, e.g. by setting an Atom. Alternately, inject a poison message into the queue that tells the loop to shut down. My preferred approach to handling run-time services like this is to inject them into the app when it starts, thereby avoiding global Vars. -S -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/D4brGvqreSo/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Why are errors in nested futures suppressed?
Hi all, If the function executed in a future throws an error it is printed out in the repl immediately. If that function is executed in a future which itself is executed in a future then it isn't. For example, imagine somebody wrote the following code (please, suspend belief and just accept people do do this when learning Clojure :)): [code] ;; some silly code user (swap! atom inc 0) ClassCastException clojure.core$atom cannot be cast to clojure.lang.Atom clojure.core/swap! (core.clj:2161) ;; silly code wrapped in a future user (future (swap! atom inc 0)) ClassCastException clojure.core$atom cannot be cast to clojure.lang.Atom clojure.core/swap! (core.clj:2161) ;; silly code wrapped in a future wrapped in a future user (future (future (swap! atom inc 0))) #core$future_call$reify__6267@11e55d39: :pending user [/code] My understanding is that future executes its delegate in a separate thread, hence the (future (swa...)) code prints out the exception almost immediately. I don't understand why the nested future doesn't print out the error though as it should surely be executed almost immediately as well? Of course, if you dereference the call then it prints out the stack trace. As to why you would want a future in a future...that is a different kettle of fish :). -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
executing tests using clojure-test-mode in emacs throws ClassNotFoundException
Hi, I am trying to get clojure-test-mode working in emacs from https://github.com/technomancy/clojure-mode. I have the nrepl working great, the problem is if I C-c, C-, in a test file then I get the clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: clojure.test.mode, compiling:(NO_SOURCE_PATH:1:1) at clojure.lang.Compiler.analyze (Compiler.java:6380) error which seems pretty common according to google. https://github.com/technomancy/clojure-mode/pull/99#issuecomment-9848355 suggests removing them from load-packages and installing them manually, but is there a better option? I am trying to consolidate the emacs config across the team so installing in init.el is much simpler. Is there a way in which I can install clojure-mode from marmalade and still have clojure test mode working? Thanks. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: executing tests using clojure-test-mode in emacs throws ClassNotFoundException
https://github.com/technomancy/clojure-mode/issues/146#issuecomment-15447065 provides one solution - navigate to the source code and then start nrepl. On Tuesday, 21 May 2013 11:37:19 UTC+1, Colin Yates wrote: Hi, I am trying to get clojure-test-mode working in emacs from https://github.com/technomancy/clojure-mode. I have the nrepl working great, the problem is if I C-c, C-, in a test file then I get the clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: clojure.test.mode, compiling:(NO_SOURCE_PATH:1:1) at clojure.lang.Compiler.analyze (Compiler.java:6380) error which seems pretty common according to google. https://github.com/technomancy/clojure-mode/pull/99#issuecomment-9848355 suggests removing them from load-packages and installing them manually, but is there a better option? I am trying to consolidate the emacs config across the team so installing in init.el is much simpler. Is there a way in which I can install clojure-mode from marmalade and still have clojure test mode working? Thanks. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Structing Clojure tests/setup and tear down
Howdy, I am using clojure.test and have some questions of how to write idiomatic Clojure. This really isn't about testing at all per-se. First - I know about fixtures to get (at least) the same as JUnit's before/after behaviour. My code is a bloomy. You can configure the bloomy and it does different things based on that behaviour. Pretty much every test has a different bloomy, *and* that bloomy must be elegantly shut down. How should I handle this? At the moment I have the most un-idiomatic way and blunt way of : [code] (deftest my-test (let [bloomy (create-a-bloomy] (try (do-something-with-my-bloomy) (is (=)) (finally (shut-down bloomy [/code] Yep, try/finally in every test - reminds me of early JDBC libraries before Spring :). If I understand it correctly, I would end up writing a separate fixture for each and every test, or at least each any every unique set of test context. I did consider writing a (defn with-bloomy [bloomy test] (try (test) (finally (shut-down bloomy but I couldn't figure out how to pass my bloomy into the test itself. I also received lots of assertion not in expectation type errors. To be explicit I would use this as (with-bloomy (create-a-bloomy) (deftest...))). I did consider a variation on the above of passing in a function which only contained the assertions, so (deftest my-test (let [bloomy...] (with-bloomy bloomy #(is (= 1 (get-something bloomy) but I also ran into similar assertion not in expectation type errors, and the indentation in emacs was insane. I expect a macro might be the answer? So, how would you solve 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Structing Clojure tests/setup and tear down
Hi Ulises, I don't think I am as that would require essentially a fixture per distinct combinations of test state, which is almost the same number of tests. Have I missed something? On 21 May 2013 15:51, Ulises ulises.cerv...@gmail.com wrote: Perhaps you're looking for fixtures? http://thornydev.blogspot.co.uk/2012/09/before-and-after-logic-in-clojuretest.html U On 21 May 2013 15:17, Colin Yates colin.ya...@gmail.com wrote: Howdy, I am using clojure.test and have some questions of how to write idiomatic Clojure. This really isn't about testing at all per-se. First - I know about fixtures to get (at least) the same as JUnit's before/after behaviour. My code is a bloomy. You can configure the bloomy and it does different things based on that behaviour. Pretty much every test has a different bloomy, *and* that bloomy must be elegantly shut down. How should I handle this? At the moment I have the most un-idiomatic way and blunt way of : [code] (deftest my-test (let [bloomy (create-a-bloomy] (try (do-something-with-my-bloomy) (is (=)) (finally (shut-down bloomy [/code] Yep, try/finally in every test - reminds me of early JDBC libraries before Spring :). If I understand it correctly, I would end up writing a separate fixture for each and every test, or at least each any every unique set of test context. I did consider writing a (defn with-bloomy [bloomy test] (try (test) (finally (shut-down bloomy but I couldn't figure out how to pass my bloomy into the test itself. I also received lots of assertion not in expectation type errors. To be explicit I would use this as (with-bloomy (create-a-bloomy) (deftest...))). I did consider a variation on the above of passing in a function which only contained the assertions, so (deftest my-test (let [bloomy...] (with-bloomy bloomy #(is (= 1 (get-something bloomy) but I also ran into similar assertion not in expectation type errors, and the indentation in emacs was insane. I expect a macro might be the answer? So, how would you solve 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/Pm-DUDxWeM4/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Structing Clojure tests/setup and tear down
Thanks Gaz, I was expecting a macro to be the answer, and seeing how you have used a macro to glue together two functions is really helpful, so thanks a bunch! On 21 May 2013 16:21, gaz jones gareth.e.jo...@gmail.com wrote: I think I would use a macro: (defn with-bloomy-fn [bloomy body] (try (body) (finally (shut-down bloomy (defmacro with-bloomy [bloomy body] `(with-bloomy-fn ~bloomy (fn [] ~@body))) (deftest my-test (with-bloomy (create-a-bloomy) (...)) FYI code is untested, typing straight in so there may be typos etc. On Tue, May 21, 2013 at 10:05 AM, Colin Yates colin.ya...@gmail.comwrote: Hi Ulises, I don't think I am as that would require essentially a fixture per distinct combinations of test state, which is almost the same number of tests. Have I missed something? On 21 May 2013 15:51, Ulises ulises.cerv...@gmail.com wrote: Perhaps you're looking for fixtures? http://thornydev.blogspot.co.uk/2012/09/before-and-after-logic-in-clojuretest.html U On 21 May 2013 15:17, Colin Yates colin.ya...@gmail.com wrote: Howdy, I am using clojure.test and have some questions of how to write idiomatic Clojure. This really isn't about testing at all per-se. First - I know about fixtures to get (at least) the same as JUnit's before/after behaviour. My code is a bloomy. You can configure the bloomy and it does different things based on that behaviour. Pretty much every test has a different bloomy, *and* that bloomy must be elegantly shut down. How should I handle this? At the moment I have the most un-idiomatic way and blunt way of : [code] (deftest my-test (let [bloomy (create-a-bloomy] (try (do-something-with-my-bloomy) (is (=)) (finally (shut-down bloomy [/code] Yep, try/finally in every test - reminds me of early JDBC libraries before Spring :). If I understand it correctly, I would end up writing a separate fixture for each and every test, or at least each any every unique set of test context. I did consider writing a (defn with-bloomy [bloomy test] (try (test) (finally (shut-down bloomy but I couldn't figure out how to pass my bloomy into the test itself. I also received lots of assertion not in expectation type errors. To be explicit I would use this as (with-bloomy (create-a-bloomy) (deftest...))). I did consider a variation on the above of passing in a function which only contained the assertions, so (deftest my-test (let [bloomy...] (with-bloomy bloomy #(is (= 1 (get-something bloomy) but I also ran into similar assertion not in expectation type errors, and the indentation in emacs was insane. I expect a macro might be the answer? So, how would you solve 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/Pm-DUDxWeM4/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups
Re: Structing Clojure tests/setup and tear down
No worries ;) On 21 May 2013 17:18, Ulises ulises.cerv...@gmail.com wrote: Hey Colin, Apologies, I missed your First - I know about fixtures... line :) I'd probably +1 Gaz's macro (I've not tested it either but it looks reasonable.) On 21 May 2013 16:05, Colin Yates colin.ya...@gmail.com wrote: Hi Ulises, I don't think I am as that would require essentially a fixture per distinct combinations of test state, which is almost the same number of tests. Have I missed something? On 21 May 2013 15:51, Ulises ulises.cerv...@gmail.com wrote: Perhaps you're looking for fixtures? http://thornydev.blogspot.co.uk/2012/09/before-and-after-logic-in-clojuretest.html U On 21 May 2013 15:17, Colin Yates colin.ya...@gmail.com wrote: Howdy, I am using clojure.test and have some questions of how to write idiomatic Clojure. This really isn't about testing at all per-se. First - I know about fixtures to get (at least) the same as JUnit's before/after behaviour. My code is a bloomy. You can configure the bloomy and it does different things based on that behaviour. Pretty much every test has a different bloomy, *and* that bloomy must be elegantly shut down. How should I handle this? At the moment I have the most un-idiomatic way and blunt way of : [code] (deftest my-test (let [bloomy (create-a-bloomy] (try (do-something-with-my-bloomy) (is (=)) (finally (shut-down bloomy [/code] Yep, try/finally in every test - reminds me of early JDBC libraries before Spring :). If I understand it correctly, I would end up writing a separate fixture for each and every test, or at least each any every unique set of test context. I did consider writing a (defn with-bloomy [bloomy test] (try (test) (finally (shut-down bloomy but I couldn't figure out how to pass my bloomy into the test itself. I also received lots of assertion not in expectation type errors. To be explicit I would use this as (with-bloomy (create-a-bloomy) (deftest...))). I did consider a variation on the above of passing in a function which only contained the assertions, so (deftest my-test (let [bloomy...] (with-bloomy bloomy #(is (= 1 (get-something bloomy) but I also ran into similar assertion not in expectation type errors, and the indentation in emacs was insane. I expect a macro might be the answer? So, how would you solve 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 --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/Pm-DUDxWeM4/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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
Re: A blocking lazy sequence populated by multiple worker threads
Can you not use http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/LinkedBlockingQueue.html? That will provide the blocking element. To execute N (i.e. 10 in your example) use a http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html. The 'glue' would be an infinite loop which .takes from the incoming sequence (which could also be a LBQ) and then puts it on the thread pool. That gets stuff happening in parallel. To consume the results of that stuff in a sequence have a(nother) LBQ which the consumers consume (using the blocking .take) and have the glue code wrap the function it received from the LBQ in a function which takes the result of that function and puts it on the sequence. This looks like (clojure forgiveness is required): [code] (def incoming-queue (javaLinkedBlockingQueue.)) (def outgoing-queue (javaLinkedBlockingQueue.)) (def workers (java... some thread pool/executor.)) ; the following would need to reify itself to be a Runnable, not got that far yet :) (defn execute [job result-queue] (let [result (job)] (.put result-queue result))) (def stop-loop (atom false)) (while (not @stop-loop) (def next (.take incoming-queue)) (execute next outgoing-queue)) [/code] A few caveats/notes: - this uses a lot of Java constructs - that is fine. It is perfectly idiomatic to use the right Clojure or Java constructs. LBQs rock. - the above won't compile and the 'execute' needs to return a Runnable - not sure how. - it ties up a worker thread until the result can be put onto the outgoing LBQ. If the outgoing LBQ is bounded and you don't have enough consumers then eventually all the worker threads will be effectively idle until the results can be consumed. - if you didn't want to use a ThreadPool then you could update 'executor' to maintain an (atom) number of currently executing jobs. The glue code is single threaded so no chance of multiple jobs starting in parallel. The single threaded 'cost' is fine as it is doing nothing other than moving things around. I am a (Clojure) newbie so be warned! I fully look forward to somebody providing a much nicer and more idiomatic Clojure implementation :). Hope this helps. Col On Thursday, 30 May 2013 06:19:29 UTC+1, Artem Boytsov wrote: Hello, folks! I'm a relative noob in Clojure especially when it comes to concurrency, so please forgive my ignorance. I have a processing stage (producer) that feeds to another one (consumer). The producer has a bunch of items to process and it's I/O blocking which takes random time, but the order of the items is insignificant, so ideally they would materialize on the consumer side on the first come first serve basis. I would like to create a blocking lazy sequence I could just give to the consumer. I know how to create a lazy sequence (lazy-seq), or how to make it run in background and block on results (seque), but what I can't wrap my head around is how parallelize the processing the Clojure way. I was considering kicking off multiple agents, but how can I wait for *any one *of them to finish, not all of them (as await does)? I'm not sure but I think the same goes for futures/promises. I could have multiple agents putting the results into some shared sequence, but then how do I block on the sequence itself? What I'm trying to do can be described in the following way in a silly imperative pseudo-code: workers = new Worker[10] ; initially w.got_data == nil for each x in source_data: w = wait_for_any_worker_ready(workers) ; initially all of them are ready if (w.got_data) output.enqueue(w.data); the consumer will read output in a blocking way w.process(x) ; non-blocking, kicks off in the background Or, another way to describe it, given a seq of integers: [ 1, 2, 3, 4 ... ] and a simple function with a variable delay: (defn process [x] (Thread/sleep (* 1 (rand))) (* 2 x)) How can I write a function which would return a blocking lazy sequence of processed integers, in arbitrary order, parallelizing the processing in up to 10 threads? Thank you! Artem. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: A blocking lazy sequence populated by multiple worker threads
Nice. On 30 May 2013 12:57, John D. Hume duelin.mark...@gmail.com wrote: On May 30, 2013 4:12 AM, Colin Yates colin.ya...@gmail.com wrote: ; the following would need to reify itself to be a Runnable, not got that far yet :) (defn execute [job result-queue] (let [result (job)] (.put result-queue result))) A no-args fn is both a perfectly good Callable and a perfectly good Runnable, making interop with java.util.concurrent pretty painless. So it takes as little as #(execute my-job my-queue) -- -- You 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/C6JRJfruoQA/unsubscribe?hl=en. To unsubscribe from this group and all its topics, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Please stand firm against Steve Yegge's yes language push
I think we need to be careful here about the association between Java and Clojure. Sure, they run on the JVM, but that is their *only* relationship (from a consumer's point of view) as far as I can see. For me, after a decade+ of developing Enterprise Java (primarily web) applications I am sick and tired of all the hoops and ceremony involved in building Java applications. More and more I am coming (from reading other people's work - not my own discovery!) to realise that most established best-practice is only required to answer an insufficiency in the language itself. The thing that most sold me on Clojure (rather than Scala, the main other contender) was the simplicity of the language itself and the low ceremony build-process. To this end, I am absolutely *not* interested in having to live inside a huge complex bit of machinery in order to productively write programs. Eclipse and IntelliJ (and ilk) are necessary for serious Java development mainly because they take the implicit weight of Java applications. I would see it as a failing (maybe too strong) if Clojure required either that much machinery. So, for me, and I appreciate this is maybe unique, I want to go back and basics and learn Clojure properly. Getting Clojure installed in my nice familiar Java IDE _might_ send the wrong, and very dangerous message that Clojure is on a migration path from Java, when, to my mind, it isn't. It is a completely different language, right down to the fundamental build-deploy cycle. I guess I am saying how much of IDE _whatever_'s functionality is actually helpful in building Clojure applications? As I understand it, large, deep nested packages (a sign of a nicely decomposed Java system) probably isn't the right thing in Clojure. Refactoring support probably isn't required as much because Clojure *seems* easier to write the right thing first time I am being naive and simplistic, but hopefully you get my point. I absolutely get that saying forget IDE _whatever_ and use Emacs isn't the right thing either, but I do think there is something good about a message of Clojure is a LISP, which have certain behaviours of development, Emacs is designed for that very purpose and whilst you can use IDE X, maybe you are trying to fit a square peg into a ridiculously heavy and complex hole. I too was pretty disillusioned when, after reading about the purity of development with the REPL and the bliss that is LISP development in emacs it turned out that after hours trying to get it all configured, I still couldn't get it working A downloaded VM, or a vagrant/ puppet/chef/one line batch/sh script file orr windows (or statically compiled tar.gz) executable would have made life much much simpler. P.S To be transparent, although I have written millions of LOC of Java on trivial and large enterprise systems, I have written 3 lines of Clojure code, along the lines of (+ 1 2 3). I have spent many hours thinking about what solutions look like in a functional language and have read 4 books on Clojure, so I am viewing this from afar. -- You 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: Please stand firm against Steve Yegge's yes language push
If it weren't for McDonalds I wouldn't have such a large belly, but my belly isn't McDonalds ;) I jest (obviously!), but I do think this is a fundamental point. I (like a lot of others I expect) found Clojure and Scala whilst looking for Java.next. I read a bit about Scala, and part of its marketing is that there is no learning curve to start writing Scala applications, due to Scala being a hybrid OO and functional language. On the other hand, the very first thing I started doing when thinking how do I wield this Clojure tool was trying to see how I can use it to make OO solutions. And the answer was painfully - *because I was asking the wrong question*. Clojure != Java - different paradigms, different mindsets, different beasts. Trying to write Java in Clojure seems to be entirely the wrong thing to do. Write Java in Scala is a recommended on-ramp to integrating Scala in your organisation. Clarifications: I use Java to mean more than the language, I use it to mean the typical shape of implemented solutions using the Java programming language, i.e. OO with anaemic domain models and a fair chunk of XML and/or annotations. I keep mentioning Scala because this whole thread seems to be about newbie experience (where newbie is in reference only to Clojure) and I suspect most newbies will be thinking about Scala as well. On Jul 8, 7:15 pm, Jonathan Fischer Friberg odysso...@gmail.com wrote: I don't agree that clojure is, or should be seen as something entirely different than java. If it weren't for java, clojure wouldn't have much use at all. --- snip I think we need to be careful here about the association between Java and Clojure. Sure, they run on the JVM, but that is their *only* relationship (from a consumer's point of view) as far as I can see. For me, after a decade+ of developing Enterprise Java (primarily web) applications I am sick and tired of all the hoops and ceremony involved in building Java applications. More and more I am coming (from reading other people's work - not my own discovery!) to realise that most established best-practice is only required to answer an insufficiency in the language itself. --- snip -- You 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
Recommendation for Clojure Enterprise Development toolkit
*This isn't meant to start a flame-war!* I am pretty convinced that I want to use Clojure as my primary tool (in place of Java/Groovy Spring and Hibernate) in writing Enterprise applications on the JVM. By Enterprise I mean that my solution has to be very stable, maintainable by others, subject to a number of stake- holders and so on. Part of the attraction of Java is the set of well-established tools for certain things: - maven/gradle/ant for building - Spring for glue and a gazillion other things (disclaimer: I used to work for them as a Consultant) - Hibernate for ORM - JUnit/TestNG - and so on I am convinced that Clojure offers a different playing field in terms of building blocks; due to its power it seems that there isn't the need for such heavyweight players, rather rolling your own, or using light-weigh libraries seems to possible. That is excellent news, but I need to start somewhere. So, what do other enterprise developers use? There are a gazillion libraries out there but where do you start? For example (religious war starts now): - cake seems to be a superset of lein but lein seems to be the preferred choice - which should a newbie go with - what behaviour driven testing (i.e. BDD) library would you use (for integration tests) - which unit testing framework do you use (lazy-test's watch method is very appealing) - which CI servers have you integrated Clojure with, and how? - which other high quality libraries can you recommend (akin to JodaTime) Basically, what supporting infrastructure do you guys use to build large Clojure apps. I hope the gist of this request comes through - I, of course, should try them all, but if recommendations are always welcome. -- You 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: Recommendation for Clojure Enterprise Development toolkit
Nobody in industry seriously considers Clojure for enterprise systems. Your argument is internally inconsistent as I am in industry and seriously considering Clojure for enterprise systems. On 9 July 2011 09:29, MarkH markhanif...@gmail.com wrote: As a tech lead or architect you should be fired for even suggesting to use Clojure as an enterprise greenfield. Industry and academia is moving towards advanced type systems. Nobody in industry seriously considers Clojure for enterprise systems. On Jul 8, 12:43 pm, Colin Yates colin.ya...@gmail.com wrote: *This isn't meant to start a flame-war!* I am pretty convinced that I want to use Clojure as my primary tool (in place of Java/Groovy Spring and Hibernate) in writing Enterprise applications on the JVM. By Enterprise I mean that my solution has to be very stable, maintainable by others, subject to a number of stake- holders and so on. Part of the attraction of Java is the set of well-established tools for certain things: - maven/gradle/ant for building - Spring for glue and a gazillion other things (disclaimer: I used to work for them as a Consultant) - Hibernate for ORM - JUnit/TestNG - and so on I am convinced that Clojure offers a different playing field in terms of building blocks; due to its power it seems that there isn't the need for such heavyweight players, rather rolling your own, or using light-weigh libraries seems to possible. That is excellent news, but I need to start somewhere. So, what do other enterprise developers use? There are a gazillion libraries out there but where do you start? For example (religious war starts now): - cake seems to be a superset of lein but lein seems to be the preferred choice - which should a newbie go with - what behaviour driven testing (i.e. BDD) library would you use (for integration tests) - which unit testing framework do you use (lazy-test's watch method is very appealing) - which CI servers have you integrated Clojure with, and how? - which other high quality libraries can you recommend (akin to JodaTime) Basically, what supporting infrastructure do you guys use to build large Clojure apps. I hope the gist of this request comes through - I, of course, should try them all, but if recommendations are always welcome. -- You 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: Recommendation for Clojure Enterprise Development toolkit
Hi Jonathon, I did see that thread, but most of the (excellent and useful) advice was around programming practices/idiomatic Clojure if I remember correctly. I am for tool recommendations as well I guess. I will re-read that thread though - thanks for the link. Col P.S. Is there a place (wiki) somewhere that non-contributors can start collecting this pearls of wisdom? On 9 July 2011 11:31, Jonathan Fischer Friberg odysso...@gmail.com wrote: That's not very constructive at all. I think clojure would work fine (or better) for enterprise applications. The one thing that could pull it down is maintainability, as the maintainers must know clojure. There was recently a thread about working on large programs in clojure. It might contain some useful info; http://groups.google.com/group/clojure/browse_thread/thread/edd07e750511e461# Jonathan On Sat, Jul 9, 2011 at 10:29 AM, MarkH markhanif...@gmail.com wrote: As a tech lead or architect you should be fired for even suggesting to use Clojure as an enterprise greenfield. Industry and academia is moving towards advanced type systems. Nobody in industry seriously considers Clojure for enterprise systems. On Jul 8, 12:43 pm, Colin Yates colin.ya...@gmail.com wrote: *This isn't meant to start a flame-war!* I am pretty convinced that I want to use Clojure as my primary tool (in place of Java/Groovy Spring and Hibernate) in writing Enterprise applications on the JVM. By Enterprise I mean that my solution has to be very stable, maintainable by others, subject to a number of stake- holders and so on. Part of the attraction of Java is the set of well-established tools for certain things: - maven/gradle/ant for building - Spring for glue and a gazillion other things (disclaimer: I used to work for them as a Consultant) - Hibernate for ORM - JUnit/TestNG - and so on I am convinced that Clojure offers a different playing field in terms of building blocks; due to its power it seems that there isn't the need for such heavyweight players, rather rolling your own, or using light-weigh libraries seems to possible. That is excellent news, but I need to start somewhere. So, what do other enterprise developers use? There are a gazillion libraries out there but where do you start? For example (religious war starts now): - cake seems to be a superset of lein but lein seems to be the preferred choice - which should a newbie go with - what behaviour driven testing (i.e. BDD) library would you use (for integration tests) - which unit testing framework do you use (lazy-test's watch method is very appealing) - which CI servers have you integrated Clojure with, and how? - which other high quality libraries can you recommend (akin to JodaTime) Basically, what supporting infrastructure do you guys use to build large Clojure apps. I hope the gist of this request comes through - I, of course, should try them all, but if recommendations are always welcome. -- You 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: Modelling complex data structures (graphs and trees for example)
of Clojure :) On 8 July 2011 20:57, James Keats james.w.ke...@gmail.com wrote: On Jun 16, 3:08 pm, Colin Yates colin.ya...@gmail.com wrote: (newbie warning) Our current solution is an OO implementation in Groovy and Java. We have a (mutable) Project which has a DAG (directed acyclic graph). This is stored as a set of nodes and edges. There are multiple implementations of nodes (which may themselves be Projects). There are also multiple implementations of edges. My question isn't how to do this in a functional paradigm, my first question is *how do I learn* to do this in a functional paradigm. I want to be able to get the answer myself ;). To that end, are there any domain driven design with functional programming type resources? A more specific question is how do I model a graph? These graphs can be quite extensive, with mutations on the individual nodes as well as the structure (i.e. adding or removing branches). Does this mean that every every node would be a ref? I think the general answer is that the aggregate roots are refs, meaning they are an atomic block, but is there any more guidance? May I humbly suggest that this ought to be a database-ish concern rather than a middleware one? have you looked at neo4j for example? A quick google found this: http://wiki.neo4j.org/content/Roles This is an implementation of an example found in the article A Model to Represent Directed Acyclic Graphs (DAG) on SQL Databases by Kemal Erdogan. ... In Neo4j storing the roles is trivial, as working with graphs is what Neo4j was designed for I would humbly suggest that you use as much of the database functionality as possible for your data needs and avoid replicating it in your middleware. I hope this works. :-) -- You 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: Modelling complex data structures (graphs and trees for example)
he he :) Well, conservative might be a run-of-the-mill Java/Spring/Hibernate application with all of that fun as those are the tools which I am most familiar with. I am not going to type another long email, but it is interesting how people define risk and conservative. I *do not* think doing the same thing as always and hope for the best is the right answer. If the question is give us something that takes years to develop and can be maintained by a team of interchangable average devs doing the same old thing then sure - this is not the answer - in any way :). I think the question being asked is can you provide a solution which allows us to respond very quickly to changing requirements that will be developed by yourself and whoever else you think you need and just maybe this is the right answer...who knows - it is all an experiment. I am very fortunate that I am paid to work in an organisation where any technical solution is evaluated based on I know how to design, which are the right tools rather than the *very* entrenched I know some tools, what can I build with them. It might have something to do with me being the technical authority here...not sure :)! On 9 July 2011 16:25, James Keats james.w.ke...@gmail.com wrote: Well if it's a project you own then you're free to do whatever you want, but if you're only an employee then I urge you to consider carefully what you're about to do, and be as conservative as you could be about it. :-) On Jul 9, 2:15 pm, Colin Yates colin.ya...@gmail.com wrote: I did think about moving this logic to the database, but I am toying around with a different model - having the entire data set in memory (possibly across multiple nodes using messaging infrastructure to communicate). The reason for this is: - writes are very small but reads are very high - each read typically requires complex processing - most operations cover a large part of the entire dataset Paying the cost of having the entire data set *efficiently* available for the application (Clojure in this case) means: - less dependence on (probably hard to test) yet-another-bit-of-tech. Integration testing DAOs or Repositories always seems like a lot of work. Reducing the technical pieces just makes things much easier - I am hoping clever use of persistent structures will help here, as there is a lot of commonality in the data itself (i.e. 5 projects might actually share 80% of the same state). Clever use in constructing these might pay dividends... - I don't think I can offload *all* processing onto a third party technology so I need the ability to deal with large data sets in memory with real-time (whatever that means) - if I need it for one, I may as well use it for all. Ambitious, and full of hairy concerns! But the idea of moving away from single-threaded web-based applications with big powerful data engines to a single chunk of logic that occasionally throws state to a fairly dumb persistent store is certainly not new ground, and seems to offer a much more powerful architecture. For example, dealing with historical data is always a pain point. What I want is the ability to snapshot the entire system whenever anything changes, to allow us to see how the system (or client rather) has improved. In a relational database, this would be ridiculous, so I captured a snapshot of interesting data. Tomorrow they realise that something else was interesting We also played with document stores (MongoDB) which makes the job much much smaller - just cloning a single document (and related data), but then it has to be hydrated, so for ease of use a snapshot is taken every X period, even if the data hasn't changed. Yuck. Now Clojure appears, with its extremely efficient (in terms of memory) way of storing data, and suddenly it feels like storing a representation every time the structure changes (which is only once or twice a week) and then realising the entire history in memory is now do-able. This means if a Project only changed 5 times over a 3 month period there would only be 5 instances of that project in storage. Calculating how each project contributes to a historical chart broken down by day (or hour whatever) is much much easier to do in Java/Clojure/whatever than third party store of choice. I am asserting that providing a sequence for a project for every day over the last year when there are only 5 snapshots will certainly not consume sizeOfProject * daysInYear memory. (Not sure that was the best example of the pain points I am trying to solve actually :), but anyway). I guess, after 15 years of using the web, app-logic, database template-cutter I am giving myself a clean piece of paper and asking what do you want to do and what is the simplest way to do it, and keeping everything in the application layer (rather than the persistence layer) seems
Re: Modelling complex data structures (graphs and trees for example)
Nice link - many thanks On 9 July 2011 17:27, Benny Tsai benny.t...@gmail.com wrote: Hi Colin, Sorry, a bit late to the party here, but it might be worth taking a look at Jeffrey Straszheim's c.c.graph library to see one way of modeling DAG's and implementing various graph operations (such as topological sort and computing strongly connected components) in Clojure: API: http://clojure.github.com/clojure-contrib/graph-api.html Source: https://github.com/clojure/clojure-contrib/blob/master/modules/graph/src/main/clojure/clojure/contrib/graph.clj Note that in the library, graphs are represented by a directed-graph struct (defined at the top of the source file) with two fields: - nodes: a collection of the nodes in the graph - neighbors: a function that takes a node and returns a collection of that node's neighbors Since Clojure maps are also functions that will return the value associated with a key when called with the key, neighbors can simply be a map of nodes to collections of neighbors. records are now recommended over structs, so it may be better to define a directed-graph record: (defrecord directed-graph [nodes neighbors]) A graph (for example, a graph of two nodes :a and :b that are connected to each other) can then created via: (def my-graph (directed-graph. [:a :b] {:a [:b], :b [:a]})) records can be used in exactly the same way as structs, so this can be used right away with all the functions defined in the library. Hope this helps! -- You 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: Recommendation for Clojure Enterprise Development toolkit
I think he was being sarcy :) On 9 July 2011 22:03, Sean Corfield seancorfi...@gmail.com wrote: On Sat, Jul 9, 2011 at 1:52 PM, Shree Mulay shreemu...@gmail.com wrote: Clojure REALLY isn't ready for Enterprise level development. That's your opinion but I expect there are enterprise companies using Clojure already who just have a policy of not talking publicly about their technology choices... Again, your answer doesn't address the OP's question about tooling... -- 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 -- You 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: Recommendation for Clojure Enterprise Development toolkit
But then how would all the consultants make their money? ;) Sent from my iPad On 10 Jul 2011, at 04:56, Luc Prefontaine lprefonta...@softaddicts.ca wrote: Hey, if it does not take a year and an army of nuclear scientists to implement, it would already be better : On Sun, 10 Jul 2011 09:22:18 +0530 Vivek Khurana hiddenharm...@gmail.com wrote: On Sun, Jul 10, 2011 at 9:06 AM, Luc Prefontaine lprefonta...@softaddicts.ca wrote: Maybe we should create something better than SAP :) Not exactly better than SAP, but I am working on a business management framework based on clojure. regards Vivek -- 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 -- You 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: Results from 2011 State of Clojure survey
What other new shiny languages are there with any traction? Scala, and maybe F#? new and traction are pretty subjective. Sometimes (as in my case) the searcher just needs enough to sell themselves on the tool they have already chosen, i.e. just enough facts to fit my theory. FWIW, I like clojure.org the way it is. Without sounding like a complete muppet, I think of Clojure as a set of surgeon's tools, all clean and layed out on a shiny metal tray. Minimalist, simple, clean and massively effective once you have thought about it are the attributes I associate with Clojure and clojure.org fits that. On the other hand, I think of Scala as a bunch of handy man tools in a bag, slightly less coherent, messy and a bit more excitable and scala-lang.org re-enforces that. My three lines of Clojure are significantly more than the zero lines of scala I have written :) On 12 July 2011 09:25, Ken Wesson kwess...@gmail.com wrote: On Tue, Jul 12, 2011 at 4:22 AM, Sergey Didenko sergey.dide...@gmail.com wrote: Public relations -- Project status and activity. This area seems to suggest the main Clojure page should be covered in tickers and feeds of various kinds I think the main site needs just a pane with a big noticeable header News, that shows one-two latest important stories and updates one time per 5-15 days. Also has a link, a few links on where to read much more news (feeds for blogs, aggregators, twitters, etc). It's purpose not to create clutter, but to give an impression that Clojure is not outdated for a random visitor. I know what the purpose would be. And also what the effect would be if it was done badly, say by cramming every remotely relevant news feed onto the front page. :) Just a script that updates the date can backfire very badly if other site areas look outdated in the eyes of a random visitor. ? When people are looking for a new shiny thing among 100 of other just new things, they can turn into scanning mode despite the fact that in other conditions they do that sort of analytical comprehension What other new shiny languages are there with any traction? Scala, and maybe F#? -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- You 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: Results from 2011 State of Clojure survey
That sounds more like Enterprise Java Development to me :) On 12 July 2011 13:20, Adam Burry abu...@gmail.com wrote: On Jul 12, 7:58 am, Colin Yates colin.ya...@gmail.com wrote: FWIW, I like clojure.org the way it is. Without sounding like a complete muppet, I think of Clojure as a set of surgeon's tools, all clean and layed out on a shiny metal tray. Minimalist, simple, clean and massively effective once you have thought about it are the attributes I associate with Clojure and clojure.org fits that. On the other hand, I think of Scala as a bunch of handy man tools in a bag, slightly less coherent, messy and a bit more excitable and scala-lang.org re-enforces that. You've never seen a surgery up close. Many of the tools are wrapped in plastic and you need a helper to find them, open them, hand them to you, and clean them. You've got so many layers on you can't feel anything. The patient is moaning with pain and draped in so much stuff you can hardly tell they are human. And for big jobs you use the same Black and Decker tools that home builders use. Adam -- You 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: Results from 2011 State of Clojure survey
Besides the languages itself, the outsider wants to evaluate libraries, community, platforms, support, etc. That could be much more challenging than comparing a few bare languages. Absolutely! I asked a couple of times for recommendations, and was quite surprised at the lack of forthcoming recommendations. The dilemna that I am for-ever battling is get something done in a poor way now or invest in something so we can do it better in the future. Adopting Clojure is definitely in the second camp (for me), and the lack of knowing which supporting libraries (for example) to use makes it more of an expense. Of course, what I want to do is plough that ground myself and produce a single 101 Enterprise Clojure Development but time time time. The professional me wants/needs it done for me, the geek in me wants to do it myself and give back to the community. (since I opened the door :)): my current thoughts are: - clojure 1.3 (complete with integration pain with 1.2 libraries) - maven 2 (with maven 3 polyglot once it is stablised and publicly available) with the clojure-maven plugin - bamboo (hence the maven decision rather than cake or lein) for CI and release management - cucumber for higher level does it do the requirements tests (not getting hung up on the highly overloaded testing terminology) - lazy-test for does the code do what the developer expects tests - emacs/slime for coding - some ring based web framework (probably clojure) - either mongodb or a graph database for persistence (need to determine the inter-relatedness of the graphs) - the venerable git - one of the gazillion high quality Clojure libraries on github As an enterprise developer I need to be able to come to those conclusions myself, of course, but some sign posts would be very useful. http://planet.clojure.in/, http://ericlavigne.wordpress.com/2011/01/30/a-tour-of-the-clojure-landscape/ , http://www.clojure-toolbox.com/ etc. are very useful points. The more I look, the more I am extremely impressed by the high quality blogs around Clojure, in particular http://cemerick.com, although that is one of many. (still only 3 lines of Clojure written!) On 12 July 2011 13:55, Sergey Didenko sergey.dide...@gmail.com wrote: You know that from inside. A Clojure outsider can have a completely other point of view. He can choose between Python, server side Javascript, new C#, Go, Scala, F#, Haskell, Erlang, haXe, Clojure. Besides the languages itself, the outsider wants to evaluate libraries, community, platforms, support, etc. That could be much more challenging than comparing a few bare languages. On Tue, Jul 12, 2011 at 11:25 AM, Ken Wesson kwess...@gmail.com wrote: When people are looking for a new shiny thing among 100 of other just new things, they can turn into scanning mode despite the fact that in other conditions they do that sort of analytical comprehension What other new shiny languages are there with any traction? Scala, and maybe F#? -- You 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: The Last Programming Language
I find his videos very easy to watch - I think it was around a hour, but the time flies by. On 19 July 2011 14:16, Ken Wesson kwess...@gmail.com wrote: On Tue, Jul 19, 2011 at 6:00 AM, Adam Richardson simples...@gmail.com wrote: Watch the video and you'll see the comment Tim is referencing. Are you aware of the length of that video? -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- You 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: The Last Programming Language
Quite - you don't get the ants in your pants vibe from plain text :) On 19 July 2011 15:18, Ben Smith-Mannschott bsmith.o...@gmail.com wrote: On Tue, Jul 19, 2011 at 16:11, Ken Wesson kwess...@gmail.com wrote: On Tue, Jul 19, 2011 at 10:05 AM, Colin Yates colin.ya...@gmail.com wrote: I find his videos very easy to watch - I think it was around a hour, but the time flies by. An hour of Will Smith blasting aliens flies by. An hour of a talking head is better presented as text. An hour of talking head + slides is better presented as text + inline images. Particularly since text is searchable and video, for the foreseeable future, is not. :) True enough, though I should hasten to point out that Uncle Bob is an unusually entertaining talking head. // ben -- You 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: Alright, fess up, who's unhappy with clojurescript?
Absolutely nothing to add to the argument as such except to say that I am quite surprised at the level of resistance to James' thread. I can see the argument if this was the 'dev' mailing list. I have been reading this mailing list for a long while now (even if I haven't contributed much to it) but if this had been the first post I had read I would have a very negative opinion of the *clojure community*. It comes off as sounding like if you don't like what we do, go away - it is our way or the highway, which would be a terrible shame as I don't *think* that is the case? If I wanted that atmosphere there are plenty of other places to go. Sure, I get that James' email didn't really provide any points of discussion, it was more a moan (sorry James ;)), but so what - I don't see anybody shooting down ClojureScript - I love it type posts. And maybe a better response would be asking OK, this guy clearly doesn't get it - how can we improve our communication? Rich - we are *all* grateful and I expect I am not alone in being amazed at the technical marvel you have pulled out of the hat. But to be honest I think you need a thicker skin. Getting your strokes from the mailing list is dangerous at best. To be disheartened by one negative post in the midst of positive votes is a bit worrying. If this mailing list is for the community to discuss Clojure and ask Clojurians for help then these responses were inappropriate. If this mailing list is to big up Clojure then fine - but make that explicit. Col (surprisingly disappointed and feels strongly enough to send this at the risk of being called a troll himself!) P.S. Strongly opinionated communities that shoots down criticisms of the great leaders' achievements is unfortunately not breaking new ground - so stop this :) and move onto the next ground breaking tool! On 25 July 2011 08:38, Mark Derricutt m...@talios.com wrote: Oracle announced/talked about Nashorn at the recent JVM Languages summit, this is an Invoke Dynamic based Javascript runtime which is (aiming) for inclusion in JDK8. I do so hope however that someone manages to pull that out for a lets run this NOW on Java 7 as that would be a great improvement over rhino. On 25/07/2011, at 3:54 AM, Stuart Halloway wrote: Rhino is an implementation detail of the development platform. That implementation detail could and probably should change. -- You 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: Alright, fess up, who's unhappy with clojurescript?
+1 - I think an etiquette document needs to be written. On 25 July 2011 15:10, Steve stephen.a.lind...@gmail.com wrote: On Jul 25, 7:54 pm, James Keats james.w.ke...@gmail.com wrote: Best regards; love you, man, and sorry again for any misunderstanding or unintended miscommunication. My humble suggestion is when you find yourself in your 5th or 6th paragraph of an opinion piece there's a reasonable chance what you're writing belongs on your blog rather than here. - Steve -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com 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: Alright, fess up, who's unhappy with clojurescript?
The irony of +1 doesn't escape me, but +1 Sent from my iPad On 26 Jul 2011, at 20:15, Base basselh...@gmail.com wrote: +1 On Jul 26, 12:31 pm, Devin Walters dev...@gmail.com wrote: Let's stop feeding this thread and turn our attention toward healthy and productive discussion. This is my first and final post on this matter. Sent via Mobile On Jul 26, 2011, at 9:56 AM, James Keats james.w.ke...@gmail.com wrote: On Jul 26, 3:08 pm, Timothy Baldridge tbaldri...@gmail.com wrote: Hi Timothy, and thanks for your much-better-than-others' reply. Oh I will be washing my hands and be gone for sure, as coding and making things better is precisely what I offered in my OP, which was taken as a threat and I was told to start a separate mailing list for it; perhaps this community welcomes folks who don't know any better than to be invariably effusive for everything in it, but for those who do it it quite evidently has not been. But I think you need to understand what exactly it is that you are asking of Rich and the other ClojureScript devs whith your original comment. Rich's comment is not abnormal for the type of request you are making. I have seen his type of reply before. And what is it exactly I was asking of them?! I offered to singlehandedly fork and redo it. For a second let's try to cool down and see the logic process used in Clojure to start with. Standard Clojure was developed on the JVM...for one reason...it provides a platform to stand on while developing a new language. We already have a type system, GC, etc. Could Rich have developed all this from scratch? Sure, but we'd probably still be at Clojure 0.1, and no one would be using the language in production. Believe me, I've actually attempted writing Clojure in a lower level language (both PyPy and C++), and it's not pretty, the level of tools that exist for the JVM and the level of the JVMs themselves shaved years of development time off the creation of Clojure. No, sorry, this doesn't make sense. No reasonable person would've expected Rich to develop from scratch a type system, GC, etc. for javascript, and this has nothing to do with Google's Closure tools. What does this have to do with ClojureScript? Well I think it shows the thought process that Rich uses when developing a new language. He looks at his tools and finds platforms that make is life easier. So, let's for the sake of argument, enumerate the features of both sides of this question: jQuery: Understood by the JS community Helps manipulate the DOM Provides some UI routines Optimizes code size via minifiers Closure: Enforces a strict OOP model Provides Graphics routines (canvas) Provides DOM manipulation routines Provides many UI routines Provides encryption, networking, spellchecking, math libraries etc. Has a full optimizing compiler The cons of Closure is of course that it's not well understood by the JS community. But this really isn't a language for the JS community, so is that really a problem? I think Rich looked at both these options (and many more), and simply picked the right tool for the job at hand. No! I would never use Closure for a website I was writing in JS. It would be a major pain in the neck. But I plan on using Clojure and ClojureScript for my future web needs. Right, so you wouldn't use it in JS but you'd use it with an additional layer of indirection (translated from another language) that'd make working with it and reasoning about what's actually happening and debugging even more of a pain. Sorry, this doesn't make sense either. I have already addressed other points, such as favoring it for enforcing a strict OOP model as being an serious affront to the credibility of clojure's rationale and advocacy and that its optimizing compiler made sense back when most of the browsers out there were IE6 but is no longer a reasonable priority. Regards, and thanks again for your better-than-others' reply, I won't be coding anything though after all this and I'll still be gone. For sanity's sake, you guys ought to realize - for your own sake - that as things stand you surely won't be kicking butt with clojurescript. Just like you can write Clojure code and not care what Java is doing under the hood. Now you can write Clojure for the browser and not care about what JS is doing. __ So after taking that all into consideration, I'm confident, that if you took the time to develop a POC that showed that a jQuery based ClojureScript would be faster, smaller, and better than one developed with Clojure, Rich would probably switch in a heartbeat. But until you have hard evidence, it's really hard to convince anyone. 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
Good book on migrating from (Java) OO to FP
Hi all, Not sure whether this is good etiquette or not, but I wanted to praise http://oreilly.com/catalog/0636920021667. I found it pretty useful in bridging the gap between OO and FP. It isn't Clojure specific, but as a (well established) Java/OO guy, this helped me get FP. (not connected in anyway with the book or author other than through appreciation :)) -- You 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: Good book on migrating from (Java) OO to FP
It is only 80 or so pages which made it jump to the top of my queue :). There wasn't really any one thing, it just made lots of things click. He describes a FP construct or principle and then shows the Java implementation. I am currently in hammock time before I jump in with both feet, and My roadblock is seeing how I can implement things in a functional way. This book helped bridged that gap for me. My only criticism is that it was a bit too lightweight and short :) Sent from my iPad On 29 Jul 2011, at 22:04, ax2groin ax2gr...@gmail.com wrote: Can you provide a more detailed review? How did it help you? What area(s) that it focused on did you find most useful? I've been playing with Clojure for nearly a year now, but it has just been on my own. At work, however, it is just Java and C#. Of course, I've also got several computer books waiting to be read, so essentially I'm asking you to convince me to let this book jump the queue. :^) On Jul 29, 5:03 am, Colin Yates colin.ya...@gmail.com wrote: Hi all, Not sure whether this is good etiquette or not, but I wanted to praisehttp://oreilly.com/catalog/0636920021667. I found it pretty useful in bridging the gap between OO and FP. It isn't Clojure specific, but as a (well established) Java/OO guy, this helped me get FP. (not connected in anyway with the book or author other than through appreciation :)) -- You 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: What information does (:key x) convey?
+1 as well. Surely (start-date voyage) would be more explicit than (start voyage) though meaning there is no ambiguity for me; I would (incorrectly) assume (start voyage) was a mutator :) On 3 August 2011 18:22, Sean Corfield seancorfi...@gmail.com wrote: On Wed, Aug 3, 2011 at 10:03 AM, Brian Marick mar...@exampler.com wrote: ** It could mean there are no nasty surprises here. I vividly remember debugging a Smalltalk program and discovering what I'd been ignoring as a simple getter actually had hundreds of lines of code behind it. Using a keyword as a getter wouldn't have misled me so. (:start voyage) also makes it clear that the code is fast, whereas (start voyage) allows for anything - perhaps a leisurely calculation involving database queries. FWIW, that's what I take it to mean. If I see (start voyage) I assume start is a function that does something to voyage to return a value. If I see (:start voyage) it conveys both the simple accessor and voyage is a map-like structure which is potentially useful in understanding the code (without that hint, voyage is some opaque data structure). -- 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 -- You 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: Optimizing JDBC code
That assumption needs checking - first rule of performance analysis: check, don't guess :) For example, is the java code using an existing connection versus clojure creating one? I would also time the cost of creating 10 clojure maps of a similar structure. Finally - 100,000 is big enough to give a small heap size worriesare the jvm settings the same? Sent from my iPad On 6 Aug 2011, at 19:11, Shoeb Bhinderwala shoeb.bhinderw...@gmail.com wrote: I am loading about 100,000 records from the database with clojure.contrib.sql, using a simple query that pulls in 25 attributes (columns) per row. Most of the columns are of type NUMBER so they get loaded as BigDecimals. I am using Oracle database and the jdbc 6 driver ( com.oracle/ojdbc6 11.1.0.7.0). I am using clojure 1.2.1. The code is about 10 times slower than the same code written in Java using the JDBC API. Is there any way to speed this up? Type hints? Move to Clojure 1.3? I am assuming that most of the extra time is spent converting the results into Clojure maps. Does anybody have experience optimizing code to load data from the database? -- 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 -- You 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: Out of memory using pmap
The point is that sequentially the GC gets to remove stale entries so simplistically only 3000 records are in memory at any one time, in parallel processing all 9 can be in memory at the same time. Sent from my iPad On 6 Aug 2011, at 21:34, Shoeb Bhinderwala shoeb.bhinderw...@gmail.com wrote: You didn't understand my problem. The exact same code throws out of memory when I change map to pmap. My monthly data is evenly divided into 30 sets. For e.g total monthly data = 9 records, daily data size for each day = 3000 records. I am trying to achieve performance gain by processing the daily data in parallel. On Aug 6, 2:18 pm, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: Just a guess. If your daily data is huge you will be loading the data for only one day when using map and you will be loading the data for multiple days (equal to number of parallel threads) .. and may be this is the cause of the problem. Sunil. On Sat, Aug 6, 2011 at 11:40 PM, Shoeb Bhinderwala shoeb.bhinderw...@gmail.com wrote: Problem summary: I am running out of memory using pmap but the same code works with regular map function. My problem is that I am trying to break my data into sets and process them in parallel. My data is for an entire month and I am breaking it into 30/31 sets - one for each day. I run a function for each daily set of data using pmap, something like: (defn process-monthly-data [grp-id month year] (doall (pmap #(process-daily-data grp-id % month year) (range 31))) (defn process-daily-data [grp-id day month year] ( ;load and process daily data … )) When I run my function using regular map it works fine, but when I change it to pmap I get an OutOfMemoryException. What am I doing wrong? -- 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 -- You 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