Re: Making things go faster

2013-06-05 Thread Tassilo Horn
David Pollak feeder.of.the.be...@gmail.com writes:

Hi David,

 * Is there a faster cycle than to change code, change tests and type
 lein test to see the results?

Obviously, you can run the tests from the already running REPL.  FWIW,
when I change something in using Emacs/nrepl.el/clojure-mode in a
namespace, I do

  C-c C-k ;; recompile the namespace
  C-c C-t ;; switch to the corresponding test namespace (I think the
  ;; original key binding is `C-c t'.)
  ;; maybe adapt the tests if needed, and if so
  C-c C-k ;; recompile the test namespace
  C-c M-n ;; switch the REPL to the test namespace
  ;; switch to the *nrepl* buffer
  (run-all-tests)

The latter can also be called with a key binding and nicer output
highlighting using clojure-test-mode, but I haven't given it a try, yet.

 * Is there a way to keep everything in a hot JVM (I've done a little
 research on Nailgun... but it seems to be out of vogue) so there's no
 JVM start-up penalty?

There's drip (https://github.com/flatland/drip) which will always keep a
fresh JVM in the background.

 * Is there a reason for the huge disparity between my MacBook Pro and
 my desktop box?

Yes, most definitively.  Unfortunately, I don't know it. ;-)

Bye,
Tassilo

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

2013-06-05 Thread Chas Emerick
Hi David,

It's odd/interesting that you're finding yourself restarting the JVM regularly. 
 For many years, I've developed Clojure with very rare restarts; especially if 
my baseline project configuration is stable, I often have REPL sessions that 
last days.

(Random thought: it'd be cute if various development environments regularly 
plinged `(.. java.lang.management.ManagementFactory getRuntimeMXBean 
getUptime)` so as to show uptime of your REPL/runtime.)

Stuart's clojure.tools.namespace patches over a couple of long-standing 
trapdoors around code loading, but I've always preferred simply loading 
files/expressions into the REPL, much as we described in the 'REPL-oriented 
Programming' chapter in the book.  I generally prefer to have as complete an 
understanding as possible of what's being loaded / being done to my REPL, and 
so various automated tools have never appealed to me.

As for testing, I've always used `clojure.test`, so re-running tests after 
changing them or the code under test has always been just a `(test-ns *ns*)` 
away.  This was actually a primary objective of mine in porting `clojure.test` 
to [clojurescript.test](https://github.com/cemerick/clojurescript.test), which 
carries forward all of the former's dynamic-runtime facilities like `test-ns` 
and `run-all-tests`, despite the lack of first-class namespaces and the static 
nature of ClojureScript compilation and Closure optimization.

In any case, whatever you do, any workflow that results in your bouncing the 
JVM is a broken one, and any tools/libraries/frameworks/whatever that push you 
in that direction are to be avoided IMO.

Cheers,

- Chas

On Jun 4, 2013, at 4:51 PM, David Pollak wrote:

 Folks,
 
 I've been doing Clojure coding for the last couple of weeks and really love 
 the language... and the community is fantastic.
 
 But the development cycle is slow.
 
 I'm coming from mostly Scala and a little Java.
 
 In Java, there's no REPL or anything... but the compile/test cycle is very 
 fast. So, I can make a few changes to code, type mvn test and see the 
 results typically in less than 2 seconds (my MacBook Pro and my Linux 
 desktop).
 
 In Scala, the compile cycles are slower than in Java because the Scala 
 compiler is doing a whole ton more. But in sbt (Simple [ha ha] Built Tool), 
 one is always building/testing in the same JVM instance so the JVM is warmed 
 up. A change code and run tests cycle is typically as fast as it is in 
 Java. For example, Changing something significant in the net.liftweb.util 
 package and doing a recompile and test takes about 9 seconds. This is running 
  450 tests.
 
 My Clojure development cycle is much slower. On my MacBook Pro (3rd gen i7 
 quadcore processor, 16GB of ram), each time I make a change and re-run the 
 test for Plugh ( https://github.com/projectplugh/plugh ) it takes about 20 
 second and there are only 4 tests. On my desktop Linux box (i7-3770 with 32gb 
 of RAM) it takes about 4 seconds to run the 4 tests. I also ran stuff on a 
 very old ThinkPad (core 2 duo with 4GB ram running Linux Mint 15) and the 
 test cycle takes 12 second.
 
 So... the questions:
 
 * Is there a faster cycle than to change code, change tests and type lein 
 test to see the results?
 * Is there a way to keep everything in a hot JVM (I've done a little research 
 on Nailgun... but it seems to be out of vogue) so there's no JVM start-up 
 penalty?
 * Is there a reason for the huge disparity between my MacBook Pro and my 
 desktop box?
 
 Thanks,
 
 David
 
 
 -- 
 Telegram, Simply Beautiful CMS https://telegr.am
 Lift, the simply functional web framework http://liftweb.net
 Follow me: http://twitter.com/dpp
 Blog: http://goodstuff.im
 
 
 -- 
 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group 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 

Is it good functional style to use a protocol to create a plugin point?

2013-06-05 Thread john
Hi,
I recently wrote some code for which I have 2 alternative implementations.
So what I did is write a protocol:

(defprotocol Calculator
 (calc-add [this data])
 (calc-multiply [this data]))
 
  
I then created two namespaces for my two implementations:
which each had a function:

(defn make-calculator []
  (reify Calculator
(calc-add [this data] .)
 (calc-multiply [this data]))
 
So my core code was using this protocol and I can switch  implementation by 
just handing my protocol-using-code a different make-calculator.

But am I really doing programming in a functional style?
 
I mean I am creating with reify a class only so that my different 
implementation gets called.
This reify makes me think this is not functional but more OO like.

On the other hand it is very nice to have a grouping of certain functions 
and it makes it clear this protocol 
is a plugin point for custom implementations.

I don't know?! Am I just complaining about perfect readable side effect 
free code? 

Many Greetings
John

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: Is it good functional style to use a protocol to create a plugin point?

2013-06-05 Thread Moritz Ulrich
If you want to keep this style, why not use a simple map of function
instead of reifying a protocol? Something like:

(defn calc-multiply [data] ...)
(defn calc-add [data] ...)
(defn make-calc [] {:calc-add #'calc-add, :calc-multiply #'calc-multiply})

Looks simpler and cleaner for me.

On Wed, Jun 5, 2013 at 12:16 PM, john john.vie...@gmail.com wrote:
 Hi,
 I recently wrote some code for which I have 2 alternative implementations.
 So what I did is write a protocol:

 (defprotocol Calculator
  (calc-add [this data])
 (calc-multiply [this data]))


 I then created two namespaces for my two implementations:
 which each had a function:

 (defn make-calculator []
   (reify Calculator
 (calc-add [this data] .)
 (calc-multiply [this data]))

 So my core code was using this protocol and I can switch  implementation by
 just handing my protocol-using-code a different make-calculator.

 But am I really doing programming in a functional style?

 I mean I am creating with reify a class only so that my different
 implementation gets called.
 This reify makes me think this is not functional but more OO like.

 On the other hand it is very nice to have a grouping of certain functions
 and it makes it clear this protocol
 is a plugin point for custom implementations.

 I don't know?! Am I just complaining about perfect readable side effect free
 code?

 Many Greetings
 John

 --
 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group 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: Is it good functional style to use a protocol to create a plugin point?

2013-06-05 Thread john
yes that seems to me, that this better expresses that I'm plugging in  a 
set of functions.
thanks

Am Mittwoch, 5. Juni 2013 12:55:16 UTC+2 schrieb Moritz Ulrich:

 If you want to keep this style, why not use a simple map of function 
 instead of reifying a protocol? Something like: 

 (defn calc-multiply [data] ...) 
 (defn calc-add [data] ...) 
 (defn make-calc [] {:calc-add #'calc-add, :calc-multiply #'calc-multiply}) 

 Looks simpler and cleaner for me. 

 On Wed, Jun 5, 2013 at 12:16 PM, john john@gmail.com javascript: 
 wrote: 
  Hi, 
  I recently wrote some code for which I have 2 alternative 
 implementations. 
  So what I did is write a protocol: 
  
  (defprotocol Calculator 
   (calc-add [this data]) 
  (calc-multiply [this data])) 
  
  
  I then created two namespaces for my two implementations: 
  which each had a function: 
  
  (defn make-calculator [] 
(reify Calculator 
  (calc-add [this data] .) 
  (calc-multiply [this data])) 
  
  So my core code was using this protocol and I can switch  implementation 
 by 
  just handing my protocol-using-code a different make-calculator. 
  
  But am I really doing programming in a functional style? 
  
  I mean I am creating with reify a class only so that my different 
  implementation gets called. 
  This reify makes me think this is not functional but more OO like. 
  
  On the other hand it is very nice to have a grouping of certain 
 functions 
  and it makes it clear this protocol 
  is a plugin point for custom implementations. 
  
  I don't know?! Am I just complaining about perfect readable side effect 
 free 
  code? 
  
  Many Greetings 
  John 
  
  -- 
  -- 
  You received this message because you are subscribed to the Google 
  Groups Clojure group. 
  To post to this group, send email to clo...@googlegroups.comjavascript: 
  Note that posts from new members are moderated - please be patient with 
 your 
  first post. 
  To unsubscribe from this group, send email to 
  clojure+u...@googlegroups.com javascript: 
  For more options, visit this group at 
  http://groups.google.com/group/clojure?hl=en 
  --- 
  You received this message because you are subscribed to the Google 
 Groups 
  Clojure group. 
  To unsubscribe from this group and stop receiving emails from it, send 
 an 
  email to clojure+u...@googlegroups.com javascript:. 
  For more options, visit https://groups.google.com/groups/opt_out. 
  
  


-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




My Clojure Workflow, Reloaded

2013-06-05 Thread Julian
Stuart Sierra has written a fantastic article on his particular pattern for 
writing and testing Clojure code:
http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

There is some commentary on Hacker News about it here:
https://news.ycombinator.com/item?id=5819487

I'll include some of the salient points

Therefore, after every significant code change, I want to restart the 
application from scratch. But I don't want to restart the JVM and reload 
all my Clojure code in order to do it: that takes too long and is too 
disruptive to my workflow. Instead, I want to design my application in such 
a way that I can quickly shut it down, discard any transient state it might 
have built up, start it again, and return to a similar state. And when I 
say quickly, I mean that the whole process should take less than a second.


To achieve this goal, I make the application itself into a transient 
object. Instead of the application being a singleton tied to a JVM process, 
I write code to construct instances of my application, possibly many of 
them within one JVM. Each time I make a change, I discard the old instance 
and construct a new one. The technique is similar to dealing with virtual 
machines in a cloud environment: rather than try to transition a VM from an 
old state to a new state, we simply discard the old one and spin up a new 
one.


My questions to the fantastic hacker new communities are:
(1) Have you used this technique on your project?
(2) What is your experiences using this technique?
(3) Stuart hints that particular projects have to be structured to be able 
to better use this technique - can you point to a particular project that 
is well suited to this?


 

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: My Clojure Workflow, Reloaded

2013-06-05 Thread Angel Java Lopez
It was recently discussed at
https://groups.google.com/group/clojure/browse_thread/thread/f1a3bb6563fecf1c?hl=en

See also
 http://blog.goodstuff.im/clojure_workflow

Angel Java Lopez
@ajlopez



On Wed, Jun 5, 2013 at 8:21 AM, Julian juliangam...@gmail.com wrote:

 Stuart Sierra has written a fantastic article on his particular pattern
 for writing and testing Clojure code:
 http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

 There is some commentary on Hacker News about it here:
 https://news.ycombinator.com/item?id=5819487

 I'll include some of the salient points

 Therefore, after every significant code change, I want to restart the
 application from scratch. But I don't want to restart the JVM and reload
 all my Clojure code in order to do it: that takes too long and is too
 disruptive to my workflow. Instead, I want to design my application in such
 a way that I can quickly shut it down, discard any transient state it might
 have built up, start it again, and return to a similar state. And when I
 say quickly, I mean that the whole process should take less than a second.


 To achieve this goal, I make the application itself into a transient
 object. Instead of the application being a singleton tied to a JVM process,
 I write code to construct instances of my application, possibly many of
 them within one JVM. Each time I make a change, I discard the old instance
 and construct a new one. The technique is similar to dealing with virtual
 machines in a cloud environment: rather than try to transition a VM from an
 old state to a new state, we simply discard the old one and spin up a new
 one.


 My questions to the fantastic hacker new communities are:
 (1) Have you used this technique on your project?
 (2) What is your experiences using this technique?
 (3) Stuart hints that particular projects have to be structured to be able
 to better use this technique - can you point to a particular project that
 is well suited to this?




 --
 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/groups/opt_out.




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

2013-06-05 Thread Adam Rulli-Gibbs
What's wrong with midje's (autotest) in the REPL? I save code or test and 
the tests relevant to the namespace are automatically run.

On Wednesday, 5 June 2013 05:16:39 UTC+1, red...@gmail.com wrote:

 midje makes each test a top level form, so test runs happen as a side 
 effect of code loading, which means you cannot really run tests in a good 
 way from the repl without doing some kind of ridiculous forced code 
 reloading. I would definitely recommend staying far away from midje, if you 
 want a tight test loop the repl is your best bet, and midje's design makes 
 using it from the repl really awkward.

 I have heard horror stories about drip jvms being launched with stale 
 args, etc, but that is anecdotal, and a while ago so maybe it is great, I 
 don't use it and have no interest in it, largely because I use the repl.


 On Wed, Jun 5, 2013 at 12:09 AM, Hoàng Minh Thắng 
 p...@banphim.netjavascript:
  wrote:

 * Is there a faster cycle than to change code, change tests and type 
 lein test to see the results?

 my favourite workflow is with lein-midje (you can run both midje tests 
 and clojure tests!)
 https://github.com/marick/lein-midje

 * Is there a way to keep everything in a hot JVM (I've done a little 
 research on Nailgun... but it seems to be out of vogue) so there's no JVM 
 start-up penalty?

 Try drip:
  https://github.com/flatland/drip/

 -- 
 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.comjavascript:
 Note that posts from new members are moderated - please be patient with 
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@googlegroups.com javascript:
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+u...@googlegroups.com javascript:.
 For more options, visit https://groups.google.com/groups/opt_out.
  
  




 -- 
 And what is good, Phaedrus,
 And what is not good—
 Need we ask anyone to tell us these things? 


-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: Is it good functional style to use a protocol to create a plugin point?

2013-06-05 Thread fmjrey
A map seems enough, unless there is a need for naming the set of functions, 
in which case the protocol could serve this purpose. But would that be the 
best way?
I'm also curious to know what solutions the community has come up with 
about this. In the case of dynamic discovery of available plugins/services, 
what solutions are there within the clojure space (i.e. not java/osgi).
Are protocols the best way to do this?
Any there any kind of plugin discovery and dynamic binding out there?

On Wednesday, June 5, 2013 1:11:57 PM UTC+2, john wrote:

 yes that seems to me, that this better expresses that I'm plugging in  a 
 set of functions.
 thanks



-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Is it good functional style to use a protocol to create a plugin point?

2013-06-05 Thread Jim
I think this approach , no matter how decoupled it may be, HotSpot will 
have a hard time (if not impossible) inlining these fn-calls.
The protocol approach you described will give you the best performance, 
especially if you type-hint your reify block.
That said, for plugin type situations I prefer multi-methods because you 
don't have to declare/group any fns up front. Whenever you need 
extension point you just add a `defmethod`.  For your use-case this 
means something like the following, which I'll admit is not very 
pretty... the general problem is that since you're doing numerical 
computation multi-methods are a bit of an overkill...when you generalise 
it a bit more though multi-methods are great...


(defmulti calculate (fn [operator _] operator))
(defmethod calculate + [_ data] (apply + data))
(defmethod calculate *  [_ data] (apply * data))

user= (calculate + (range 100))
4950
user= (calculate * (range 100))
0
user= (calculate * (range 1 100))
ArithmeticException integer overflow 
clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)

user= (calculate * (range 1 10))
362880

Jim

ps: another nice and functional approach would be this:

(defn make-calculator [operator]
   (fn [ data] (apply operator data)))

(defn calculate [calculator data]
  (apply calculator data))

which you call like this:

(- (make-calculator +)
(calculate (range 25)))
=300

HTH, :)


On 05/06/13 11:55, Moritz Ulrich wrote:

If you want to keep this style, why not use a simple map of function
instead of reifying a protocol? Something like:

(defn calc-multiply [data] ...)
(defn calc-add [data] ...)
(defn make-calc [] {:calc-add #'calc-add, :calc-multiply #'calc-multiply})

Looks simpler and cleaner for me.

On Wed, Jun 5, 2013 at 12:16 PM, john john.vie...@gmail.com wrote:

Hi,
I recently wrote some code for which I have 2 alternative implementations.
So what I did is write a protocol:

(defprotocol Calculator
  (calc-add [this data])
(calc-multiply [this data]))


I then created two namespaces for my two implementations:
which each had a function:

(defn make-calculator []
   (reify Calculator
 (calc-add [this data] .)
(calc-multiply [this data]))

So my core code was using this protocol and I can switch  implementation by
just handing my protocol-using-code a different make-calculator.

But am I really doing programming in a functional style?

I mean I am creating with reify a class only so that my different
implementation gets called.
This reify makes me think this is not functional but more OO like.

On the other hand it is very nice to have a grouping of certain functions
and it makes it clear this protocol
is a plugin point for custom implementations.

I don't know?! Am I just complaining about perfect readable side effect free
code?

Many Greetings
John

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




NullPointerException when creating protocol in macro

2013-06-05 Thread Vincent
I’m trying to write a macro that defines a protocol and a function that, 
when called, returns an implementation of that protocol.

I’ve reduced the code to the following example:
(defmacro create-protocol [protocol implementation]
  (let [[protocol-name signature] protocol]
`(do
   (defprotocol ~protocol-name ~signature)
   (fn [] (reify ~protocol-name ~implementation)

(let [f (create-protocol [P (method [this])]
 (method [this] (println method)))]
  (method (f)))


The original code is more complicated, where the function will read a value 
from a file and, depending on that value, return the appropriate 
implementation of the protocol.

When I run Clojure 1.5.1 on that code I get the following exception:
Exception in thread main java.lang.NullPointerException, 
compiling:(protocol.clj:7:9)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6567)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6548)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.analyze(Compiler.java:6322)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5708)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5139)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3751)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6558)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6548)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.analyze(Compiler.java:6322)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5708)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6548)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.access$100(Compiler.java:37)
at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:5973)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.analyze(Compiler.java:6322)
at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5708)
at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5139)
at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3751)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6558)
at clojure.lang.Compiler.analyze(Compiler.java:6361)
at clojure.lang.Compiler.eval(Compiler.java:6616)
at clojure.lang.Compiler.load(Compiler.java:7064)
at clojure.lang.Compiler.loadFile(Compiler.java:7020)
at clojure.main$load_script.invoke(main.clj:294)
at clojure.main$script_opt.invoke(main.clj:356)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:415)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at clojure.lang.Compiler.resolveIn(Compiler.java:6840)
at clojure.lang.Compiler.resolve(Compiler.java:6818)
at clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:7427)
at 
clojure.lang.Compiler$NewInstanceExpr$ReifyParser.parse(Compiler.java:7377)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
... 38 more

From what I understood by tracing through the compiler it seems that the P 
var is created at macro expansion time but bound at execution time only. 
When expanding the ‘reify’ macro, P is still unbound, which yields a nil 
interface, which triggers the NPE.

I could solve the problem by redefining the macro in the following way:
(defmacro create-protocol [protocol implementation]
  (let [[protocol-name signature] protocol]
(eval `(defprotocol ~protocol-name ~signature))
`(fn [] (reify ~protocol-name ~implementation

Using eval doesn’t feel right though.

I guess I could modify my code to avoid using protocols, but it seemed to 
me to be the most natural way of achieving what I wanted.

I was just wondering if anybody had any opinion or suggestion about that. 
Am I going off track? Is there a more idiomatic way of doing things that I 
missed?

Thanks,
Vincent

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

Re: [ANN] alpacas: a new Clojure source viewer

2013-06-05 Thread John Gabriele
On Tuesday, June 4, 2013 4:24:49 PM UTC-4, Gary Trakhman wrote:

 Just fyi, most clojure libs are published under EPL or Apache licenses, of 
 course the choice is up to you :-).  GPL has some restrictions that would 
 prevent the lib from being used in many projects.

 from the EPL wikipedia page: 'The EPL 1.0 is not 
 compatiblehttp://en.wikipedia.org/wiki/License_compatibility with 
 the GPL, and a work created by combining a work licensed under the GPL with 
 a work licensed under the EPL cannot be lawfully distributed.'


LGPL is also a fine choice for Clojure libs.

-- John

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: [ANN] alpacas: a new Clojure source viewer

2013-06-05 Thread Laurent PETIT
Hello,

2013/6/5 John Gabriele jmg3...@gmail.com:
 On Tuesday, June 4, 2013 4:24:49 PM UTC-4, Gary Trakhman wrote:

 Just fyi, most clojure libs are published under EPL or Apache licenses, of
 course the choice is up to you :-).  GPL has some restrictions that would
 prevent the lib from being used in many projects.

 from the EPL wikipedia page: 'The EPL 1.0 is not compatible with the GPL,
 and a work created by combining a work licensed under the GPL with a work
 licensed under the EPL cannot be lawfully distributed.'


 LGPL is also a fine choice for Clojure libs.

Given that it is by default suggested to use the EPL for Open Source
Clojure projects, what would be the incentive to use LGPL.

tl;dr: when should I prefer LGPL over EPL for a Clojure lib ?

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




parsing xml with zip, xml and clojure.data.zip

2013-06-05 Thread Ryan Moore
Hi, I've read http://nakkaya.com/2009/12/07/zipping-xml-with-clojure/ and 
http://stackoverflow.com/questions/1194044/clojure-xml-parsing/9595315#comment24442712_9595315
 , 
but the usage of (xml-) is still mysterious to me.

If I have this for my xml file...
(def myxml (zip-str level1
level2 a='the attribute'
   level3aText in level 3a/level3a
   level3bText in level 3b./level3b
/level2
  /level1))

My question is how the xml- function determines how nested you have to 
specify things. Eg
(xml- myxml :level1 text)
= ()
(xml- myxml :level2 text)
= (Text in level 3aText in level 3b.)
(xml- myxml :level2 :level3a text)
= (Text in level 3a)

The last call gives the text in 3a, but why don't you have to specifiy that 
it is under level 1 as well as level 2?

Thanks

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: Making things go faster

2013-06-05 Thread Ben Mabey

On 6/4/13 10:16 PM, Kevin Downey wrote:
midje makes each test a top level form, so test runs happen as a side 
effect of code loading, which means you cannot really run tests in a 
good way from the repl without doing some kind of ridiculous forced 
code reloading. I would definitely recommend staying far away from 
midje, if you want a tight test loop the repl is your best bet, and 
midje's design makes using it from the repl really awkward.




When was the last time you tried to use midje from the REPL?  Ever since 
the 1.5 release I've found the workflow quite nice and usable.


-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: Best IDE

2013-06-05 Thread Catonano
My 2 cents:

it´s ture that the Emacs features are not discoverable and that the
learning curve is mean.

But it also true that once you´ve done it, it brings you a great value.

My suggestions about Emacs:

1) Start with the footage by Peepcode. It´ll save you tons of time,
especially if you´re not accustomed to reading the f... manuals and prefer
to see people do stuff while explaining them to you as if you were seated
side by side. The Emacs docs are daunting, in my experience

2) progress towards Overtone-Live https://github.com/overtone/emacs-live .
It´s a selection of packages and configurations for Clojure, and it´s
awesome. With that you have a REPL inside Emacs and you can even evaluate
Clojure expressioons from inside your buffer, you have autocompletion. M-.
brings you to the code of the function at point (probably not of the record
or macro at poin) at M-, brings back where you started from. Also the
paredits combo to nest a sexp into another or to bring it out are really
cool. There´s also a thing to search stuff and it makes the screen
translucid with some characters colored in red and it you press the keys
correpsonding to those chars it... does something I didn´t have time to try
it ;-)

3) Consider that in the 24.x version there´s the package managent stuff.
A combination of el-get and the ELPA based stuff can get you a long way. I
managed to install a hairy setup for the autocompletion in python. My
feeling is that this gives you a somewhat bigger control on your Emacs
configuration.

4) consider that in order to reach a satisfying level, you don´t need to
have it perfectly and completely set up. There are professionals who only
use clojure mode and they keep a terminal with a repl aside and they switch
back and forth and copy and paste expressions from te buffer to the repl in
order to explore what they´re doing. That´s a perfectly acceptabe set up

5) it´s true that the debugging situation is less than ideal. I didn´t try
the machinery for clojure debugging because it´s not supported in Live and
I didn´t have time to install it myself, but when the need to debug
something arised, I copied subexpressions of my expressions and see the
results to try to isolate the sections generating problems. I concede it´s
not ideal but it´s reasonable in clojure and it probably wouldn´t be in an
imperative language. I keep the intention to stabilize the configuraion for
a better debugging too.

6) A wildly weird suggestion: consider meeting with Emacs users with more
experience and do stuff together. It´s not unreasonable as it sounds.
There´s value in that. In my opinion, of course.

7) last but not least, in ripping my arguments to shreds, please consider
that if you feel my opinions are gonna ruin some honest beginner, I could
feel the same about yours. Our opinions are relative to the single
individuals and to gazillions of other things. Also, here´s a human being
on the other side of the wire and although I have learned not to contribute
to the heat of the polemics, it still takes me some effort to keep calm, as
I don´t always have time to stay on track with my meditation practice.
OOhhhm ;-)


2013/6/5 Duane Searsmith dsearsm...@gmail.com

 Has ne1 looked at emacs or light table or netbeans or eclipse or vim or
 Intelli what ... don't know ... let us post an IDE FAQ please!


 On Tue, Jun 4, 2013 at 12:53 PM, Alan Thompson thompson2...@gmail.comwrote:

 Have any of you looked at Light Table?
 http://www.chris-granger.com/2012/04/12/light-table---a-new-ide-concept/

 I wonder what it would take to get a VIM-like mode available with that?
 Alan


 On Tue, Jun 4, 2013 at 10:27 AM, Alex Baranosky 
 alexander.barano...@gmail.com wrote:

 There are things I love and hate about both Emacs and Intellij, so after
 a year of working professionally with a bunch of Clojure-Emacs users, I
 still end up using Intellij about half the time, and get my fair share of
 harassment over it.  I'd like to merge the two actually if possible.


 On Tue, Jun 4, 2013 at 7:20 AM, Gary Trakhman 
 gary.trakh...@gmail.comwrote:

 I used eclipse emacs+ for about a year for java code once I had started
 writing clojure in emacs, it made me more productive, but it was a hassle
 to set up.

 Unfortunately, when eclipse updated itself to juno, it broke, and there
 is still no support.

 Going forward, I think this is a more compelling solution to get some
 of the benefits of eclipse in emacs:
 https://github.com/senny/emacs-eclim

 But, I think it's not quite there yet.


 On Tue, Jun 4, 2013 at 9:02 AM, Kelker Ryan theinter...@yandex.comwrote:

 Have you tried Eclipse Emacs+?
 http://marketplace.eclipse.org/content/emacs

 04.06.2013, 21:41, Korny Sietsma ko...@sietsma.com:

 My 2c - I use emacs, I love it.  I don't inflict it on my team, and I
 strongly disagree with it being easy.  To learn the basics, yes, but 
 full
 fluency?  If you have someone fluent in IntelliJ, with the major 
 keystrokes
 in their muscle memory, and 

Re: parsing xml with zip, xml and clojure.data.zip

2013-06-05 Thread gaz jones
This may help:

http://clojure-doc.org/articles/tutorials/parsing_xml_with_zippers.html


On Wed, Jun 5, 2013 at 9:54 AM, Ryan Moore niclas1...@gmail.com wrote:

 Hi, I've read http://nakkaya.com/2009/12/07/zipping-xml-with-clojure/ and
 http://stackoverflow.com/questions/1194044/clojure-xml-parsing/9595315#comment24442712_9595315
  ,
 but the usage of (xml-) is still mysterious to me.

 If I have this for my xml file...
 (def myxml (zip-str level1
 level2 a='the attribute'
level3aText in level 3a/level3a
level3bText in level 3b./level3b
 /level2
   /level1))

 My question is how the xml- function determines how nested you have to
 specify things. Eg
 (xml- myxml :level1 text)
 = ()
 (xml- myxml :level2 text)
 = (Text in level 3aText in level 3b.)
 (xml- myxml :level2 :level3a text)
 = (Text in level 3a)

 The last call gives the text in 3a, but why don't you have to specifiy
 that it is under level 1 as well as level 2?

 Thanks

 --
 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because you are subscribed to the Google Groups
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/groups/opt_out.




-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: [ANN] alpacas: a new Clojure source viewer

2013-06-05 Thread David Powell
Personally, I think there is too much guesswork involved in understanding
what the LGPL means re Java.

For example, from http://jtds.sourceforge.net/license.html, a Java library:

Using jTDS is considered to be dynamic linking; hence our interpretation of
 the LGPL is that the use of the unmodified jTDS source or binary does not
 affect the license of your application code.


The authors were kind enough to say what their interpretation of the
license is - most LGPL libraries don't; but what if you distribute an LGPL
library with an application as an uberjar - that may well be outside of
what is permitted - I don't know.  Is it outside the spirit of the 6b) of
the LGPL, which seems to be intended to allow the user to easily swap in
implementations.

It just seems easier to stick to EPL, especially if you want to allow
commercial use of the library.



On Wed, Jun 5, 2013 at 2:48 PM, John Gabriele jmg3...@gmail.com wrote:

 On Tuesday, June 4, 2013 4:24:49 PM UTC-4, Gary Trakhman wrote:

 Just fyi, most clojure libs are published under EPL or Apache licenses,
 of course the choice is up to you :-).  GPL has some restrictions that
 would prevent the lib from being used in many projects.

 from the EPL wikipedia page: 'The EPL 1.0 is not 
 compatiblehttp://en.wikipedia.org/wiki/License_compatibility with
 the GPL, and a work created by combining a work licensed under the GPL with
 a work licensed under the EPL cannot be lawfully distributed.'


 LGPL is also a fine choice for Clojure libs.

 -- John

  --
 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group 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: parsing xml with zip, xml and clojure.data.zip

2013-06-05 Thread Stefan Kamphausen
AFAIK your var myxml already refers to the root node of your XML document.  

So your first example searches for a tag called level1 inside the root 
tag (which is level1).  Obviously, there is no such node and the text is 
empty.

Your second example extracts a textual representation of the child nodes 
(plural) of tag level2.

The third example references the tag level3a inside the tag level2 and 
extracts the text, which contains no more child nodes but just the text.

Hope that helps
Stefan

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




importing a java class which 'requires' your namespace in a static block

2013-06-05 Thread Jim - FooBar();

Hello everyone,

weirdness strikes again!

I've got the following situation:

- a namespace core.clj which imports a java class, let's call it Foo.java
- Foo.java requires core.clj in the usual way :

 private static IFn requireFn =   RT.var(clojure.core, 
require).fn();

 static { requireFn.invoke(Symbol.intern(someNamespace.core)); }

Now, the first time I (load-file xxx.core.clj) everything is perfectly 
fine. The minute I make a change and re-load I get:


NoClassDefFoundError Could not initialize class yyy.Foo

have you ever had that? what do you do when one of your java sources 
delegates back to a namespace of yours? is that completely bad design 
perhaps?


thanks for your time,

Jim

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

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: importing a java class which 'requires' your namespace in a static block

2013-06-05 Thread Gary Trakhman
One problem with doing this in a static initializer is that you lose the
relevant exception.  I would try moving this to a constructor or lazy-load
it, and you might get a better error message.


On Wed, Jun 5, 2013 at 1:28 PM, Jim - FooBar(); jimpil1...@gmail.comwrote:

 Hello everyone,

 weirdness strikes again!

 I've got the following situation:

 - a namespace core.clj which imports a java class, let's call it Foo.java
 - Foo.java requires core.clj in the usual way :

  private static IFn requireFn =   RT.var(clojure.core,
 require).fn();
  static { requireFn.invoke(Symbol.**intern(someNamespace.core)); }

 Now, the first time I (load-file xxx.core.clj) everything is perfectly
 fine. The minute I make a change and re-load I get:

 NoClassDefFoundError Could not initialize class yyy.Foo

 have you ever had that? what do you do when one of your java sources
 delegates back to a namespace of yours? is that completely bad design
 perhaps?

 thanks for your time,

 Jim

 --
 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en
 --- You received this message because you are subscribed to the Google
 Groups Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to 
 clojure+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com
 .
 For more options, visit 
 https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out
 .




-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: importing a java class which 'requires' your namespace in a static block

2013-06-05 Thread Jim - FooBar();

On 05/06/13 18:40, Gary Trakhman wrote:
One problem with doing this in a static initializer is that you lose 
the relevant exception.  I would try moving this to a constructor or 
lazy-load it, and you might get a better error message.


doing what you suggested seems to alleviate the problem! I'm still not 
quite sure what happened but I can reload my namespace just fine!


thanks! :)

Jim

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

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: importing a java class which 'requires' your namespace in a static block

2013-06-05 Thread Softaddicts
The other alternative is to extend the class loader to add a trap.
I do not have the code handy but you might find it using a search on google.


Luc


 One problem with doing this in a static initializer is that you lose the
 relevant exception.  I would try moving this to a constructor or lazy-load
 it, and you might get a better error message.
 
 
 On Wed, Jun 5, 2013 at 1:28 PM, Jim - FooBar(); jimpil1...@gmail.comwrote:
 
  Hello everyone,
 
  weirdness strikes again!
 
  I've got the following situation:
 
  - a namespace core.clj which imports a java class, let's call it Foo.java
  - Foo.java requires core.clj in the usual way :
 
   private static IFn requireFn =   RT.var(clojure.core,
  require).fn();
   static { requireFn.invoke(Symbol.**intern(someNamespace.core)); }
 
  Now, the first time I (load-file xxx.core.clj) everything is perfectly
  fine. The minute I make a change and re-load I get:
 
  NoClassDefFoundError Could not initialize class yyy.Foo
 
  have you ever had that? what do you do when one of your java sources
  delegates back to a namespace of yours? is that completely bad design
  perhaps?
 
  thanks for your time,
 
  Jim
 
  --
  --
  You received this message because you are subscribed to the Google
  Groups Clojure group.
  To post to this group, send email to clojure@googlegroups.com
  Note that posts from new members are moderated - please be patient with
  your first post.
  To unsubscribe from this group, send email to
  clojure+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com
  For more options, visit this group at
  http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en
  --- You received this message because you are subscribed to the Google
  Groups Clojure group.
  To unsubscribe from this group and stop receiving emails from it, send an
  email to 
  clojure+unsubscribe@**googlegroups.comclojure%2bunsubscr...@googlegroups.com
  .
  For more options, visit 
  https://groups.google.com/**groups/opt_outhttps://groups.google.com/groups/opt_out
  .
 
 
 
 
 -- 
 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 --- 
 You received this message because you are subscribed to the Google Groups 
 Clojure group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 
 
--
Softaddictslprefonta...@softaddicts.ca sent by ibisMail from my ipad!

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

2013-06-05 Thread Alan Thompson
Nice summary on the blog.  Might I suggest one small improvement?  How
about:

(do (use 'plugh.file-test :reload-all) (run-tests) )

Then, just a single up-arrow ret sequence.  :)
Alan Thompson

P.S.  I'm still working on getting GVIM+fireplace set up, which should
allow me to do everything from within the editor.


On Tue, Jun 4, 2013 at 6:42 PM, David Pollak
feeder.of.the.be...@gmail.comwrote:

 Thanks for pointing me in the right direction. I did a quick blog post to
 help other newbies:

 http://blog.goodstuff.im/clojure_workflow



 On Tue, Jun 4, 2013 at 1:54 PM, Tim Visher tim.vis...@gmail.com wrote:

 On Tue, Jun 4, 2013 at 4:51 PM, David Pollak
 feeder.of.the.be...@gmail.com wrote:
  So... the questions:
 
  * Is there a faster cycle than to change code, change tests and type
 lein
  test to see the results?
  * Is there a way to keep everything in a hot JVM (I've done a little
  research on Nailgun... but it seems to be out of vogue) so there's no
 JVM
  start-up penalty?
  * Is there a reason for the huge disparity between my MacBook Pro and my
  desktop box?

 http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-reloaded

 Seems relevant. :)

 I don't have time to write it down, but much of what you're doing
 isn't very idiomatic and there's vast opportunities for improvement.
 Someone'll let you know. :)

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





 --
 Telegram, Simply Beautiful CMS https://telegr.am
 Lift, the simply functional web framework http://liftweb.net
 Follow me: http://twitter.com/dpp
 Blog: http://goodstuff.im

  --
 --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com
 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com
 For more options, visit this group 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: importing a java class which 'requires' your namespace in a static block

2013-06-05 Thread Marshall Bockrath-Vandegrift
Jim - FooBar(); jimpil1...@gmail.com writes:

 Now, the first time I (load-file xxx.core.clj) everything is
 perfectly fine. The minute I make a change and re-load I get:

 NoClassDefFoundError Could not initialize class yyy.Foo

This confuses me, because the JVM should only be loading and
initializing the Java class once.  Re-loading the Clojure namespace
shouldn’t report an error unless initialization actually failed the
first time around.

That said, you will definitely get errors if you have a Java class
`require` a namespace in a static initializer which then `import`s the
class.  Clojure `import` causes referenced classes to be initialized,
which runs static initializers, which means a circular namespace -
initializer - namespace dependency effectively reduces to a circular
namespace dependency.

The solution I’ve been using lately is to push the Java-side
namespace-loading into a private static inner class of the original Java
class.  This provides the benefits of JVM-managed single-initialization,
but defers execution of that initialization code until something
actually needs one of the imported Vars.  Example:


https://github.com/damballa/abracad/blob/master/src/java/abracad/avro/ClojureDatumReader.java

HTH,

-Marshall

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: [ANN] alpacas: a new Clojure source viewer

2013-06-05 Thread Lee Spector

On Jun 4, 2013, at 4:13 PM, Andrea Chiavazza wrote:

 Alpacas is an application that displays Clojure source code with forms shown 
 as nested boxes, doing away with parenthesis altogether.

FWIW somewhat related ideas go back a couple of decades. Some pointers can be 
found at http://www.cs.umd.edu/hcil/members/bshneiderman/nsd/

 -Lee

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




lein clojars plugin and latest version of leiningen

2013-06-05 Thread Mark Engelberg
I've been using the lein clojars plugin to deploy to clojars with the lein
push command.  It's been working great for me, but today, it's not
working.  I recently upgraded to the newest version of leiningen, and
that's the only major change I can think of since my last deployment, so
I'm speculating that there may be a change with the way the newest version
of leiningen builds, or more specifically, *where* it puts the built jar
file.

See, the error message is telling me that the lein push command is
building the jar file and putting it in target/provided, but then when it
goes to upload the jar, it looks for it in the target directory (not
target/provided).

So. is this a new change that puts it into the provided subdirectory of
target?  If so, what's the easiest way to get lein push working again?

Thanks,

Mark

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

2013-06-05 Thread Stuart Sierra
Hi Vincent,

`defprotocol` is a top-level form, not really meant to be mixed with 
value-returning expressions like `fn`. Protocols are always global because 
of how they compile into Java interfaces.

Here's one way to make it work, by defining a symbol instead of returning a 
function:

(defmacro create-protocol [protocol symbol implementation]
  (let [[protocol-name signature] protocol]
`(do
   (defprotocol ~protocol-name ~signature)
   (defn ~symbol [] (reify ~protocol-name ~implementation)

(create-protocol [P (method [this])]
 constructor
 (method [this] (println method)))

(method (constructor))

-S


On Wednesday, June 5, 2013 9:16:05 AM UTC-4, Vincent wrote:

 I’m trying to write a macro that defines a protocol and a function that, 
 when called, returns an implementation of that protocol.

 I’ve reduced the code to the following example:
 (defmacro create-protocol [protocol implementation]
   (let [[protocol-name signature] protocol]
 `(do
(defprotocol ~protocol-name ~signature)
(fn [] (reify ~protocol-name ~implementation)

 (let [f (create-protocol [P (method [this])]
  (method [this] (println method)))]
   (method (f)))


 The original code is more complicated, where the function will read a 
 value from a file and, depending on that value, return the appropriate 
 implementation of the protocol.

 When I run Clojure 1.5.1 on that code I get the following exception:
 Exception in thread main java.lang.NullPointerException, 
 compiling:(protocol.clj:7:9)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6567)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6548)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.analyze(Compiler.java:6322)
 at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5708)
 at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5139)
 at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3751)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6558)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6548)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.analyze(Compiler.java:6322)
 at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5708)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6548)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.access$100(Compiler.java:37)
 at clojure.lang.Compiler$LetExpr$Parser.parse(Compiler.java:5973)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.analyze(Compiler.java:6322)
 at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5708)
 at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5139)
 at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3751)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6558)
 at clojure.lang.Compiler.analyze(Compiler.java:6361)
 at clojure.lang.Compiler.eval(Compiler.java:6616)
 at clojure.lang.Compiler.load(Compiler.java:7064)
 at clojure.lang.Compiler.loadFile(Compiler.java:7020)
 at clojure.main$load_script.invoke(main.clj:294)
 at clojure.main$script_opt.invoke(main.clj:356)
 at clojure.main$main.doInvoke(main.clj:440)
 at clojure.lang.RestFn.invoke(RestFn.java:408)
 at clojure.lang.Var.invoke(Var.java:415)
 at clojure.lang.AFn.applyToHelper(AFn.java:161)
 at clojure.lang.Var.applyTo(Var.java:532)
 at clojure.main.main(main.java:37)
 Caused by: java.lang.NullPointerException
 at clojure.lang.Compiler.resolveIn(Compiler.java:6840)
 at clojure.lang.Compiler.resolve(Compiler.java:6818)
 at clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:7427)
 at 
 clojure.lang.Compiler$NewInstanceExpr$ReifyParser.parse(Compiler.java:7377)
 at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
 ... 38 more

 From what I understood by tracing through the compiler it seems that the P 
 var is created at macro expansion time but bound at execution time only. 
 When expanding the ‘reify’ macro, P is still unbound, which yields a nil 
 interface, which triggers the NPE.

 I could solve the problem by redefining the macro in the following way:
 (defmacro create-protocol [protocol implementation]
   (let [[protocol-name signature] protocol]
 (eval `(defprotocol ~protocol-name ~signature))
 `(fn [] (reify ~protocol-name ~implementation

 Using eval doesn’t feel right though.

 I guess I could modify my code to avoid using protocols, but it seemed to 
 me to be the most natural way of achieving what I wanted.

 I 

Re: parsing xml with zip, xml and clojure.data.zip

2013-06-05 Thread Ryan Moore
Ahh, so if the var refers to the root that would explain why specifying the 
root never returns anything. Thanks.

On Wednesday, June 5, 2013 11:54:49 AM UTC-4, Stefan Kamphausen wrote:

 AFAIK your var myxml already refers to the root node of your XML 
 document.  

 So your first example searches for a tag called level1 inside the root 
 tag (which is level1).  Obviously, there is no such node and the text is 
 empty.

 Your second example extracts a textual representation of the child nodes 
 (plural) of tag level2.

 The third example references the tag level3a inside the tag level2 and 
 extracts the text, which contains no more child nodes but just the text.

 Hope that helps
 Stefan


-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: Utility libraries and dependency hygiene

2013-06-05 Thread Mark Engelberg
This thread came up right around the time I was considering adding a
dependency on rhizome to instaparse to make it easy to visualize the parse
trees.  Based on the discussion here, I decided it would be a bad idea to
include rhizome directly in instaparse's dependencies.  Nevertheless, it
made sense to enable the visualize function *provided* rhizome was
already in the user's dependencies.  More specifically, it will use
whichever version of rhizome they choose to put in their dependencies, thus
a version conflict is not an issue.

I found a technique to achieve this effect, and wanted to report on it here.

First, towards the top of the file, after the namespace declaration, I
included the following:

(try
  (require '[rhizome.viz :as r])
  (catch Exception e
(require '[instaparse.viz-not-found :as r])))

This sets things up so r/ refers either to the rhizome.viz namespace, or if
it is not installed, my dummy instaparse.viz-not-found namespace.  The
instaparse.viz-not-found contains stubs for all the functions from rhizome
that I use; the stubs simply throw a friendly error message saying to add
rhizome to the project's dependencies.

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: [ANN] alpacas: a new Clojure source viewer

2013-06-05 Thread Colin Fleming
Right, FWIW in my previous company we disallowed LGPL libraries because of
the clause that explicitly allows reverse engineering to substitute
different versions of the library. Of course, it's unlikely that anyone
would ever do this but it would be a support nightmare if they did, so it
was just easier to avoid the problem altogether. Rightly or wrongly a lot
of companies think this way so LGPL can affect commercial adoption
(assuming you're interested in that, of course).


On 6 June 2013 03:46, David Powell djpow...@djpowell.net wrote:

 Personally, I think there is too much guesswork involved in understanding
 what the LGPL means re Java.

 For example, from http://jtds.sourceforge.net/license.html, a Java
 library:

 Using jTDS is considered to be dynamic linking; hence our interpretation
 of the LGPL is that the use of the unmodified jTDS source or binary does
 not affect the license of your application code.


 The authors were kind enough to say what their interpretation of the
 license is - most LGPL libraries don't; but what if you distribute an LGPL
 library with an application as an uberjar - that may well be outside of
 what is permitted - I don't know.  Is it outside the spirit of the 6b) of
 the LGPL, which seems to be intended to allow the user to easily swap in
 implementations.

 It just seems easier to stick to EPL, especially if you want to allow
 commercial use of the library.



 On Wed, Jun 5, 2013 at 2:48 PM, John Gabriele jmg3...@gmail.com wrote:

 On Tuesday, June 4, 2013 4:24:49 PM UTC-4, Gary Trakhman wrote:

 Just fyi, most clojure libs are published under EPL or Apache licenses,
 of course the choice is up to you :-).  GPL has some restrictions that
 would prevent the lib from being used in many projects.

 from the EPL wikipedia page: 'The EPL 1.0 is not 
 compatiblehttp://en.wikipedia.org/wiki/License_compatibility with
 the GPL, and a work created by combining a work licensed under the GPL with
 a work licensed under the EPL cannot be lawfully distributed.'


 LGPL is also a fine choice for Clojure libs.

 -- John

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




-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: [ANN] alpacas: a new Clojure source viewer

2013-06-05 Thread Colin Fleming
Interesting, I think I like this presentation better, I found the explicit
boxes in the OP a little distracting. I guess this then becomes more like
Python-style significant indentation, which might be an interesting
approach too.


On 5 June 2013 12:15, Matthew Chadwick mathn...@gmail.com wrote:

 hehe looks similar to something I've been writing:

 http://celeriac.net/ioio/public/

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

2013-06-05 Thread Colin Fleming
*`defprotocol` is a top-level form...*

This is interesting, and it's something I've wondered about. As far as I
can tell, there's really no distinction between top-level forms and other
forms, for example this is legal and works:

(defn define-my-functions []
  (defn test-1 []
1)
  (defn test-2 []
2))
= #=(var plugin.performance.project/define-my-functions)
test-1
= Unbound: #'plugin.performance.project/test-1
test-2
= Unbound: #'plugin.performance.project/test-2
(define-my-functions)
= #=(var plugin.performance.project/test-2)
test-1
= plugin.performance.project$define_my_functions$test_1__3112@30e63c09
test-2
= plugin.performance.project$define_my_functions$test_2__3114@24ae6e0a

Given this, are there any forms that are genuinely top-level from the
compiler's point of view? I'm assuming defining functions like this is
generally discouraged, but defining them inside of let-forms seems
relatively common:

(let [a 1]
  (defn get-a []
a))
= #=(var plugin.performance.project/get-a)
(get-a)
= 1




On 6 June 2013 09:57, Stuart Sierra the.stuart.sie...@gmail.com wrote:

 Hi Vincent,

 `defprotocol` is a top-level form, not really meant to be mixed with
 value-returning expressions like `fn`. Protocols are always global because
 of how they compile into Java interfaces.

 Here's one way to make it work, by defining a symbol instead of returning
 a function:

 (defmacro create-protocol [protocol symbol implementation]

   (let [[protocol-name signature] protocol]
 `(do
(defprotocol ~protocol-name ~signature)
(defn ~symbol [] (reify ~protocol-name ~implementation)


 (create-protocol [P (method [this])]
  constructor

  (method [this] (println method)))

 (method (constructor))

 -S



 On Wednesday, June 5, 2013 9:16:05 AM UTC-4, Vincent wrote:

 I’m trying to write a macro that defines a protocol and a function that,
 when called, returns an implementation of that protocol.

 I’ve reduced the code to the following example:
 (defmacro create-protocol [protocol implementation]
   (let [[protocol-name signature] protocol]
 `(do
(defprotocol ~protocol-name ~signature)
(fn [] (reify ~protocol-name ~implementation)

 (let [f (create-protocol [P (method [this])]
  (method [this] (println method)))]
   (method (f)))


 The original code is more complicated, where the function will read a
 value from a file and, depending on that value, return the appropriate
 implementation of the protocol.

 When I run Clojure 1.5.1 on that code I get the following exception:
 Exception in thread main java.lang.**NullPointerException,
 compiling:(protocol.clj:7:9)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6567)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6548)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.analyze(**Compiler.java:6322)
 at clojure.lang.Compiler$**BodyExpr$Parser.parse(**
 Compiler.java:5708)
 at clojure.lang.Compiler$**FnMethod.parse(Compiler.java:**5139)
 at clojure.lang.Compiler$FnExpr.**parse(Compiler.java:3751)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6558)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6548)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.analyze(**Compiler.java:6322)
 at clojure.lang.Compiler$**BodyExpr$Parser.parse(**
 Compiler.java:5708)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6560)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6548)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.access$**100(Compiler.java:37)
 at clojure.lang.Compiler$LetExpr$**Parser.parse(Compiler.java:**5973)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6560)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.analyze(**Compiler.java:6322)
 at clojure.lang.Compiler$**BodyExpr$Parser.parse(**
 Compiler.java:5708)
 at clojure.lang.Compiler$**FnMethod.parse(Compiler.java:**5139)
 at clojure.lang.Compiler$FnExpr.**parse(Compiler.java:3751)
 at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6558)
 at clojure.lang.Compiler.analyze(**Compiler.java:6361)
 at clojure.lang.Compiler.eval(**Compiler.java:6616)
 at clojure.lang.Compiler.load(**Compiler.java:7064)
 at clojure.lang.Compiler.**loadFile(Compiler.java:7020)
 at clojure.main$load_script.**invoke(main.clj:294)
 at clojure.main$script_opt.**invoke(main.clj:356)
 at clojure.main$main.doInvoke(**main.clj:440)
 at clojure.lang.RestFn.invoke(**RestFn.java:408)
 at clojure.lang.Var.invoke(Var.**java:415)
 at clojure.lang.AFn.**applyToHelper(AFn.java:161)
 

Re: NullPointerException when creating protocol in macro

2013-06-05 Thread Stuart Sierra
On Wed, Jun 5, 2013 at 7:35 PM, Colin Fleming
colin.mailingl...@gmail.comwrote:

 Given this, are there any forms that are genuinely top-level from the
 compiler's point of view?



It's never explicitly enforced, just a consequence of how the compiler
creates and loads Java classes. Generally, the things which compile
directly to named Java classes -- defprotocol, deftype, defrecord -- may
not work except as top-level forms, as Vincent discovered.

-S

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.




Re: NullPointerException when creating protocol in macro

2013-06-05 Thread Softaddicts
Legal but comparable to a hidden side effect with all the pitfalls that can 
derive
from this.

It's not a compiler issue, more a discipline issue.

Having a helper macro like Stuart suggest is acceptable to me
if it's called at top level, it's always done. There's less ambiguity.

Using def/defn in a function is less desirable, the definition/redefinition 
occurs when you
call the fn and it may occur at less desirable times or could be hard to spot.

If you need a local fn, let-fn is exactly for this purpose. The scope is limited
to the let-fn body.

Luc P.


 *`defprotocol` is a top-level form...*
  This is interesting, and it's something I've wondered about. As far as I
 can tell, there's really no distinction between top-level forms and other
 forms, for example this is legal and works:
  (defn define-my-functions []
   (defn test-1 []
 1)
   (defn test-2 []
 2))
 = #=(var plugin.performance.project/define-my-functions)
 test-1
 = Unbound: #'plugin.performance.project/test-1
 test-2
 = Unbound: #'plugin.performance.project/test-2
 (define-my-functions)
 = #=(var plugin.performance.project/test-2)
 test-1
 = plugin.performance.project$define_my_functions$test_1__3112@30e63c09
 test-2
 = plugin.performance.project$define_my_functions$test_2__3114@24ae6e0a
  Given this, are there any forms that are genuinely top-level from the
 compiler's point of view? I'm assuming defining functions like this is
 generally discouraged, but defining them inside of let-forms seems
 relatively common:
  (let [a 1]
   (defn get-a []
 a))
 = #=(var plugin.performance.project/get-a)
 (get-a)
 = 1
 On 6 June 2013 09:57, Stuart Sierra the.stuart.sie...@gmail.com 
 wrote:
   Hi Vincent,
 
  `defprotocol` is a top-level form, not really meant to be mixed with
  value-returning expressions like `fn`. Protocols are always global because
  of how they compile into Java interfaces.
 
  Here's one way to make it work, by defining a symbol instead of returning
  a function:
 
  (defmacro create-protocol [protocol symbol implementation]
 
(let [[protocol-name signature] protocol]
  `(do
 (defprotocol ~protocol-name ~signature)
 (defn ~symbol [] (reify ~protocol-name ~implementation)
 
 
  (create-protocol [P (method [this])]
   constructor
 
   (method [this] (println method)))
 
  (method (constructor))
 
  -S
 
 
 
  On Wednesday, June 5, 2013 9:16:05 AM UTC-4, Vincent wrote:
 
  I’m trying to write a macro that defines a protocol and a function that,
  when called, returns an implementation of that protocol.
 
  I’ve reduced the code to the following example:
  (defmacro create-protocol [protocol implementation]
(let [[protocol-name signature] protocol]
  `(do
 (defprotocol ~protocol-name ~signature)
 (fn [] (reify ~protocol-name ~implementation)
 
  (let [f (create-protocol [P (method [this])]
   (method [this] (println method)))]
(method (f)))
 
 
  The original code is more complicated, where the function will read a
  value from a file and, depending on that value, return the appropriate
  implementation of the protocol.
 
  When I run Clojure 1.5.1 on that code I get the following exception:
  Exception in thread main java.lang.**NullPointerException,
  compiling:(protocol.clj:7:9)
  at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6567)
  at clojure.lang.Compiler.analyze(**Compiler.java:6361)
  at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6548)
  at clojure.lang.Compiler.analyze(**Compiler.java:6361)
  at clojure.lang.Compiler.analyze(**Compiler.java:6322)
  at clojure.lang.Compiler$**BodyExpr$Parser.parse(**
  Compiler.java:5708)
  at clojure.lang.Compiler$**FnMethod.parse(Compiler.java:**5139)
  at clojure.lang.Compiler$FnExpr.**parse(Compiler.java:3751)
  at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6558)
  at clojure.lang.Compiler.analyze(**Compiler.java:6361)
  at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6548)
  at clojure.lang.Compiler.analyze(**Compiler.java:6361)
  at clojure.lang.Compiler.analyze(**Compiler.java:6322)
  at clojure.lang.Compiler$**BodyExpr$Parser.parse(**
  Compiler.java:5708)
  at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6560)
  at clojure.lang.Compiler.analyze(**Compiler.java:6361)
  at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6548)
  at clojure.lang.Compiler.analyze(**Compiler.java:6361)
  at clojure.lang.Compiler.access$**100(Compiler.java:37)
  at clojure.lang.Compiler$LetExpr$**Parser.parse(Compiler.java:**5973)
  at clojure.lang.Compiler.**analyzeSeq(Compiler.java:6560)
  at clojure.lang.Compiler.analyze(**Compiler.java:6361)
  at clojure.lang.Compiler.analyze(**Compiler.java:6322)
  at clojure.lang.Compiler$**BodyExpr$Parser.parse(**
  Compiler.java:5708)
  at clojure.lang.Compiler$**FnMethod.parse(Compiler.java:**5139)
   

Re: lein clojars plugin and latest version of leiningen

2013-06-05 Thread Phil Hagelberg
On Jun 5, 2:54 pm, Mark Engelberg mark.engelb...@gmail.com wrote:
 So. is this a new change that puts it into the provided subdirectory of
 target?  If so, what's the easiest way to get lein push working again?

Yeah, you can set :target-path in project.clj to just target to get
the old behaviour.

AFAIK `lein push` is just a simple wrapper around scp, so `lein do
pom, jar  scp pom.xml target/foo.jar cloj...@clojars.org:` (with a
shell alias or something) is another way to work around this.

-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: Making things go faster

2013-06-05 Thread Brian Marick

On Jun 4, 2013, at 3:51 PM, David Pollak feeder.of.the.be...@gmail.com wrote:

 * Is there a faster cycle than to change code, change tests and type lein 
 test to see the results?

I use Midje in a repl. That looks like this:

  % lein repl
  (use 'midje.repl)
  (autotest)

When I save a source or test file, the relevant (transitive closure) tests get 
run. That usually happens in the time it takes me to move my eyes to the Emacs 
window that the repl lives in. 

I didn't used to like (Ruby) autotest in my workflow, but I've concluded I was 
wrong.

In combination with some Emacs hackery I've done to make sure the source, test, 
and repl are all simultaneously visible, I'm finding this workflow decidedly 
competitive with Intellij/Java or Emacs/Ruby.


Latest book: /Functional Programming for the Object-Oriented Programmer/
https://leanpub.com/fp-oo

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

2013-06-05 Thread Brian Marick

On Jun 4, 2013, at 11:16 PM, Kevin Downey redc...@gmail.com wrote:

 midje makes each test a top level form, so test runs happen as a side effect 
 of code loading, which means you cannot really run tests in a good way from 
 the repl without doing some kind of ridiculous forced code reloading. I would 
 definitely recommend staying far away from midje, if you want a tight test 
 loop the repl is your best bet, and midje's design makes using it from the 
 repl really awkward.

That hasn't been true since 1.5. 


Latest book: /Functional Programming for the Object-Oriented Programmer/
https://leanpub.com/fp-oo

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

2013-06-05 Thread Brian Marick

On Jun 4, 2013, at 11:16 PM, Kevin Downey redc...@gmail.com wrote:

 midje makes each test a top level form, so test runs happen as a side effect 
 of code loading, which means you cannot really run tests in a good way from 
 the repl without doing some kind of ridiculous forced code reloading. I would 
 definitely recommend staying far away from midje, if you want a tight test 
 loop the repl is your best bet, and midje's design makes using it from the 
 repl really awkward.

That hasn't been true since 1.5. 


Latest book: /Functional Programming for the Object-Oriented Programmer/
https://leanpub.com/fp-oo

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

2013-06-05 Thread Mikera
My setup is usually:

 - Eclipse with Counterclockwise plugin
 - Keep an open, running REPL at all times
 - Reload namespaces when necessary (Ctrl+Alt+L)
 - Run tests with clojure.test from the REPL

This avoids the startup overhead most of the time - I usually only use the 
Maven / leiningen command line when doing a build (in this case, a new JVM 
instance is probably desirable anyway for the purpose of testing in a fresh 
environment).

Note that the problem is actually the Clojure startup time, *not* the JVM 
startup. JVM starts up in about 0.1sec on my machine. The rest of the time 
is spend loading Clojure code, compiling all the core namespaces etc.

On Wednesday, 5 June 2013 04:51:10 UTC+8, David Pollak wrote:

 Folks,

 I've been doing Clojure coding for the last couple of weeks and really 
 love the language... and the community is fantastic.

 But the development cycle is slow.

 I'm coming from mostly Scala and a little Java.

 In Java, there's no REPL or anything... but the compile/test cycle is very 
 fast. So, I can make a few changes to code, type mvn test and see the 
 results typically in less than 2 seconds (my MacBook Pro and my Linux 
 desktop).

 In Scala, the compile cycles are slower than in Java because the Scala 
 compiler is doing a whole ton more. But in sbt (Simple [ha ha] Built Tool), 
 one is always building/testing in the same JVM instance so the JVM is 
 warmed up. A change code and run tests cycle is typically as fast as it 
 is in Java. For example, Changing something significant in the 
 net.liftweb.util package and doing a recompile and test takes about 9 
 seconds. This is running  450 tests.

 My Clojure development cycle is much slower. On my MacBook Pro (3rd gen i7 
 quadcore processor, 16GB of ram), each time I make a change and re-run the 
 test for Plugh ( https://github.com/projectplugh/plugh ) it takes about 
 20 second and there are only 4 tests. On my desktop Linux box (i7-3770 with 
 32gb of RAM) it takes about 4 seconds to run the 4 tests. I also ran stuff 
 on a very old ThinkPad (core 2 duo with 4GB ram running Linux Mint 15) and 
 the test cycle takes 12 second.

 So... the questions:

 * Is there a faster cycle than to change code, change tests and type lein 
 test to see the results?
 * Is there a way to keep everything in a hot JVM (I've done a little 
 research on Nailgun... but it seems to be out of vogue) so there's no JVM 
 start-up penalty?
 * Is there a reason for the huge disparity between my MacBook Pro and my 
 desktop box?

 Thanks,

 David


 -- 
 Telegram, Simply Beautiful CMS https://telegr.am
 Lift, the simply functional web framework http://liftweb.net
 Follow me: http://twitter.com/dpp
 Blog: http://goodstuff.im

  

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

2013-06-05 Thread Ben Smith-Mannschott
edn-java [1] is a parser and printer for edn [2].

This release fixes issue31 [3] single quote in a string is incorrectly
escaped.

It is available on Maven Central [4].

// Ben

[1] http://edn-java.bpsm.us
[2] https://github.com/edn-format/edn
[3] https://github.com/bpsm/edn-java/issues/31
[4]
http://search.maven.org/#artifactdetails%7Cus.bpsm%7Cedn-java%7C0.4.1%7Cjar

-- 
-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group 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: [ANN] alpacas: a new Clojure source viewer

2013-06-05 Thread John Gabriele
On Wednesday, June 5, 2013 10:34:35 AM UTC-4, Laurent PETIT wrote:


 tl;dr: when should I prefer LGPL over EPL for a Clojure lib ? 


Have a look at the brief summary at 
http://docs.python-guide.org/en/latest/writing/license.html . If you care 
more about item #2 on that 2-item list, then you may prefer LGPL over EPL.

-- John

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