Padding missing elements in a sequence of identical K/V maps

2013-11-19 Thread Colin Yates
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

2013-11-19 Thread Colin Yates
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

2013-11-19 Thread Colin Yates
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

2013-11-19 Thread Colin Yates
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?

2013-11-19 Thread Colin Yates
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

2013-11-20 Thread Colin Yates
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)

2013-11-20 Thread Colin Yates
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)

2013-11-24 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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?

2014-01-10 Thread Colin Yates
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

2014-01-15 Thread Colin Yates
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

2014-01-15 Thread Colin Yates
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...

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates


+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

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates
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.

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates
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

2014-02-04 Thread Colin Yates
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

2014-02-05 Thread Colin Yates
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)

2014-02-05 Thread Colin Yates
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?

2014-02-06 Thread Colin Yates
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

2014-04-08 Thread Colin Yates
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?

2014-04-08 Thread Colin Yates
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?

2014-04-08 Thread Colin Yates
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?

2014-04-08 Thread Colin Yates
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

2014-04-09 Thread Colin Yates
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

2014-04-09 Thread Colin Yates
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

2014-04-09 Thread Colin Yates
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

2014-04-09 Thread Colin Yates
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

2014-04-11 Thread Colin Yates
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

2014-04-11 Thread Colin Yates
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

2014-04-15 Thread Colin Yates
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)

2014-04-17 Thread Colin Yates
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?

2014-04-22 Thread Colin Yates
(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?

2014-04-22 Thread Colin Yates
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?

2014-04-22 Thread Colin Yates
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

2013-05-01 Thread Colin Yates
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

2013-05-01 Thread Colin Yates
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

2013-05-09 Thread Colin Yates
(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

2013-05-09 Thread Colin Yates
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

2013-05-10 Thread Colin Yates
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

2013-05-10 Thread Colin Yates
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?

2013-05-10 Thread Colin Yates
(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

2013-05-10 Thread Colin Yates
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

2013-05-10 Thread Colin Yates
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?

2013-05-10 Thread Colin Yates
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

2013-05-10 Thread Colin Yates
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?

2013-05-10 Thread Colin Yates
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?

2013-05-11 Thread Colin Yates
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?

2013-05-11 Thread Colin Yates
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

2013-05-15 Thread Colin Yates
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?

2013-05-15 Thread Colin Yates
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?

2013-05-15 Thread Colin Yates
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

2013-05-16 Thread Colin Yates
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?

2013-05-21 Thread Colin Yates
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

2013-05-21 Thread Colin Yates
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

2013-05-21 Thread Colin Yates
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

2013-05-21 Thread Colin Yates
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

2013-05-21 Thread Colin Yates
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

2013-05-21 Thread Colin Yates
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

2013-05-21 Thread Colin Yates
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

2013-05-30 Thread Colin Yates
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

2013-05-30 Thread Colin Yates
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

2011-07-08 Thread Colin Yates
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

2011-07-08 Thread Colin Yates
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

2011-07-08 Thread Colin Yates
*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

2011-07-09 Thread Colin Yates
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

2011-07-09 Thread Colin Yates
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)

2011-07-09 Thread Colin Yates
 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)

2011-07-09 Thread Colin Yates
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)

2011-07-09 Thread Colin Yates
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

2011-07-09 Thread Colin Yates
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

2011-07-10 Thread Colin Yates
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

2011-07-12 Thread Colin Yates
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

2011-07-12 Thread Colin Yates
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

2011-07-12 Thread Colin Yates
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

2011-07-19 Thread Colin Yates
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

2011-07-19 Thread Colin Yates
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?

2011-07-25 Thread Colin Yates
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?

2011-07-25 Thread Colin Yates
+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?

2011-07-26 Thread Colin Yates
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

2011-07-29 Thread Colin Yates
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

2011-07-29 Thread Colin Yates
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?

2011-08-03 Thread Colin Yates
+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

2011-08-06 Thread Colin Yates
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

2011-08-06 Thread Colin Yates
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


  1   2   3   4   5   6   >