Re: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes:

 On 17 October 2014 16:21, Phillip Lord phillip.l...@newcastle.ac.uk wrote:
 http://en.wikipedia.org/wiki/Uniform_access_principle

 To my knowledge, Clojure cannot do this.


 Yes, Clojure pretty much rejects the idea of uniform access.


I don't think it does. I think it just does not support it which is a
somewhat different thing.


  With regard to automatically :doc string, why can't you set it when the
 var
  is created?

 Two reasons. The first is specific to my library, which is that the var
 contains a mutable Java object. So the :doc string may change over time,
 independently of the value of the var. Don't use mutable objects would
 be an obvious response, but not a useful one in this case.


 If you're placing mutable objects in a top-level var, and having that var's
 docstring change based on their contents, that's a strong indication you're
 doing something wrong.


Yes, this is certainly a possibility.


 It sounds like you're trying to interoperate with a Java library that's
 very structured around OOP principles, and very hard to translate into
 idiomatic Clojure. My guess is that you wouldn't have the issues you
 mention in a pure Clojure solution.


Which is the actuality. While using mutable objects and global state may
be an indication that I am doing something wrong, my belief is that
starting a software project by ignoring existing java libraries and
rewriting everything in Clojure is a much bigger error. I got to a
usable piece of software in two months; this would not have happened
from scratch.

Still, although my example might appear irrelevant to Clojure in
general, I don't think it is. Clojure's current docstring support is not
very good (and there was a thread here about it not long ago). It would
be nice to have something richer. For really rich documentation,
maintaining the docstrings is a different file might make sense. Clojure
can support this at the moment, but only in the way that I have -- the
var metadata could be updated at load time. What it cannot do (easily)
is support lazy loading of the file documentation at the point of first
use, because the decision was made originally that :doc metadata is a
value and is NOT computed.

Phil


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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: Modelling in Clojure

2014-10-20 Thread Phillip Lord
Fluid Dynamics a2093...@trbvm.com writes:
 I don't know who is the outlier. The point is that Scala, for instance, 
 has explicit support to hide the distinction between accessing a value 
 and computing a value. The point is to support the uniform access 
 principle. 

 http://en.wikipedia.org/wiki/Uniform_access_principle 

 To my knowledge, Clojure cannot do this.


 It seems to me that some support could be created for this. Specifically, 
 we'd want to make it that a) (deref foo) on a non-IDeref just evaluates to 
 foo in a no-op, and furthermore that if foo is known at compile time not to 
 be an IDeref the (deref foo) compiles away to just foo, so has no runtime 
 cost; and b) (deref (delay (some-fcall))) amounts to (force (delay 
 (some-fcall))) and where the compiler knows the thing being derefed is a 
 delay (via type hint or whatever) is as efficient as just (some-fcall) at 
 run-time the first time called, and as efficient as ((constantly foo)) for 
 some value of foo thereafter.

 In that case, one could hide the computed-or-not nature of some data behind 
 expecting users to use @my-thing to access it, and if my-thing is not an 
 IDeref it is the same as my-thing, but it can be changed later to a delay 
 to make it a lazily-computed thing without breaking the API, and without 
 much runtime efficiency cost, given that the new object is hinted with 
 ^IDeref or something.


It's definately supportable. Symbol macros could also achieve the same
thing; Clojure has these, but not globally.

Phil


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes:

 On 18 October 2014 08:28, Mark Engelberg mark.engelb...@gmail.com wrote:

 Yeah, it's hard to deny the convenience of Clojure's keyword lookups and
 standard assoc mechanism for getting and setting stored values, but I think
 Bertrand Meyer's Uniform Access Principle reflects some pretty deep
 thinking about the kinds of complications that arise in maintaining large
 programs.  Although the Clojure community mostly rejects the Uniform Access
 Principle right now, as people start writing larger programs in Clojure,
 and need to maintain them for longer periods of time, it will be
 interesting to see if the pendulum swings back in favor of uniform access.


 You make it sound as if structuring an application around data, rather than
 APIs, is untested at scale. I'd argue the opposite: the only architecture
 we know works at scale is data driven.

 The largest systems we've developed, including the web itself, are data
 driven. 


Interesting. So, if you resolve http://www.clojure.org, is this data or
is it computed?

I don't think you can tell. The web supports the Uniform Access
Principle.

Phil

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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: Modelling in Clojure

2014-10-20 Thread Gary Verhaegen
On Monday, 20 October 2014, Phillip Lord phillip.l...@newcastle.ac.uk
wrote:

 Interesting. So, if you resolve http://www.clojure.org, is this data or
 is it computed?


You're dereferencing a ref (url) to get an immutable value (string).

Maybe it would be worth exploring ways to implement IDeref with custom data
types?

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Modelling in Clojure

2014-10-20 Thread James Reeves
On 20 October 2014 12:23, Phillip Lord phillip.l...@newcastle.ac.uk wrote:

 James Reeves ja...@booleanknot.com writes:

  Yes, Clojure pretty much rejects the idea of uniform access.


 I don't think it does. I think it just does not support it which is a
 somewhat different thing.


I thought it was pretty clear that Clojure prefers data over APIs. The
uniform access principle is about preferring APIs over data, which seems
counter to Clojure's ideology.


Still, although my example might appear irrelevant to Clojure in
 general, I don't think it is. Clojure's current docstring support is not
 very good (and there was a thread here about it not long ago). It would
 be nice to have something richer. For really rich documentation,
 maintaining the docstrings is a different file might make sense. Clojure
 can support this at the moment, but only in the way that I have -- the
 var metadata could be updated at load time. What it cannot do (easily)
 is support lazy loading of the file documentation at the point of first
 use, because the decision was made originally that :doc metadata is a
 value and is NOT computed.


There's no reason why you have to use the :doc metadata for that. Just
write another function that takes a var and spits out some documentation.


On 20 October 2014 12:26, Phillip Lord phillip.l...@newcastle.ac.uk wrote:

  The largest systems we've developed, including the web itself, are data
  driven.

 Interesting. So, if you resolve http://www.clojure.org, is this data or
 is it computed?

 I don't think you can tell. The web supports the Uniform Access
 Principle.


The response may be computed, but once it's sent to the client it's
immutable data. The response returned has no inherent API associated with
it.

To put it another way, consider the function:

(defn build-user [first-name last-name]
  {:first-name first-name
   :last-name last-name
   :full-name (str first-name   last-name)})

Like a website, a function may perform computations, but its return value
is immutable data. Would you say the above conforms the the Uniform Access
Principle?

- 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 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: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes:
  Yes, Clojure pretty much rejects the idea of uniform access.


 I don't think it does. I think it just does not support it which is a
 somewhat different thing.


 I thought it was pretty clear that Clojure prefers data over APIs. The
 uniform access principle is about preferring APIs over data, which seems
 counter to Clojure's ideology.

The uniform access principle is about having uniform access to data and
APIs. It's not about prefering one or the other.


 Still, although my example might appear irrelevant to Clojure in
 general, I don't think it is. Clojure's current docstring support is not
 very good (and there was a thread here about it not long ago). It would
 be nice to have something richer. For really rich documentation,
 maintaining the docstrings is a different file might make sense. Clojure
 can support this at the moment, but only in the way that I have -- the
 var metadata could be updated at load time. What it cannot do (easily)
 is support lazy loading of the file documentation at the point of first
 use, because the decision was made originally that :doc metadata is a
 value and is NOT computed.


 There's no reason why you have to use the :doc metadata for that. Just
 write another function that takes a var and spits out some documentation.

Yes, which is what I have done, of course. Now it won't work in any IDE
which looks for the docstring as :doc metadata. It is totally
unextensible. I do not think that this is good.



  The largest systems we've developed, including the web itself, are data
  driven.

 Interesting. So, if you resolve http://www.clojure.org, is this data or
 is it computed?

 I don't think you can tell. The web supports the Uniform Access
 Principle.


 The response may be computed, but once it's sent to the client it's
 immutable data.

Well, that's the point, you cannot tell. So, for example, I can provide
a website implemented over a relational database. Or I can serialize it
out as static files. Or I can add a caching layer which serializes
lazily, and redoes every hour.


 The response returned has no inherent API associated with it.

That sort of depends on the response.


 To put it another way, consider the function:

 (defn build-user [first-name last-name]
   {:first-name first-name
:last-name last-name
:full-name (str first-name   last-name)})

 Like a website, a function may perform computations, but its return
 value is immutable data. Would you say the above conforms the the
 Uniform Access Principle?

As I said at the beginning, it is possible to achieve UAP by making
*everything* a function. So, we can automatically achieve UAP by ONLY
using functions and never values.

So consider for example, this case.

(:doc (meta #'concat))

The return value of this expression can never be computed (short of
reimplementing ILookup or IMeta which, of course, we could do).

On the other hand

((:doc (meta #'concat)))

could be computed or not, since the function returned could just be
returning a value. So, the latter supports the UAP, the former doesn't.

In fact, this is how I squared the circle in my case. I changed

data-factory

to 

(data-factory)

In most cases the data-factory function just returns a constant value,
but it can use computation when I choose.

Phil

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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.


[ANN] New release 0.29.0 of Counterclockwise

2014-10-20 Thread Laurent PETIT
Counterclockwise, the Eclipse Clojure development tool.

Counterclockwise 0.29.0 has been released.

Improvement over 0.28.1 based on user feedback.
Also, upgraded Leiningen version to 2.5.0.


ChangeLog
=

http://doc.ccw-ide.org/ChangeLog.html#_changes_between_counterclockwise_0_28_1_and_0_29_0

Installation instructions
==

http://doc.ccw-ide.org/documentation.html#_install_counterclockwise

Cheers,

-- 
Laurent Petit

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Modelling in Clojure

2014-10-20 Thread James Reeves
On 20 October 2014 14:02, Phillip Lord phillip.l...@newcastle.ac.uk wrote:

 The uniform access principle is about having uniform access to data and
 APIs. It's not about prefering one or the other.


Right, but Clojure *does* heavily prefer data over APIs, and therein lies
the conflict.



 Yes, which is what I have done, of course. Now it won't work in any IDE
 which looks for the docstring as :doc metadata. It is totally
 unextensible. I do not think that this is good.


Clojure prefers simple solutions over easy solutions.

Unrestricted polymorphism and universal access would make solving this
problem easier, but they also create more complexity.

Or to put it another way, rather than trying to shoehorn a solution into a
system that wasn't built for it, we should design a new system around the
desired solution. In the case of documentation, the most obvious approach
is to decide on a new protocol all IDEs can implement.


 The response may be computed, but once it's sent to the client it's
  immutable data.

 Well, that's the point, you cannot tell. So, for example, I can provide
 a website implemented over a relational database. Or I can serialize it
 out as static files. Or I can add a caching layer which serializes
 lazily, and redoes every hour.


Yes, and so can a function. Clojure doesn't say, you shouldn't compute,
it says, you should separate computations and data.

I suppose it's possible to build a service where every value lookup
requires hitting an external server, but no-one sane builds a web service
like that. Latency concerns alone mean that data and computation need to be
separated in distributed systems.



  The response returned has no inherent API associated with it.

 That sort of depends on the response.


I suppose one could design architecture around passing around executable
code that's executed in a sandbox by the client, but see my previous point
about sane design.



  To put it another way, consider the function:
 
  (defn build-user [first-name last-name]
{:first-name first-name
 :last-name last-name
 :full-name (str first-name   last-name)})
 
  Like a website, a function may perform computations, but its return
  value is immutable data. Would you say the above conforms the the
  Uniform Access Principle?

 As I said at the beginning, it is possible to achieve UAP by making
 *everything* a function. So, we can automatically achieve UAP by ONLY
 using functions and never values.


The point I was trying to make was that computed values (such as those
produced by a web server) do not necessarily imply UAP.

I don't disagree that UAP has some benefits, but it comes with a huge
number of tradeoffs. Given that the problem it tries to solve is, in my
experience at least, exceeding rare, it really doesn't seem worth the
additional complexity.

- 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 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: Modelling in Clojure

2014-10-20 Thread Phillip Lord
James Reeves ja...@booleanknot.com writes:
 Yes, which is what I have done, of course. Now it won't work in any IDE
 which looks for the docstring as :doc metadata. It is totally
 unextensible. I do not think that this is good.


 Clojure prefers simple solutions over easy solutions.

A nice aphorism sometimes, but content free in this case, I think.


 Unrestricted polymorphism and universal access would make solving this
 problem easier, but they also create more complexity.

 Or to put it another way, rather than trying to shoehorn a solution into a
 system that wasn't built for it, we should design a new system around the
 desired solution.

So, there is this tourist, and he asks a local, how do I get into
town. Hmmm, says the local, if I want to get into town, I wouldn't
start from here.

Software engineering is a compromise, and designing a new system is a
pain, especially if multiple people have to update to it. I think
Clojure's doc string support is weak. Part of the reason for this, is
because it is not extensible. The main reason that it is not extensible
is that, in Clojure, once you have decided that something is a value,
you are stuck.

Don't care about my use-case? That's fine. Have a look at Andy
Fingerhuts thalia which helps to fix Clojure's poor documentation.

https://github.com/jafingerhut/thalia

Same problem -- all has to be done up front, which is ugly and nasty. As
a result, I don't use thalia, which is a shame.


 The response may be computed, but once it's sent to the client it's
  immutable data.

 Well, that's the point, you cannot tell. So, for example, I can provide
 a website implemented over a relational database. Or I can serialize it
 out as static files. Or I can add a caching layer which serializes
 lazily, and redoes every hour.


 Yes, and so can a function. Clojure doesn't say, you shouldn't compute,
 it says, you should separate computations and data.

Which is nice and simple, yes. And has negative consequences in terms of
extensibility. I understand if you are happy with this compromise. But
it is a compromise.



 The point I was trying to make was that computed values (such as those
 produced by a web server) do not necessarily imply UAP.

 I don't disagree that UAP has some benefits, but it comes with a huge
 number of tradeoffs. Given that the problem it tries to solve is, in my
 experience at least, exceeding rare, it really doesn't seem worth the
 additional complexity.

Well, the question is, where does this additional complexity come from.
In Java, it results in enormous quantities of boilerplate get/set
methods. In Scala, these are autocoded away.

In Clojure, I don't see an easy solution. Not going to stop me using the
language, but it's a weak spot.

Phil

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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: Modelling in Clojure

2014-10-20 Thread Brandon Bloom


 Well, the question is, where does this additional complexity come from. 
 In Java, it results in enormous quantities of boilerplate get/set 
 methods. In Scala, these are autocoded away. 


Boilerplate isn't complexity: It's inefficiency.

I'll grant that it creates complexity-potential-energy via many increased 
space for complexity to hide. However, it's far more complex to eliminate 
boilerplate via dynamic mechanisms, such as interface dispatch or, heaven 
forbid, Ruby-style abuses such as method_missing. Simpler is to eliminate 
boilerplate by developing terser encodings in terms of values, and bringing 
computation to bear to interpret (or translate) those values.

But I'll argue that avoiding the UAP isn't about complexity. It's about an 
intentional modeling of non-uniform access. Clojure data is built, 
constructively, out of lists, maps, sets, vectors, symbols, keywords, 
numbers, strings, etc. Any inductive data types, by the very nature of 
computation, are implemented in terms of co-inductive operations on codata 
types. You can't observe something in your computer without executing code 
to interpret some representation which models some abstraction. Any 
representation is built concretely out of the abstractions below it. By 
committing to :keyword style access, you're making a proclamation that 
you're operating on a concrete representation. If that concrete 
representation happens to be implemented abstractly (as it must be), you 
can override it (again with ILookup, etc). However, if you're going to 
override it, you damn well better provide value-like semantics.

UAP grants you flexibility in changing an abstraction. However, it grants 
*too much* flexibility. It lets you change from a convincing emulation of a 
true mathematical value to a full-blown computation object. Making 
operations on data source-incompatible with operations on codata is a 
feature, not a bug.

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Modelling in Clojure

2014-10-20 Thread James Reeves
On 20 October 2014 17:08, Phillip Lord phillip.l...@newcastle.ac.uk wrote:

 James Reeves ja...@booleanknot.com writes:

  Clojure prefers simple solutions over easy solutions.

 A nice aphorism sometimes, but content free in this case, I think.


Well, no... The whole point is that simple and easy in this context
have objective definitions.

If you go by Rich's definition of simple, then a value is *objectively*
simpler than a function.


So, there is this tourist, and he asks a local, how do I get into
 town. Hmmm, says the local, if I want to get into town, I wouldn't
 start from here.


That makes perfect sense, *if* the tourist is making the trip *only once*.

But that hardly applies in this case, because a documentation system will
be used many times.

So there's this business owner, and he asks a local, What's the quickest
route for my vehicles to get to town? The local considers, and replies,
You'd be able to get into town much faster if your vehicles were stationed
on the other side of town.


A small context shift, and suddenly the local's advice is extremely useful.



 Which is nice and simple, yes. And has negative consequences in terms of
 extensibility. I understand if you are happy with this compromise. But
 it is a compromise.


I don't disagree, but I do consider the compromise to be a minor one.

UAP has huge disadvantages in terms of complexity, repetition, scalability,
reliability, isolation, and a whole bunch of other things that Clojure is
explicitly trying to avoid.

On the other hand, I can't personally recall a situation where it would
have actually been useful to me.


Well, the question is, where does this additional complexity come from.
 In Java, it results in enormous quantities of boilerplate get/set
 methods. In Scala, these are autocoded away.


By complexity I'm again referring to Rich's more objective definition of
the term.

Complexity in this sense is a measurement of how many things can affect
part of your program. An immutable value is the simple, because nothing can
affect it. A pure function is more complex, because it's affected by its
arguments, and a side-effectful function has even an greater complexity,
because it can be affected by pretty much anything.

The simple vs. easy idea is a short way of saying we should prioritise
reducing coupling between components (simplicity), even at the cost of
short term gains (easiness).

- 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 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: [ANN] New release 0.29.0 of Counterclockwise

2014-10-20 Thread Mikera
Working great for me - thanks Laurent!

On Monday, 20 October 2014 21:22:31 UTC+8, Laurent PETIT wrote:

 Counterclockwise, the Eclipse Clojure development tool.

 Counterclockwise 0.29.0 has been released.

 Improvement over 0.28.1 based on user feedback.
 Also, upgraded Leiningen version to 2.5.0.


 ChangeLog
 =


 http://doc.ccw-ide.org/ChangeLog.html#_changes_between_counterclockwise_0_28_1_and_0_29_0

 Installation instructions
 ==

 http://doc.ccw-ide.org/documentation.html#_install_counterclockwise

 Cheers,

 -- 
 Laurent Petit
  

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.