How to avaoid regresssions in Clojure Applications

2015-12-05 Thread Timur
Hi all,

I'm using Clojure to build a set of services. 

Development with Clojure is fun but most of the time, I lose time with 
fixing regressions due to changing small parts of the codes. Do you have 
any best practices to avoid regressions occurring due to changes in the 
code? I use :pre and :post conditions. Sometimes, they are not sufficient.  
do not write so far regression tests as they are quite time consuming. 
Writing these tests will be probably an answer, I guess. Do you have any 
guidelines to write good regression tests? It would be nice if I could 
re-use the code that I type into the REPL to test separate functions, into 
the test code but most of the time it somehow does not work. Another 
problem I'm facing is many functions are dependent on each other, so I 
cannot test each separately, I pass the results in a map and each function 
updates the map, so I cannot write really atomic tests.

Any suggestions? 


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

2015-12-05 Thread Colin Yates
Hi Timur,

I find almost all of my pain is from changing shapes of the data that flows 
through the system. As you say “I pass the results in a map and each function 
updates the map” so even if you unit test each fn that doesn’t actually help 
because the tests provide the (now incorrect) data. Stepping back a problem 
this is a problem of visibility and enforcement - the required structures are 
opaque (otherwise it wouldn’t be painful) and they aren’t enforced.

On a related note, I don’t see why you can’t still write atomic tests here...

I find Prismatic Schema a great answer to both of these. I also think it is 
worth viewing fns as a graph rather than a list - I frequently have a fn which 
then delegates to a bunch of other fns. Add a few of the ‘top level’ fns in a 
single namespace and it gets really hard really quickly to see this graph 
making it hard to visualise an impact analysis. Again, one trick is to document 
these ‘gateway’ fns with the schema and simply use pre/post (or not, depending 
on the complexity) on the ‘inner fns’. Namespaces are also an obvious tool but 
I don’t think one ns per high level fn is viable.

I also find in that function graph at the bottom are ‘shape-a->shape-b’, in the 
middle are higher level fn which takes some sequence or graph, untangles it and 
then maps/reduces the ‘bottom’ shape changer fns. At the top are higher 
level/entry point fns which are more often than not push a data structure 
through a sequence of the ‘middle’ fns using (-> ) or (->> ).

I deliberately don’t document anything other than the high level fns as a 
starting point - everything else should be _so_ obvious (assuming you 
understand Clojure of course) that a ‘what does this do’ is a smell. The higher 
level fns are documented in terms of the schema (which with good naming is 
self-documenting) and _why_ it is doing what it is doing.

Another cause of pain is the cognitive load of the code itself. Initially I 
found myself writing so much code that was in the core library but I didn’t 
know it. Once I learnt the core library it wasn’t unusual to delete 10s of line 
to replace with a 1 or 2 liner using the core data structures/idioms. This has 
a non-obvious benefit which is a non-trivial amount of code is ‘just’ using the 
core fns. This means there is nothing new - the core fns become a significant 
part of your code’s ubiquitous language. I recall a senior member of the 
community saying something like ‘whenever I write my own code I consider it a 
smell’ (or something like it). The point is familiarity - the more core fns you 
use the more domain-agnostic and familiar that code will be.

My final point (waffled too much already I think) is that of ignorance - you 
want your fns to be as ignorant as possible. For each fn follow this process 
_ruthlessly_:
 - what assumptions does this fn make?
 - what can change outside this fn which will break this fn?
 - how many times do I use the word ‘and’ when I describe this fn
 - can I replace it with a core fn

For the higher level fns the answer is usually ‘many ands’ because they 
implement a process but that is fine.

Once you are happy that your code is composed of tiny little ignorant and 
bullet proof bricks, all composed together in readable top level fns and 
feeling all great about it, go get somebody to review it, even if you have 
paired on the code, always get somebody else to read it, not for correctness, 
just for consistency (using same idioms, style etc.) with the rest of the code 
base.

All of this is to say the pain comes from obfuscation, I find the above goes 
along way to writing self documenting code.

In summary, what I find helpful:

 - the pain comes from the opaqueness of the really important concepts: data 
shapes and function graphs
 - comments explaining _what_ the code are doing are really helpful when you 
are writing fns that do too much
 - Prismatic Schema to document _and_ enforce (runtime enforcement isn’t really 
that inefficient I find) the abstract shapes
 - fns further up the graph tend to be very well documented, non-private and 
almost certainly have a schema attached
 - delegate fns tend to be trivial one or two liners that typically map/reduce 
something over a sequence
 - actual worker fns tend to take one element of a sequence and are likely to 
be `defmulti`s. These take one fairly trivial ‘shape’
 - always get somebody else’s eyes - they might be able to say ‘why’ the code 
is doing it but they should be able to say _what_ the code is doing - WITHOUT 
you prompting them :-)

HTH - knee jerk and written stream of consciousness so apologies for numptyness

> On 5 Dec 2015, at 14:10, Timur  wrote:
> 
> Hi all,
> 
> I'm using Clojure to build a set of services. 
> 
> Development with Clojure is fun but most of the time, I lose time with fixing 
> regressions due to changing small parts of the codes. Do you have any best 
> practices to avoid regressions occurring due to changes in the code? I use 
>

Re: How to avaoid regresssions in Clojure Applications

2015-12-05 Thread Magnus Therning

Timur writes:

> Hi all,
>
> I'm using Clojure to build a set of services.
>
> Development with Clojure is fun but most of the time, I lose time with
> fixing regressions due to changing small parts of the codes. Do you
> have any best practices to avoid regressions occurring due to changes
> in the code? I use :pre and :post conditions. Sometimes, they are not
> sufficient. do not write so far regression tests as they are quite
> time consuming. Writing these tests will be probably an answer, I
> guess. Do you have any guidelines to write good regression tests? It
> would be nice if I could re-use the code that I type into the REPL to
> test separate functions, into the test code but most of the time it
> somehow does not work. Another problem I'm facing is many functions
> are dependent on each other, so I cannot test each separately, I pass
> the results in a map and each function updates the map, so I cannot
> write really atomic tests.
>
> Any suggestions?

Typed Clojure maybe?

/M

--
Magnus Therning  OpenPGP: 0xAB4DFBA4
email: mag...@therning.org   jabber: mag...@therning.org
twitter: magthe   http://therning.org/magnus

Eagles may soar, but weasels don't get sucked into jet engines.

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


[Docs] Help needed on clojure.org guides

2015-12-05 Thread Alex Miller
Hello all, just wanted to mention a few easy places that someone could help 
out if they're interested.

There are two excellent guides that Andy Fingerhut has written in the past 
on comparators and hash/equality stuff. Andy has given the ok to contribute 
those guides onto the new clojure.org site. This is largely a job of 
porting existing content (in Markdown) into asciidoc, so these are 
comparatively easy things that need to be done. Tasks are here with links 
to the source content:

https://github.com/clojure/clojure-site/issues/15 - comparators 
https://github.com/clojure/clojure-site/issues/16 - hash/equality

There are a number of other issues for needed content as well if you want 
to do more writing!

https://github.com/clojure/clojure-site/issues

Also, we have been working hard on the styling, deployment, and many other 
details and things are looking pretty good. I'm hopeful that we will be 
able to cut over to the new site before the end of the year (even if not 
everything is perfect). 

Alex

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


Naming convention for atoms, refs, etc.?

2015-12-05 Thread Mars0i
Does anyone want to suggest or promote a naming convention for atoms, refs, 
and agents, i.e. some of things that you can dereference with @ i.e. deref?

(Also, what about futures, delays, and promises?  I think of these as 
playing a different sort of role, even though deref works with them, too.)

The Clojure style guide 
 says:

Use *earmuffs* for things intended for rebinding (ie. are dynamic). 

;; good
(def ^:dynamic *a* 10)


It could be reasonable to use earmuffs for atoms, etc., too, but I think 
that "@*my-atom*" is ugly because of the juxtaposed @-sign and asterisk, 
and in any event I think of rebinding as a different kind of thing from 
what happens with atoms/refs/agents.

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

2015-12-05 Thread Mars0i
&, $, and ! might be good to use as special naming characters for 
atoms/refs/agents, either as an initial char, a final char, or both, but 
I'm wondering whether anyone already has a naming convention that they use.

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

2015-12-05 Thread James Reeves
Why should they have any sort of naming scheme? Dynamic vars are unusual
because their values can change. Atoms and refs remain the same, and even
though inside their values mutate, they don't affect the outer var.

- James

On 5 December 2015 at 21:39, Mars0i  wrote:

> Does anyone want to suggest or promote a naming convention for atoms,
> refs, and agents, i.e. some of things that you can dereference with @ i.e.
> deref?
>
> (Also, what about futures, delays, and promises?  I think of these as
> playing a different sort of role, even though deref works with them, too.)
>
> The Clojure style guide
>  says:
>
> Use *earmuffs* for things intended for rebinding (ie. are dynamic).
>
> ;; good
> (def ^:dynamic *a* 10)
>
>
> It could be reasonable to use earmuffs for atoms, etc., too, but I think
> that "@*my-atom*" is ugly because of the juxtaposed @-sign and asterisk,
> and in any event I think of rebinding as a different kind of thing from
> what happens with atoms/refs/agents.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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.
>

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

2015-12-05 Thread Leif
I took it to mean "How many people are *using* your Clojure app?"

On Friday, December 4, 2015 at 3:33:10 PM UTC-5, puzzler wrote:
>
> I took it to mean "How many people are working on your Clojure project?"
>
> On Fri, Dec 4, 2015 at 8:44 AM, James Reeves  > wrote:
>
>> What does this question mean, exactly?
>>
>> 6. What types of applications do you use Clojure, ClojureScript, or 
>>> ClojureCLR in?
>>>  
>>> Company-wide/Enterprise
>>> Departmental
>>> Team
>>> Personal 
>>
>>
>> - James
>>
>> On 4 December 2015 at 16:31, Alex Miller > > wrote:
>>
>>> If you are a user of Clojure, ClojureScript, or ClojureCLR, we are 
>>> greatly interested in your responses to the following survey:
>>>
>>> https://www.surveymonkey.com/r/clojure-2015
>>>
>>> The survey contains four pages:
>>>
>>> 1. General questions applicable to any user of Clojure, ClojureScript, 
>>> or ClojureCLR
>>> 2. Questions specific to the JVM Clojure (skip if not applicable)
>>> 3. Questions specific to ClojureScript (skip if not applicable)
>>> 4. Final comments
>>>
>>> The survey will close December 18th. Afterwards we will release all of 
>>> the data and some analysis.
>>>
>>> Many thanks to Chas Emerick for starting and keeping this survey going 
>>> for so many years!
>>>
>>> -- 
>>> 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/d/optout.
>>>
>>
>> -- 
>> 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/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: Naming convention for atoms, refs, etc.?

2015-12-05 Thread Timothy Baldridge
Also, if you have so many atoms in your program that it becomes hard to
remember where they are, that would be another source of concern ;-)

On Sat, Dec 5, 2015 at 4:44 PM, James Reeves  wrote:

> Why should they have any sort of naming scheme? Dynamic vars are unusual
> because their values can change. Atoms and refs remain the same, and even
> though inside their values mutate, they don't affect the outer var.
>
> - James
>
> On 5 December 2015 at 21:39, Mars0i  wrote:
>
>> Does anyone want to suggest or promote a naming convention for atoms,
>> refs, and agents, i.e. some of things that you can dereference with @ i.e.
>> deref?
>>
>> (Also, what about futures, delays, and promises?  I think of these as
>> playing a different sort of role, even though deref works with them, too.)
>>
>> The Clojure style guide
>>  says:
>>
>> Use *earmuffs* for things intended for rebinding (ie. are dynamic).
>>
>> ;; good
>> (def ^:dynamic *a* 10)
>>
>>
>> It could be reasonable to use earmuffs for atoms, etc., too, but I think
>> that "@*my-atom*" is ugly because of the juxtaposed @-sign and asterisk,
>> and in any event I think of rebinding as a different kind of thing from
>> what happens with atoms/refs/agents.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from 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.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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.
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

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

2015-12-05 Thread Mars0i
On Saturday, December 5, 2015 at 5:45:22 PM UTC-6, James Reeves wrote:
>
> Why should they have any sort of naming scheme? Dynamic vars are unusual 
> because their values can change. Atoms and refs remain the same, and even 
> though inside their values mutate, they don't affect the outer var.
>

Good point, James.  They're just regular variables.  Still, their role is 
very different from that of normal Clojure variables.  I prefer to give 
them a different kind of name.  But I can understand why others wouldn't. 

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

2015-12-05 Thread Mars0i
On Saturday, December 5, 2015 at 8:04:34 PM UTC-6, tbc++ wrote:
>
> Also, if you have so many atoms in your program that it becomes hard to 
> remember where they are, that would be another source of concern ;-)
>

Yeah   I'm worried that I'll come back to the code a year later and not 
remember that the variable contains an atom, and wonder why I'm getting 
different things out of it.  Though I suppose the at-sign might be a 
tip-off.

Or suppose I have a recurrent role in several functions or several 
namespaces or several programs, for which I always use the same name.  
Using the same name in different contexts makes the meaning of the 
variables clear.  Then it turns out that I have to make a new special 
version of this kind of program, in which I need to store the same kind of 
data in an atom rather than simply passing it from function to function.  I 
want to give the variable containing the data the same name ... but I 
don't, because this variable is different--it contains an atom containing 
the usual data, rather than the data itself.  (This is actually the 
situation that prompted the question.  I don't like having to store the 
data in an atom, but )

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

2015-12-05 Thread Mars0i
As in the past, many survey questions are not appropriately designed for 
getting info about uses of Clojure in academic research.  I don't think 
there's very much use of of Clojure for this purpose, but the survey won't 
be able to track it.

(Examples: 

7. Where do you deploy Clojure, ClojureScript, or ClojureCLR applications? 
Traditional infrastructure 
Private cloud (or hybrid) 
Public cloud
Huh?  I deploy my research simulations on my own computers.  Sometimes I 
deploy them on a computing cluster, so that I can run many instances at 
once.


(Tiny bug in the form: #11 has radio buttons and an "other" text box, but 
the box doesn't have an associated radio button.)

fwiw, as I've remarked before, it would be good for Clojure if it were used 
more often in academia, since any professor using Clojure has the potential 
to turn many students on to it.

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/d/optout.