Re: Revisiting forward-chaining rules in Clojure

2013-08-19 Thread Maik Schünemann
Hi, the library looks very interesting!
I am also working on a rule based translator as part of expresso [1],
my gsoc project Algebraic Expressions, which uses the rule based
translator
to succinctly specify transformations of algebraic expressions.
You can see some examples of this in my recent blog posts on [2].

It is, of course, most suited for algebraic expressions, but this
means just s-exps in clojure (it is also backed by protocols so even
java interop should be possible).

would clara also be applicable to the domain of algebraic expressions?
If so, how does it compare?

The one cool feature of the rule based translator i like the most is
that it has semantic matching instead of purely syntactical matching.
That means, that for example '+ can specify its own matching algorithm
(in this case commutative matching).
So
(def r (rule (ex (+ 0 ?&*)) :=> (ex (+ ?&*
(apply-rule r (ex (+ 0 1 2))) :=> '(+ 1 2)
(apply-rule r (ex (+ 1 0 2))) :=> '(+ 1 2)

?&* here stands for: match zero or more expressions.

[1] https://github.com/clojure-numerics/expresso
[2] http://kimavcrp.blogspot.de/

On Sun, Aug 18, 2013 at 9:54 PM, Shantanu Kumar
 wrote:
> Thanks for posting. I will certainly explore this.
>
> Did you look at Mimir? https://github.com/hraberg/mimir Could you outline
> how is Clara's approach different from Mimir?
>
> Shantanu
>
>
> On Sunday, 18 August 2013 23:46:14 UTC+5:30, Ryan Brush wrote:
>>
>> Perhaps the best aspect of Clojure is how it can adopt the best ideas from
>> other domains to concisely solve problems, as we've seen with core.logic,
>> core.async and other libraries. I recently came across a problem domain that
>> is easily expressed in forward-chaining rules, and found Clojure to be a
>> powerful way to solve it.
>>
>> While working through this problem space I started to suspect there is a
>> more general need for forward-chaining rules in Clojure to complement
>> core.logic and other libraries. So as a side project I implemented a raw but
>> working engine to do so. I'm posting here to share a draft of this engine,
>> its major design goals, and to ask for input on how we should approach
>> forward-chaining rules in Clojure in general.
>>
>> The rationale and some examples are on the github page for this engine,
>> which I've tentatively named Clara. The state of the code isn't where it
>> needs to be yet; I've been learning the intricacies of Rete and discovering
>> better ways to solve problems along the way, and some of that is reflected
>> in the code base. However, the major pieces of design and functionality are
>> in place, so I'd like to get input on those.
>>
>> The idea is to draw a bit from Jess and Lisa, with the Java interop
>> strength of Drools, but the advantages and idioms available in Clojure. The
>> major goals are:
>>
>> Focus on problem spaces naturally expressed as forward-chaining rules.
>> Data-driven needs like eventing, data validation, or application of
>> arbitrary business rules fit here.
>> Embrace immutability. The rule engine's working memory is a persistent
>> Clojure data structure that can participate in transactions. All changes
>> produce a new working memory that shares state with the previous.
>> Rule constraints and actions are simply Clojure s-expressions.
>> First-class Java interoperability and APIs. This should be an alternative
>> to Jess or Drools from Java-land.
>> Usable either as a library to simplify Clojure code, or as a DSL to
>> externalize business logic.
>> Working memory facts are typically (but not exclusively) Clojure records
>> or Java objects following the Java Bean conventions.
>> Support the major advantages of existing rules systems, such as
>> explainability of why a rule fired and automatic truth maintenance.
>> Collections of facts can be reasoned with using accumulators similar to
>> Jess or Drools. These accumulators leverage the reducers API and are
>> transparently parallelized.
>> The working memory is independent of the logic flow, and can be replaced
>> with a distributed processing system. A prototype that uses Storm to apply
>> rules to a stream of incoming events already exists.
>>
>> I'd love to hear thoughts on a couple questions:
>>
>> What else would you want from a forward-chaining rules engine in Clojure?
>> What design changes would you make, given the above criteria and examples
>> on github?
>>
>> All thoughts are appreciated!
>>
>> -Ryan
>>
>> https://github.com/rbrush/clara-rules
>> https://github.com/rbrush/clara-examples
>> https://github.com/rbrush/clara-storm
>>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from 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: vec to map with consolidated vals

2013-08-19 Thread Philipp Meier

Am Samstag, 17. August 2013 11:19:23 UTC+2 schrieb David Chelimsky:
>
> Hey Steven, here's a variation of my first example that, I think, gets 
> closer to what you're proposing (with maybe-add handled in-line):
>
> (defn to-consolidated-map [parts]
>   (reduce (fn [h [k v]]
> (assoc h k (+ (get h k 0) v)))
>   {}
>   parts))
>
 
An expression of the form (assoc m k (fn (get m k a) v))) can replaced with 
update-in. If you need a default value, then add fnil to the party:

(defn to-consolidated-map [parts] 
  (reduce (fn [h [k v]]
  (update-in h [k] (fnil + 0) v))
  {}
  parts))

-billy,

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

2013-08-19 Thread Philipp Meier
Hi Christian,

Am Sonntag, 18. August 2013 18:52:54 UTC+2 schrieb Christian Sperandio:
>
> Hi,
>
> I wrote a set of functions to compare 2 words managing the keyboard 
> mistakes. The common mistakes are insertion, deletion, substitution or 
> inversion.
>

This sound like you're looking for an implementation of the levinstein 
distance. Incanter, e.g. has an implementation

http://clojuredocs.org/incanter/1.2.3-SNAPSHOT/incanter.stats/levenshtein-distance

-billy.

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

2013-08-19 Thread Christian Sperandio
The purpose is close but not the same. I want to manage the keyboard
mistakes. It comes from the need to validate keyboard input. At work, we
canceled the use of distance because is not efficient enough for name
comparing (person, medicine and others) and provided wrong result. We use
the find-errors function that returns the mistakes find between two words
(inversion, insertion, deletion...). Each error has a level (in function of
the word type, length) and that defines the likeness of the 2 words. For
example, in the case of lastname, we accept only one insertion or deletion
mistake for short lastnames. But if the lastnames are long, we accept
couple of 2 errors (1 insertion/deletion and 1 inversion for instance).
I should talk more about find-errors function than candidates? one :)
 Le 19 août 2013 09:47, "Philipp Meier"  a écrit :

> Hi Christian,
>
> Am Sonntag, 18. August 2013 18:52:54 UTC+2 schrieb Christian Sperandio:
>>
>> Hi,
>>
>> I wrote a set of functions to compare 2 words managing the keyboard
>> mistakes. The common mistakes are insertion, deletion, substitution or
>> inversion.
>>
>
> This sound like you're looking for an implementation of the levinstein
> distance. Incanter, e.g. has an implementation
>
>
> http://clojuredocs.org/incanter/1.2.3-SNAPSHOT/incanter.stats/levenshtein-distance
>
> -billy.
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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.


What does IOC in terms of core.async mean?

2013-08-19 Thread Michal Till
I kinda understand the whole problem and I also understand that this has 
nothing to do with the OO IOC pattern, but I still don't exactly get what 
is meant by this term. What is inverting what and where? What does 
"control" refer to exactly - compared to callbacks?

M.

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

2013-08-19 Thread Phillip Lord


That would be true, if I knew what my code was going to do when I
started. But most of my code is used to investigate things that I don't
understand; so it evolves slowly over time. I don't know when I start
what "low-level" is going to be. So, I'm left with the task of removing
forward declarations at the end.

I've also been using clojure for representing things other than
functions -- logical statements in this case -- and mutational
referencing is very common there.

If there aren't any tools, then I'm left with doing it by hand.




Stuart Sierra  writes:
> Forward declarations are rarely necessary in my experience: you just get 
> used to defining your namespaces with low-level primitive functions at the 
> top and higher-level functions at the bottom. You only need forward 
> declarations (`declare`) in cases of mutual recursion, i.e. two functions 
> that call each other.
>
> -S
>
>
>
> On Wednesday, August 14, 2013 8:56:06 AM UTC-4, Phillip Lord wrote:
>>
>>
>> One of the things that I find unusual with clojure is the requirement 
>> for forward declaration. While I can see the advantages, managing it by 
>> hand can be a pain. 
>>
>> So I was wondering, are there any tools for adding declare statements 
>> when necessary. And better for working out how to reorder function 
>> declarations to minimize the requirement for forward declarations. 
>>
>> Phil 
>>
>>
>
> -- 

-- 
Phillip Lord,   Phone: +44 (0) 191 222 7827
Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk
School of Computing Science,
http://homepages.cs.ncl.ac.uk/phillip.lord
Room 914 Claremont Tower,   skype: russet_apples
Newcastle University,   twitter: phillord
NE1 7RU 

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

2013-08-19 Thread John D. Hume
On Aug 19, 2013 5:53 AM, "Phillip Lord" 
wrote:
>
> That would be true, if I knew what my code was going to do when I
> started. But most of my code is used to investigate things that I don't
> understand; so it evolves slowly over time. I don't know when I start
> what "low-level" is going to be. So, I'm left with the task of removing
> forward declarations at the end.

I don't think Stuart was suggesting that you start by writing low-level fns
at the top but that, as you extract or introduce low-level things to
support the idea you're working on, you put them above where you're working
(instead of just putting the forward declarations there).

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

2013-08-19 Thread Tim Visher
The most annoying thing to me about forward declaration is that it
prevents what Uncle Bob calls 'Newspaper Style Code' where I can
structure my code in such a way that the high-level functions are
right at the top and the primitives that they might need are found
below so that I or someone else who needs to read me code can stop
reading at any point and only miss some details about how things work.

I'm a big fan of this and it's one of the things I miss most about
other languages when I'm in Clojure. Keepin a bunch of primitives in
my head without seeing the big picture so that when I see the big
picture it makes more sense is difficult and for whatever reason
scrolling from the bottom of the file feels unnatrural enough that I
still haven't gotten used to it.

One advantage though is that the requiring forward declaration does
gaurentee that if it compiles the code will not have a mixture of the
two styles.

On Mon, Aug 19, 2013 at 4:18 AM, John D. Hume  wrote:
>
> On Aug 19, 2013 5:53 AM, "Phillip Lord" 
> wrote:
>>
>> That would be true, if I knew what my code was going to do when I
>> started. But most of my code is used to investigate things that I don't
>> understand; so it evolves slowly over time. I don't know when I start
>> what "low-level" is going to be. So, I'm left with the task of removing
>> forward declarations at the end.
>
> I don't think Stuart was suggesting that you start by writing low-level fns
> at the top but that, as you extract or introduce low-level things to support
> the idea you're working on, you put them above where you're working (instead
> of just putting the forward declarations there).
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from 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: Revisiting forward-chaining rules in Clojure

2013-08-19 Thread Ryan Brush
Hey Maik, I appreciate it!

I'm going to look more closely at expresso, but at first glance I think 
these projects have different objectives. Expresso appears to offer very 
rich semantics in its domain, where Clara intentionally offers more limited 
semantics in exchange for scalability and interoperability with existing 
data.  It targets the "lots of data and arbitrary business rules" use case, 
versus the algebraic focus of expresso.  So while it might be possible to 
force these sorts of expressions into Clara, it won't be straightforward. I 
suspect this is a case where these tools are complementary, and expresso is 
better suited for the problems you describe.

In any case, expresso looks like a cool project in its own right, so I'm 
glad you mentioned it here.

-Ryan

On Monday, August 19, 2013 2:36:21 AM UTC-5, Maik Schünemann wrote:
>
> Hi, the library looks very interesting! 
> I am also working on a rule based translator as part of expresso [1], 
> my gsoc project Algebraic Expressions, which uses the rule based 
> translator 
> to succinctly specify transformations of algebraic expressions. 
> You can see some examples of this in my recent blog posts on [2]. 
>
> It is, of course, most suited for algebraic expressions, but this 
> means just s-exps in clojure (it is also backed by protocols so even 
> java interop should be possible). 
>
> would clara also be applicable to the domain of algebraic expressions? 
> If so, how does it compare? 
>
> The one cool feature of the rule based translator i like the most is 
> that it has semantic matching instead of purely syntactical matching. 
> That means, that for example '+ can specify its own matching algorithm 
> (in this case commutative matching). 
> So 
> (def r (rule (ex (+ 0 ?&*)) :=> (ex (+ ?&* 
> (apply-rule r (ex (+ 0 1 2))) :=> '(+ 1 2) 
> (apply-rule r (ex (+ 1 0 2))) :=> '(+ 1 2) 
>
> ?&* here stands for: match zero or more expressions. 
>
> [1] https://github.com/clojure-numerics/expresso 
> [2] http://kimavcrp.blogspot.de/ 
>
> On Sun, Aug 18, 2013 at 9:54 PM, Shantanu Kumar 
> > wrote: 
> > Thanks for posting. I will certainly explore this. 
> > 
> > Did you look at Mimir? https://github.com/hraberg/mimir Could you 
> outline 
> > how is Clara's approach different from Mimir? 
> > 
> > Shantanu 
> > 
> > 
> > On Sunday, 18 August 2013 23:46:14 UTC+5:30, Ryan Brush wrote: 
> >> 
> >> Perhaps the best aspect of Clojure is how it can adopt the best ideas 
> from 
> >> other domains to concisely solve problems, as we've seen with 
> core.logic, 
> >> core.async and other libraries. I recently came across a problem domain 
> that 
> >> is easily expressed in forward-chaining rules, and found Clojure to be 
> a 
> >> powerful way to solve it. 
> >> 
> >> While working through this problem space I started to suspect there is 
> a 
> >> more general need for forward-chaining rules in Clojure to complement 
> >> core.logic and other libraries. So as a side project I implemented a 
> raw but 
> >> working engine to do so. I'm posting here to share a draft of this 
> engine, 
> >> its major design goals, and to ask for input on how we should approach 
> >> forward-chaining rules in Clojure in general. 
> >> 
> >> The rationale and some examples are on the github page for this engine, 
> >> which I've tentatively named Clara. The state of the code isn't where 
> it 
> >> needs to be yet; I've been learning the intricacies of Rete and 
> discovering 
> >> better ways to solve problems along the way, and some of that is 
> reflected 
> >> in the code base. However, the major pieces of design and functionality 
> are 
> >> in place, so I'd like to get input on those. 
> >> 
> >> The idea is to draw a bit from Jess and Lisa, with the Java interop 
> >> strength of Drools, but the advantages and idioms available in Clojure. 
> The 
> >> major goals are: 
> >> 
> >> Focus on problem spaces naturally expressed as forward-chaining rules. 
> >> Data-driven needs like eventing, data validation, or application of 
> >> arbitrary business rules fit here. 
> >> Embrace immutability. The rule engine's working memory is a persistent 
> >> Clojure data structure that can participate in transactions. All 
> changes 
> >> produce a new working memory that shares state with the previous. 
> >> Rule constraints and actions are simply Clojure s-expressions. 
> >> First-class Java interoperability and APIs. This should be an 
> alternative 
> >> to Jess or Drools from Java-land. 
> >> Usable either as a library to simplify Clojure code, or as a DSL to 
> >> externalize business logic. 
> >> Working memory facts are typically (but not exclusively) Clojure 
> records 
> >> or Java objects following the Java Bean conventions. 
> >> Support the major advantages of existing rules systems, such as 
> >> explainability of why a rule fired and automatic truth maintenance. 
> >> Collections of facts can be reasoned with using accumulators similar to 
> >> Jess or Drools.

Re: tools for minimizing forward declaration

2013-08-19 Thread Phillip Lord

Tim Visher  writes:
> The most annoying thing to me about forward declaration is that it
> prevents what Uncle Bob calls 'Newspaper Style Code' where I can
> structure my code in such a way that the high-level functions are
> right at the top and the primitives that they might need are found
> below so that I or someone else who needs to read me code can stop
> reading at any point and only miss some details about how things work.


I tend to agree with this. I like to write in a relatively literate
style when I can, and group functions according to, er, their function.
Without forward declarations, as Stuart suggests, the primary axis of
classification becomes "primitiveness", which can probably be reduced to
"how many other functions does this one refer to".

> I'm a big fan of this and it's one of the things I miss most about
> other languages when I'm in Clojure. Keepin a bunch of primitives in
> my head without seeing the big picture so that when I see the big
> picture it makes more sense is difficult and for whatever reason
> scrolling from the bottom of the file feels unnatrural enough that I
> still haven't gotten used to it.
>
> One advantage though is that the requiring forward declaration does
> gaurentee that if it compiles the code will not have a mixture of the
> two styles.


True. And it also stops the spell mistake errors that I am used to in
Elisp where you call a function by the wrong name. Although, then
clojure brings the problems of accidentally capturing a clojure core
name:

(defn thing [class]
(do-other-thing name))

which compiles just fine but is going to do the wrong thing.

Compromises, compromises.

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/groups/opt_out.


preference and implications of using as-> vs let

2013-08-19 Thread Jay Fields
In the past, I've written code like the following

(defn foo [x y]
  (let [x-squared (* x x)]
(if (pos? y)
  (+ x-squared y)
  (- x-squared y

However, the introduction of as-> has led me to write the following, at times

(defn foo [x y]
  (as-> (* x x) x-squared
(if (pos? y)
  (+ x-squared y)
  (- x-squared y

In essence, I've started replacing single binding lets with as->. John
Hume has pointed out that as-> seems to have been introduced to work
in conjunction with ->. Which brings me to my question - do you think
it's better to use a single binding let from a readability
perspective? Are there any (performance or otherwise) impacts that I
should be aware of?

Cheers, Jay

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

2013-08-19 Thread Steven Degutis
Ah! fnil! That's just what I was wanting, and didn't even know it. Thanks!
I think I like this version best.


On Mon, Aug 19, 2013 at 2:44 AM, Philipp Meier  wrote:

>
> Am Samstag, 17. August 2013 11:19:23 UTC+2 schrieb David Chelimsky:
>
>> Hey Steven, here's a variation of my first example that, I think, gets
>> closer to what you're proposing (with maybe-add handled in-line):
>>
>> (defn to-consolidated-map [parts]
>>   (reduce (fn [h [k v]]
>> (assoc h k (+ (get h k 0) v)))
>>   {}
>>   parts))
>>
>
> An expression of the form (assoc m k (fn (get m k a) v))) can replaced
> with update-in. If you need a default value, then add fnil to the party:
>
> (defn to-consolidated-map [parts]
>   (reduce (fn [h [k v]]
>   (update-in h [k] (fnil + 0) v))
>   {}
>   parts))
>
> -billy,
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: preference and implications of using as-> vs let

2013-08-19 Thread Ben Mabey

On 8/19/13 8:58 AM, Jay Fields wrote:

In the past, I've written code like the following

(defn foo [x y]
   (let [x-squared (* x x)]
 (if (pos? y)
   (+ x-squared y)
   (- x-squared y

However, the introduction of as-> has led me to write the following, at times

(defn foo [x y]
   (as-> (* x x) x-squared
 (if (pos? y)
   (+ x-squared y)
   (- x-squared y

In essence, I've started replacing single binding lets with as->. John
Hume has pointed out that as-> seems to have been introduced to work
in conjunction with ->. Which brings me to my question - do you think
it's better to use a single binding let from a readability
perspective? Are there any (performance or otherwise) impacts that I
should be aware of?

Cheers, Jay

I prefer the standard `let` in these cases for readability since `as->`, 
to me, implies some threading is going on.  I only use `as->` when I'm 
already using `->` as it saves me an extra binding that breaks up the 
flow of the code.  WRT performance, the only difference with the `as->` 
version is an extra rebinding of `x-squared` as this expansion shows:


(clojure.core/let [x-squared (* x x)
   x-squared (if (pos? y)
   (+ x-squared y)
   (- x-squared y))]
  x-squared)


-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 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.


Clojure Macro Tutorial

2013-08-19 Thread Steve Shogren
http://deliberate-software.com/intro-to-macros/

I wrote this tutorial up for a friend of mine who is a Ruby programmer 
thinking of learning Clojure, as my defense of why Clojure is worth his 
time.

I will welcome any advice, code reviews, or suggestions about the post or 
code samples. 

Thanks!

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 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: Help to morph this imperative snippet into a functional one

2013-08-19 Thread Timo Mihaljov
On 18.08.2013 16:51, Hussein B. wrote:
> Would you please help me transforming this imperative code into
> functional one?
> 
> The code is a typical snippet in imperative style. A lot of mutations
> that I don't even know how to start morphing it to Clojure.
> 
> class Container {
>   Map children;
>   String letter;
>   List value;
> }
> 
> void insert(Container container, String letters, String value) {
>   
>   for (int i = 0; i < letters.length; i++) {
> 
> String letter = new String(letters.chatAt[i]);
> 
> if (container.children.get(letter) != null) {
>   container = container.children.get(letter);
> } else {
>   Map childContainer = new HashMap<>();
>   container.children.put(letter, childContainer);
>   container = container.children.get(letter);
> }
> 
>if (i == letters.length() - 1) {
>  container.values.add(value);
>  break;
>}
> 
> } 

(You don't provide example inputs and outputs for the method, so I may
have misunderstood the code. If that's the case please disregard the
next paragraph.)

This example may be to artificial to be translated into Clojure. What
use is it to store strings in a tree keyed by the string's characters?
If you know the path to the string, you already know the string itself,
and you don't need the tree at all!

It is rarely a good idea to directly translate code from one language
into a much different one. It may be done, but the end result will not
be pretty and it certainly won't be idiomatic. I'm sure you'll get much
more helpful responses if you ask a question of the form "I need to
solve this problem – how can I do it in Clojure?"

If what you want is to manipulate trees in a purely functional way, you
might want to check out the Zipper data structure. [1] You can find it
in Clojure's standard library in the namespace `clojure.zip`. [2]

[1]
http://www.st.cs.uni-saarland.de/edu/seminare/2005/advanced-fp/docs/huet-zipper.pdf
[2] http://richhickey.github.io/clojure/clojure.zip-api.html

Hope this helps,
-- 
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 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.


ANN: CFP for Strata 2014

2013-08-19 Thread Alex Miller
I have no involvement with this conference but thought some people in the
Clojure world might be interested in submitting talks about big data,
analytics, data science, machine learning, etc.

http://strataconf.com/strata2014/public/cfp/283

CFP closes: Sept 16th, 2013
Notification: Oct, 2013
Conference: Feb 11-13, 2014 - Santa Clara, CA

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

2013-08-19 Thread Alan Moore
inline

On Sunday, August 18, 2013 10:57:35 PM UTC-7, Ryan Brush wrote:
>
> The idea of Datomic as an approach to scalable working memory is 
> interesting. I haven't looked at the mechanics of doing this, but it seems 
> possible since Clara aims to separate the working memory system from the 
> rule logic and Rete network.  Also, the approach I've taken here aligns 
> with Datomic's ideals of persistent data structures. I think having 
> multiple working memory implementations makes sense -- the approaches for 
> dealing with distributed event streams, local business logic, and 
> incremental queries over large, long-lived memory likely call for different 
> infrastructures. Datomic seems like a possible candidate to fill at least 
> one of those roles. The problems I've been working on haven't (yet) 
> required persisting the working memory, so my focus has been on in-memory 
> models to this point.
>

I agree that it is an unorthodox approach but that hasn't stopped me 
before. :-) I started by looking at graph APIs and databases to represent a 
distributed rete graph but then datomic was announced and it seemed a much 
better fit for the problems I'm trying to solve.

IMHO the real benefit for a rule engine that accommodates a data model like 
that of datomic is that it automatically gains access to temporal 
reasoning, something many rule engines struggle with or do not implement as 
seamlessly. It also makes the shape of the data less relevant and 
simplifies things considerably.

Datomic already has rules (well the LHS anyway)... if only they could work 
incrementally and trigger a RHS... I guess this is probably the wrong forum 
for this line of reasoning... I'll take it over there.
 

>
> As for help on this project, it would be welcome! Right now the code is 
> rough and the documentation nearly absent, but I plan on addressing that in 
> the coming weeks. I am starting to track bugs and enhancements on Github 
> for this project in the interest of transparency and collaboration. If 
> there's a particular item of interest, feel free to log or claim an issue 
> on the project.
>

Sure - I'll will start by writing some docs so that I can more fully 
understand the implementation. See you over there.

 

>
> Regarding ClojureScript: I believe it should be straightforward to get 
> this running in ClojureScript, but I haven't attempted it. There is a small 
> amount of logic specific to the JVM -- the mechanism for identifying the 
> fields that exist in a fact used in the working memory -- but that could be 
> factored out ad a ClojureScript alternative made available. I logged an 
> issue to track that: https://github.com/rbrush/clara-rules/issues/4
>

Nice... As you consider the java interop support you might want to avoid 
excluding clojurescript, even if it isn't supported initially. I have seen 
many client-side use cases that could benefit from a rules engine. The 
equivalent javascript solutions get messy fast.

Take care.

Alan

 

>
> On Sunday, August 18, 2013 11:51:46 PM UTC-5, Alan Moore wrote:
>>
>> On Sunday, August 18, 2013 1:41:56 PM UTC-7, Ryan Brush wrote:
>>>
>>> Shantanu,
>>>
>>> I appreciate it. I did look at Mimir, but had some different objectives, 
>>> and therefore tradeoffs, and didn't see a straightforward way to reconcile 
>>> them. 
>>>
>>> First, I wanted to use existing data models in the rules as is -- be it 
>>> Clojure records, Java Beans, or other structures. Drools has a number of 
>>> drawbacks, but has success in Java-land largely because it interoperates 
>>> with existing models so well. A pure Clojure solution with strong interop 
>>> could offer a number of advantages over existing engines. In fairness, I 
>>> have yet to add first-class Java support, but the same structure that uses 
>>> Clojure records right now will be extended to seamlessly use 
>>> JavaBeans-style classes.
>>>
>>> Second, I have a broader goal of executing rules against arbitrarily 
>>> large data sets in a distributed system, and there are semantic and 
>>> structural tradeoffs to make that happen. For instance, the underlying 
>>> working memory is a separate subsystem in Clara, and all join operations 
>>> are hash-based and structured in such a way that they need not be performed 
>>> in the same process. The clara-storm project is a very raw proof-of-concept 
>>> of distributing rules across a cluster, but we should be able to layer it 
>>> on top of other infrastructures as well, such as Hadoop (although that's 
>>> another, involved conversation in itself.) At this point I'm more focused 
>>> on getting the core system correct and useful on its own, doing enough to 
>>> ensure this will be scalable in the future. 
>>>
>>
>>
>> I have been working on a similar approach - only using datomic as the 
>> "working memory". At one point I briefly considered putting the rete nodes 
>> into datomic but quickly realized that wasn't a good idea.
>>
>> The datomic datalog engine is very im

Re: Help to morph this imperative snippet into a functional one

2013-08-19 Thread Timo Mihaljov
On 19.08.2013 20:27, Timo Mihaljov wrote:
> This example may be to artificial to be translated into Clojure. What
> use is it to store strings in a tree keyed by the string's characters?
> If you know the path to the string, you already know the string itself,
> and you don't need the tree at all!

Aaand of course I misread the code... I got `letters` and `value` mixed
up. Sorry about the noise!

-- 
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 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.


ANN Langohr 1.4.1 is released

2013-08-19 Thread Michael Klishin
Langohr [1] is a small, feature complete Clojure client for RabbitMQ.

1.4.1 is a bug fix release. Release notes:
http://blog.clojurewerkz.org/blog/2013/08/16/langohr-1-dot-4-1-is-released/

1. http://clojurerabbitmq.info
-- 
MK

http://github.com/michaelklishin
http://twitter.com/michaelklishin

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

2013-08-19 Thread Michael Gardner
On Aug 19, 2013, at 06:38 , Tim Visher  wrote:

> The most annoying thing to me about forward declaration is that it
> prevents what Uncle Bob calls 'Newspaper Style Code' where I can
> structure my code in such a way that the high-level functions are
> right at the top and the primitives that they might need are found
> below so that I or someone else who needs to read me code can stop
> reading at any point and only miss some details about how things work.

On the other hand, it doesn't take much to get used to reading source files 
from the bottom up. And I'd consider it a (minor) benefit that Clojure 
encourages this organization, as opposed to languages that don't care where in 
the file you put your functions.

Not that I'd be against doing things another way; I just haven't been bothered 
much by Clojure's "backwards" orientation and the occasional 
forward-declaration.

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

2013-08-19 Thread Mikera
I think a regular "let" is clearer in this kind of case.

"as->" suggests to me that multiple rebindings will happen to the name: if 
that is not happening then it is confusing for readers IMHO.

The only case I can think of where "as->" makes sense and the binding only 
happens once is if you are anticipating/suggesting that more rebindings 
will be inserted later (e.g. you expect additional steps like input 
transformation or output validation to be added).

On Monday, 19 August 2013 22:58:28 UTC+8, Jay Fields wrote:
>
> In the past, I've written code like the following 
>
> (defn foo [x y] 
>   (let [x-squared (* x x)] 
> (if (pos? y) 
>   (+ x-squared y) 
>   (- x-squared y 
>
> However, the introduction of as-> has led me to write the following, at 
> times 
>
> (defn foo [x y] 
>   (as-> (* x x) x-squared 
> (if (pos? y) 
>   (+ x-squared y) 
>   (- x-squared y 
>
> In essence, I've started replacing single binding lets with as->. John 
> Hume has pointed out that as-> seems to have been introduced to work 
> in conjunction with ->. Which brings me to my question - do you think 
> it's better to use a single binding let from a readability 
> perspective? Are there any (performance or otherwise) impacts that I 
> should be aware of? 
>
> Cheers, Jay 
>

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

2013-08-19 Thread Steven Degutis
I personally think the only place as-> should be used is inside other
threading macros. When it's used anywhere else, the name-goes-second
ordering feels wrong and very awkward.


On Mon, Aug 19, 2013 at 9:58 AM, Jay Fields  wrote:

> In the past, I've written code like the following
>
> (defn foo [x y]
>   (let [x-squared (* x x)]
> (if (pos? y)
>   (+ x-squared y)
>   (- x-squared y
>
> However, the introduction of as-> has led me to write the following, at
> times
>
> (defn foo [x y]
>   (as-> (* x x) x-squared
> (if (pos? y)
>   (+ x-squared y)
>   (- x-squared y
>
> In essence, I've started replacing single binding lets with as->. John
> Hume has pointed out that as-> seems to have been introduced to work
> in conjunction with ->. Which brings me to my question - do you think
> it's better to use a single binding let from a readability
> perspective? Are there any (performance or otherwise) impacts that I
> should be aware of?
>
> Cheers, Jay
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: tools for minimizing forward declaration

2013-08-19 Thread Mikera
I've found the requirement to define things in order to be a major pain in 
the following reasonably common situation:

A) public API in one namespace
B) various functions used to implement public API in another namespace

A clearly depends on B. But B often needs to depend on A also: you 
typically want to use calls to the public API as part of your 
implementation (e.g. recursively processing subcomponents in a tree-like 
data structure)

I haven't found a good solution to this yet in Clojure. Typical workarounds 
involve duplication / facades, such as having "api-function" in A call 
"api-function-impl" in B. 

My personal opinion (before anyone starts flaming - please regard as 
constructive criticism) is that Clojure is weak in this regard. Even if it 
is possible to make this sort of code work, expecting developers to jump 
through hoops, restructure their code and/or spend a lot of time 
refactoring because the language doesn't support proper forward 
declarations is not great. Clojure would be a better language IMHO if 
the environment allowed arbitrary declaration order and I think this could 
feasibly be achieved (via some judicious compiler / namespace handling 
enhancements).

On Saturday, 17 August 2013 00:53:23 UTC+8, Stuart Sierra wrote:
>
> Forward declarations are rarely necessary in my experience: you just get 
> used to defining your namespaces with low-level primitive functions at the 
> top and higher-level functions at the bottom. You only need forward 
> declarations (`declare`) in cases of mutual recursion, i.e. two functions 
> that call each other.
>
> -S
>
>
>
> On Wednesday, August 14, 2013 8:56:06 AM UTC-4, Phillip Lord wrote:
>>
>>
>> One of the things that I find unusual with clojure is the requirement 
>> for forward declaration. While I can see the advantages, managing it by 
>> hand can be a pain. 
>>
>> So I was wondering, are there any tools for adding declare statements 
>> when necessary. And better for working out how to reorder function 
>> declarations to minimize the requirement for forward declarations. 
>>
>> 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/groups/opt_out.


Re: preference and implications of using as-> vs let

2013-08-19 Thread David Nolen
While I don't think I'd use it in your particular example, I like it when
it can eliminate superfluous let bindings.

(let [z (as-> (* x x) xsq
   ...)]
   ...)


On Mon, Aug 19, 2013 at 10:58 AM, Jay Fields  wrote:

> In the past, I've written code like the following
>
> (defn foo [x y]
>   (let [x-squared (* x x)]
> (if (pos? y)
>   (+ x-squared y)
>   (- x-squared y
>
> However, the introduction of as-> has led me to write the following, at
> times
>
> (defn foo [x y]
>   (as-> (* x x) x-squared
> (if (pos? y)
>   (+ x-squared y)
>   (- x-squared y
>
> In essence, I've started replacing single binding lets with as->. John
> Hume has pointed out that as-> seems to have been introduced to work
> in conjunction with ->. Which brings me to my question - do you think
> it's better to use a single binding let from a readability
> perspective? Are there any (performance or otherwise) impacts that I
> should be aware of?
>
> Cheers, Jay
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: tools for minimizing forward declaration

2013-08-19 Thread Mark Engelberg
I agree this is a huge pain, although I don't know if I'd call it a
"forward declaration" issue as much as it is an issue with Clojure not
allowing circular dependencies among modules.

Potemkin seems to be the best way to deal with this particular scenario,
but I personally think that this is an important enough problem that a
standard mechanism for referring-and-reexporting a var should be built into
Clojure's core.

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

2013-08-19 Thread Anand Prakash
What is the major benefit of as->

=> (-> 4 (#(* % %)) (+ 12) )

28

=> (-> 4 (as-> y (* y y)) (+ 12))

28

On Monday, August 19, 2013 9:13:36 AM UTC-7, Ben Mabey wrote:
>
> On 8/19/13 8:58 AM, Jay Fields wrote: 
> > In the past, I've written code like the following 
> > 
> > (defn foo [x y] 
> >(let [x-squared (* x x)] 
> >  (if (pos? y) 
> >(+ x-squared y) 
> >(- x-squared y 
> > 
> > However, the introduction of as-> has led me to write the following, at 
> times 
> > 
> > (defn foo [x y] 
> >(as-> (* x x) x-squared 
> >  (if (pos? y) 
> >(+ x-squared y) 
> >(- x-squared y 
> > 
> > In essence, I've started replacing single binding lets with as->. John 
> > Hume has pointed out that as-> seems to have been introduced to work 
> > in conjunction with ->. Which brings me to my question - do you think 
> > it's better to use a single binding let from a readability 
> > perspective? Are there any (performance or otherwise) impacts that I 
> > should be aware of? 
> > 
> > Cheers, Jay 
> > 
> I prefer the standard `let` in these cases for readability since `as->`, 
> to me, implies some threading is going on.  I only use `as->` when I'm 
> already using `->` as it saves me an extra binding that breaks up the 
> flow of the code.  WRT performance, the only difference with the `as->` 
> version is an extra rebinding of `x-squared` as this expansion shows: 
>
> (clojure.core/let [x-squared (* x x) 
> x-squared (if (pos? y) 
> (+ x-squared y) 
> (- x-squared y))] 
>x-squared) 
>
>
> -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 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: Current state of the art in Web deployment?

2013-08-19 Thread Phil Hagelberg
On Saturday, August 17, 2013 4:51:34 PM UTC-7, Mark Mandel wrote:

>
> On Sun, Aug 18, 2013 at 6:52 AM, John Jacobsen 
> 
> > wrote:
>
>> After some prototyping and development, we are now getting to the stage 
>> where "lein run" and a Jetty server running from -main aren't going to cut 
>> it.
>
>
> At the risk of asking a dumb question, but being quite new to Clojure, I 
> don't mind - why do you say they won't cut it?
> 
>

Using Leiningen in production is actually kinda tricky due to the fact that 
you are going to want to trampoline to save memory plus avoid the default 
plugins which place dev dependencies and test directories on the classpath. 
Plus you end up having to resolve all your dependencies repeatedly for each 
server in your cluster, which can easily lead to a lack of consistency 
across a single deployment. Bad stuff.

Creating an uberjar once in a neutral environment (like a CI server) and 
distributing that makes it *much* easier to avoid these pitfalls.

Run `lein help tutorial` and skip down to "Server-side Projects" for 
details.

-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/groups/opt_out.


Re: Clojure Macro Tutorial

2013-08-19 Thread Plínio Balduino
Awesome, Steve.

Thank you for the tutorial.

Plínio


On Mon, Aug 19, 2013 at 1:10 PM, Steve Shogren wrote:

> http://deliberate-software.com/intro-to-macros/
>
> I wrote this tutorial up for a friend of mine who is a Ruby programmer
> thinking of learning Clojure, as my defense of why Clojure is worth his
> time.
>
> I will welcome any advice, code reviews, or suggestions about the post or
> code samples.
>
> Thanks!
>
> 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 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.


[ANN] FW/1 0.2.1 for Clojure released

2013-08-19 Thread Sean Corfield
What:
Framework One - a lightweight MVC framework for convention-based
Clojure web application development.

Where:
https://github.com/framework-one/fw1-clj

Usage:
Easiest way to get started:
lein new fw1 myapp && cd myapp && PORT= lein run
Now you have a minimal web application running on port  (via Jetty)

What's new?
0.2.1 Introduces support for the Selmer templating library
(previously FW/1 only supported Enlive). Selmer provides Django-style
HTML templates with {% code blocks %} and {{variable}} substitution.
Thank you Yogthos!

History:
FW/1 was originally created in 2009 and became one of the most
popular MVC frameworks for CFML so I ported it to Clojure in 2011 but
I haven't promoted it much yet. With Selmer support, FW/1 becomes much
easier to use so I'm hoping it can become a popular option for
Clojure!
-- 
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.


ANN: CFP for 2013 Workshop on Scheme and Functional Programming (co-located with Clojure/conj)

2013-08-19 Thread William Byrd
[Apologies for duplication from cross-postings.]

Important Note: This year's Workshop on Scheme and Functional Programming 
is co-located with Clojure/conj.
Clojure-related papers are encouraged, as are first-time and non-academic 
authors. --Will

---

DEADLINE: 13 September 2013
WEBSITE:  http://webyrd.net/scheme-2013/
LOCATION: Alexandria, Virginia (Washington, D.C.) (co-located with 
Clojure/conj)
DATE: 13 November 2013

The 2013 Workshop on Scheme and Functional Programming is now
accepting submissions.

Submissions related to Scheme and functional programming are welcome
and encouraged.

We also welcome papers related to dynamic or multiparadigmatic
languages and programming techniques.

Topics of interest include but are not limited to:

 contracts;
 commercial applications of Scheme; 
 compiler-implementation techniques;
 compiler optimization;
 data structures;
 domain-specific languages;
 garbage-collection;
 language-based security;
 language design;
 macros and hygiene;
 mixing static and dynamic typing;
 module systems;
 semantics;
 static analysis; 
 syntactic extensibility;
 tools and packages; and
 web-based development.

For more information, please see:

http://webyrd.net/scheme-2013/

Sincerely,

Will Byrd, 2013 Chair

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

2013-08-19 Thread u1204
Or you could use (*cough*) a literate (*cough*) programming (*cough*)
style  :-)

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

2013-08-19 Thread Tim Visher
I'll point out as well that though I thought Yegge's criticisms of
Clojure were a bit polemical (I guess that's his style), the single
pass compiler issue was one of his biggest gripes, and I do think it
still rings true. I feel like I have to babysit clojure in this
regard, when I usually feel like clojure is babysitting me! :)

On Mon, Aug 19, 2013 at 7:06 PM, Mark Engelberg
 wrote:
> I agree this is a huge pain, although I don't know if I'd call it a "forward
> declaration" issue as much as it is an issue with Clojure not allowing
> circular dependencies among modules.
>
> Potemkin seems to be the best way to deal with this particular scenario, but
> I personally think that this is an important enough problem that a standard
> mechanism for referring-and-reexporting a var should be built into Clojure's
> core.
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from 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: tools for minimizing forward declaration

2013-08-19 Thread Armando Blancas

>
> I'll point out as well that though I thought Yegge's criticisms of 
> Clojure were a bit polemical (I guess that's his style), the single 
> pass compiler issue was one of his biggest gripes, and I do think it 
> still rings true. I feel like I have to babysit clojure in this 
> regard, when I usually feel like clojure is babysitting me! :) 
>

Have you seen this? https://news.ycombinator.com/item?id=2467359

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

2013-08-19 Thread Jay Fields
On Mon, Aug 19, 2013 at 6:41 PM, Anand Prakash  wrote:
> What is the major benefit of as->
>
> => (-> 4 (#(* % %)) (+ 12) )
>
> 28
>
> => (-> 4 (as-> y (* y y)) (+ 12))
>
> 28

Solving the contrived example doesn't really help answer the original
question of preference and tradeoffs. As to the benefits of as->, I'd
defer to the benefits of threading macros in general.

The actual production code I'd originally written had this shape,
though I suspect it won't make much sense without context.

(defn foo [xrel yrel]
  (as-> (filter #(= "a val" (:a-key %)) xrel) x
(map :b-key x)
(set x)
(filter (comp x :b-key) yrel)
(set x)))

The above solution can be written in many ways, including
- a single let to build the filter predicate
(defn foo [xrel yrel]
  (let [pred (->> xrel (filter (comp (partial = "a val") :a-key)) (map
:b-key) set)]
(set (filter (comp pred :b-key) yrel

and many other options as well
- using the -> macro, wrapping the map with a (->>) and extracting the
comp to (it's own) line above
- using clojure.set/project, select-keys, & clojure.set/select
- using group-by to create a map that you use as the filter pred
etc, etc.

The two that I found the most readable were
A. the above as solution, my first example
B. single let that builds the predicate set, my second example

I find that A, in my opinion, eliminates a let, but sacrifices a bit
of readability at a high level - i.e. it's hard to look at the parts
of the function and determine the sum of what you're trying to do.
Conversely, I find that B includes a let that's strictly introduced
for readability, and sacrifices low level readability - i.e. the parts
are not easy to digest, but once you've figured them out the sum of
what you're trying to do is very obvious.

I haven't decided which I prefer, though I tend to lean towards A,
considering it to be (as David described) an elimination of a
superfluous let.

Cheers, Jay

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

2013-08-19 Thread Alan Shaw
I read those. Now I'm screaming :)
On Aug 18, 2013 11:40 PM, "Ben Wolfson"  wrote:

> Counterpoint! He's not crazy:
> https://github.com/bwo/monads/blob/master/src/monads/util.clj#L8-43
>
>
> On Sun, Aug 18, 2013 at 9:20 PM, Sean Corfield wrote:
>
>> You're crazy :)
>>
>> On Sun, Aug 18, 2013 at 9:04 PM, Chris Allen 
>> wrote:
>> > Am I crazy or does this scream macro?
>> >
>> > On Saturday, August 17, 2013 6:02:03 PM UTC-7, Sean Corfield wrote:
>> >>
>> >> On Sat, Aug 17, 2013 at 5:43 PM, yair  wrote:
>> >> > What do you mean by currying in this context?  Is there a way to do
>> this
>> >> > in
>> >> > clojure apart from using partial?
>> >>
>> >> (defn some-func
>> >>   ([a b c] (process a b c))
>> >>   ([a b]   (fn [c] (some-func a b c)))
>> >>   ([a] (fn ([b] (fn [c] (some-func a b c)))
>> >>([b c] (some-func a b c)
>> >>
>> >> (some-func 1 2 3)
>> >> ((some-func 1 2) 3)
>> >> (((some-func 1) 2) 3)
>> >> ((some-func 1) 2 3)
>> >> --
>> >> 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.
>>
>>
>>
>> --
>> 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.
>>
>
>
>
> --
> Ben Wolfson
> "Human kind has used its intelligence to vary the flavour of drinks, which
> may be sweet, aromatic, fermented or spirit-based. ... Family and social
> life also offer numerous other occasions to consume drinks for pleasure."
> [Larousse, "Drink" entry]
>
>  --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from 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: preference and implications of using as-> vs let

2013-08-19 Thread Anand Prakash
Hi Jay
Thanks for the reply. I did not know how as-> works, till I saw your 
example. I myself need to many a times chain things where in some cases the 
variable will go at the first location and in another cases it will go to 
the last location and it was a big pain to do something like what you did 
in B.

To tell you the truth I found Example A much more readable than Example B.

Thanks
Anand

On Monday, August 19, 2013 9:03:53 PM UTC-7, Jay Fields wrote:
>
> On Mon, Aug 19, 2013 at 6:41 PM, Anand Prakash 
> > 
> wrote: 
> > What is the major benefit of as-> 
> > 
> > => (-> 4 (#(* % %)) (+ 12) ) 
> > 
> > 28 
> > 
> > => (-> 4 (as-> y (* y y)) (+ 12)) 
> > 
> > 28 
>
> Solving the contrived example doesn't really help answer the original 
> question of preference and tradeoffs. As to the benefits of as->, I'd 
> defer to the benefits of threading macros in general. 
>
> The actual production code I'd originally written had this shape, 
> though I suspect it won't make much sense without context. 
>
> (defn foo [xrel yrel] 
>   (as-> (filter #(= "a val" (:a-key %)) xrel) x 
> (map :b-key x) 
> (set x) 
> (filter (comp x :b-key) yrel) 
> (set x))) 
>
> The above solution can be written in many ways, including 
> - a single let to build the filter predicate 
> (defn foo [xrel yrel] 
>   (let [pred (->> xrel (filter (comp (partial = "a val") :a-key)) (map 
> :b-key) set)] 
> (set (filter (comp pred :b-key) yrel 
>
> and many other options as well 
> - using the -> macro, wrapping the map with a (->>) and extracting the 
> comp to (it's own) line above 
> - using clojure.set/project, select-keys, & clojure.set/select 
> - using group-by to create a map that you use as the filter pred 
> etc, etc. 
>
> The two that I found the most readable were 
> A. the above as solution, my first example 
> B. single let that builds the predicate set, my second example 
>
> I find that A, in my opinion, eliminates a let, but sacrifices a bit 
> of readability at a high level - i.e. it's hard to look at the parts 
> of the function and determine the sum of what you're trying to do. 
> Conversely, I find that B includes a let that's strictly introduced 
> for readability, and sacrifices low level readability - i.e. the parts 
> are not easy to digest, but once you've figured them out the sum of 
> what you're trying to do is very obvious. 
>
> I haven't decided which I prefer, though I tend to lean towards A, 
> considering it to be (as David described) an elimination of a 
> superfluous let. 
>
> Cheers, Jay 
>

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