:bootclasspath causes java.lang.NullPointerException

2015-09-02 Thread J . Pablo Fernández
Hello,

I'm trying to compile my project with :bootclasspath set to true, so as to 
have the jar for a java agent added to my classpath, but in one of my 
projects it's generating java.lang.NullPointerException on this line:

(def app (middleware/wrap-base #'app-base))

which is preceded by:

(defroutes base-routes
   (route/resources "/")
   (route/not-found "Not Found"))

(def app-base
  (routes
(var service-routes)
(wrap-routes #'home-routes middleware/wrap-csrf)
#'base-routes))

The full backtrace is:

java.lang.NullPointerException, compiling:(handler.clj:86:10)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3628)
at clojure.lang.Compiler$DefExpr.eval(Compiler.java:439)
at clojure.lang.Compiler.compile1(Compiler.java:7323)
at clojure.lang.Compiler.compile(Compiler.java:7390)
at clojure.lang.RT.compile(RT.java:399)
at clojure.lang.RT.load(RT.java:444)
at clojure.lang.RT.load(RT.java:412)
at clojure.core$load$fn__5448.invoke(core.clj:5866)
at clojure.core$load.doInvoke(core.clj:5865)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5671)
at clojure.core$load_lib$fn__5397.invoke(core.clj:5711)
at clojure.core$load_lib.doInvoke(core.clj:5710)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$load_libs.doInvoke(core.clj:5749)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$require.doInvoke(core.clj:5832)
at clojure.lang.RestFn.invoke(RestFn.java:482)
at projectx.core$loading__5340__auto21.invoke(core.clj:3)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3623)
at clojure.lang.Compiler.compile1(Compiler.java:7323)
at clojure.lang.Compiler.compile1(Compiler.java:7313)
at clojure.lang.Compiler.compile(Compiler.java:7390)
at clojure.lang.RT.compile(RT.java:399)
at clojure.lang.RT.load(RT.java:444)
at clojure.lang.RT.load(RT.java:412)
at clojure.core$load$fn__5448.invoke(core.clj:5866)
at clojure.core$load.doInvoke(core.clj:5865)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5671)
at clojure.core$compile$fn__5453.invoke(core.clj:5877)
at clojure.core$compile.invoke(core.clj:5876)
at user$eval9$fn__16.invoke(form-init8240839476947253640.clj:1)
at user$eval9.invoke(form-init8240839476947253640.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6782)
at clojure.lang.Compiler.eval(Compiler.java:6772)
at clojure.lang.Compiler.load(Compiler.java:7227)
at clojure.lang.Compiler.loadFile(Compiler.java:7165)
at clojure.main$load_script.invoke(main.clj:275)
at clojure.main$init_opt.invoke(main.clj:280)
at clojure.main$initialize.invoke(main.clj:308)
at clojure.main$null_opt.invoke(main.clj:343)
at clojure.main$main.doInvoke(main.clj:421)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at 
org.webjars.WebJarAssetLocator.listParentURLsWithResource(WebJarAssetLocator.java:66)
at org.webjars.WebJarAssetLocator.getAssetPaths(WebJarAssetLocator.java:84)
at 
org.webjars.WebJarAssetLocator.getFullPathIndex(WebJarAssetLocator.java:121)
at org.webjars.WebJarAssetLocator.(WebJarAssetLocator.java:152)
at ring.middleware.webjars$wrap_webjars.invoke(webjars.clj:27)
at ring.middleware.webjars$wrap_webjars.invoke(webjars.clj:25)
at projectx.middleware$wrap_base.invoke(middleware.clj:90)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3623)
... 51 more
Exception in thread "main" java.lang.NullPointerException, 
compiling:(handler.clj:86:10)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3628)
at clojure.lang.Compiler$DefExpr.eval(Compiler.java:439)
at clojure.lang.Compiler.compile1(Compiler.java:7323)
at clojure.lang.Compiler.compile(Compiler.java:7390)
at clojure.lang.RT.compile(RT.java:399)
at clojure.lang.RT.load(RT.java:444)
at clojure.lang.RT.load(RT.java:412)
at clojure.core$load$fn__5448.invoke(core.clj:5866)
at clojure.core$load.doInvoke(core.clj:5865)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5671)
at clojure.core$load_lib$fn__5397.invoke(core.clj:5711)
at clojure.core$load_lib.doInvoke(core.clj:5710)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$load_libs.doInvoke(core.clj:5749)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:632)
at clojure.core$require.doInvoke(core.clj:5832)
at clojure.lang.RestFn.invoke(RestFn.java:482)
at projectx.core$loading__5340__auto21.invoke(core.clj:3)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at 

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-06 Thread J . Pablo Fernández
On 5 August 2015 at 19:33, James Reeves ja...@booleanknot.com wrote:

 So when you're testing, presumably you use a dynamic binding to override
 the global connection to the test database?


The wrap transaction always overrides the dynamic binding, whether it's in
tests or not.

-- 
J. Pablo Fernández pup...@pupeno.com (http://pupeno.com)

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-04 Thread J . Pablo Fernández
On 3 August 2015 at 23:47, Rob Lally rob.la...@gmail.com wrote:

 I’m also a little confused by your suggestion that it would be impossible
 to enclose each test in a transaction. The article you point to shows one
 way.


It shows how to pass data to the test by using a dynamic var, which is what
we are using to track the connection, which is what I'm interested in
passing in to the test. If my solution to use a dynamic var to track the
connection is dirty and unacceptable, so is that one. The only difference I
can think of is, using a dynamic var only for tests dirties only tests but
using a dynamic var to track connections is consistent across the code-base.


-- 
J. Pablo Fernández pup...@pupeno.com (http://pupeno.com)

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread J . Pablo Fernández
Other than the fact that this approach doesn't reach the level of
functional purity that some people want, after playing with it for a while,
we found it very productive and leads to clean/readable code and tests, so
we decided to turn it into a library:

https://clojars.org/conman

https://github.com/luminus-framework/conman

You are still in control of the connection so you can do other things with
it and have more than one if necessary.

On 31 July 2015 at 01:44, J. Pablo Fernández pup...@pupeno.com wrote:

 Hello Clojurians,

 I found passing around the database connection to each function that uses
 it very error prone when you are using transactions as passing the wrong
 one could mean a query runs outside the transaction when in the source code
 it is inside the with-db-transaction function. So I ended up defining the
 db namespace like this:

 (ns db)

 (defonce ^:dynamic conn (atom nil))

 (defn connect!
   (reset conn (generate-new-connection)))

 (defn run-query
   [query] (run-query query @conn)
   [query conn] (run-the-query-in-connection query conn))


 This is pseudo-code of course, simplified to highlight the part that I'm
 most unfamiliar with:

 (defonce ^:dynamic conn (atom nil))

 The reason why it's an atom is so that connect! can *set* it and the
 reason why it's a dynamic var is so I can do this:

 (jdbc/with-db-transaction
 [db-connection-with-transaction @db/conn]
 (binding [db/conn (atom db-connection-with-transaction)]
   (db/run-query SELECT *))

 and the query will be implicitly run inside the transaction. Does it make
 sense? Is this wrong? will it fail in unexpected ways? Is there a better
 way?

 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 a topic in the
 Google Groups Clojure group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/clojure/fRi554wbPSk/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to
 clojure+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.




-- 
J. Pablo Fernández pup...@pupeno.com (http://pupeno.com)

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread J . Pablo Fernández
Rob,

The transactions are not global, the transactions are local. Connections
are global and there's no way around it with the constraints of a
traditional RDBMs. Your idea of making the global connection unavailable
for code that's in the context of a transaction would prevent the errors
I'm trying to prevent but you would still required to pass the connection
around, which in a webapp, means that the whole chain of function calls,
pretty much everything, would have a database connection. That is ugly in
some cases, impossible in others.

A piece of code that would be impossible is to enclose each test in a
transaction using clojure.test:
http://stackoverflow.com/questions/31735423/how-to-pass-a-value-from-a-fixture-to-a-test-with-clojure-test

Furthermore, I don't think this solution gains you any purity, you still
have a global estate and you are hiding it away when starting a
transaction. My proposal was to make it work instead of hiding it. They are
rather equivalent from the complexity point of view.

On 1 August 2015 at 18:29, Rob Lally rob.la...@gmail.com wrote:

 Hey Pablo,

 I could be wrong, but it seems that the key problem here is the existence
 of the global transaction. If the global transaction didn’t exist then any
 time you failed to pass in a transaction the code would fail: immediately
 and loudly.

 I appreciate what you’re trying to do but it seems like you’re on a path
 to solve the problems caused by one shared, implicit, global variable by
 creating more shared, implicit, slightly less global, variables and that
 doesn’t seem like it is going to end well. Implicit connections in a
 binding will fail in, perhaps mysterious ways if you ever include any sort
 of concurrency: even things as simple as asynchronous logging can start
 logging wrong values or missing values.

 Can you somehow render the global connection inoperable in some way?
 Perhaps redefine it, point it at a data source that doesn’t exist or… by
 some other hook-or-crook have it fail in a loud, grotesque manner if it is
 touched?


 R.




 On 31 Jul 2015, at 01:54, J. Pablo Fernández pup...@pupeno.com wrote:

 Hello James,

 Thanks for your answer. I do understand your point. Pure functions are
 easier to reason about and my use of dynamic here breaks that purity. I'm
 not doing it lightly. It already happened to me, that one of those
 functions that was running inside the transaction, was not passed the
 transaction connection and instead got the global one and the failure was
 silent and very hard to debug, and this was with a project that has less
 than 200 lines of code. I'm trying to find patterns that will work when
 this project has 200k lines of code.

 For me, the thing is, I have a traditional relational database here, this
 is already far from pure. For example, calling (db/create-user 
 pup...@pupeno.com) twice will not only not return the same thing the
 second time, it'll actually raise an exception the second time. Also, the
 database connection is *global state* unless each function creates its own
 connection, which would be terrible. So, this global state also breaks
 functional purity.

 The problem with the second aspect of breaking purity as far as I can see
 is this: at some point, this global state has to be picked up and used, so
 at some point a function will *not* get a database connection passed to it
 but *will* access the database by using this global connection. I haven't
 advanced this project enough to say this with 100% certainty, but, I think
 there's going to be more than one function like that and at some point I'll
 need to have one inside the other so I need them to be composable. Let me
 show you a naive example:

 db/create-user is the low level database function that creates a record in
 the user table
 user/create is the function used to create a user, it takes care of, for
 example, encrypting the password.
 account/register is the function to register a new user, it takes care of
 creating a user but also validation, sending a welcome email and so on.

 So each function calls the predecessor there and would pass the database
 connection, account/register, being the entry point, would grab it from the
 global state so it doesn't get a connection passed to it. So far, a lot of
 it looks like pure functions (let's ignore the fact that a database breaks
 that purity). The problem arises when I get another function,
 account/invite, that is used to register a bunch of people one after the
 other, so that account/invite would call account/register many times. The
 problem is that account/invite *can't* start a transaction and have
 account/register and all its inner functions use that transaction when that
 makes a lot of sense.

 To make account/register composable it needs to accept an optional
 database connection and use that one if it's present, or the global one if
 it's not. Every time a function does that there's a high risk of picking
 the wrong database and account

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread J . Pablo Fernández
James,

I'm not new to functional programming and I understand the principles and
why they are good. I worked in Haskell, Erlang and other Lisps before. Even
if only a tiny portion of my codebase deals with the database, I still need
a pattern for that part of the codebase.

It is very easy to say this is dirty, you should not do this without
offering an alternative solution and by alternative solution I mean one
that applies to the pattern of making web applications that are database
heavy. Think of your traditional CRUD application, you can say quarentine
the code that deals with the database and yes, you can do that, but it
still is 90% of the code.





On 3 August 2015 at 06:00, James Gatannah james.gatan...@gmail.com wrote:



 On Thursday, July 30, 2015 at 7:44:31 PM UTC-5, J. Pablo Fernández wrote:

 Hello Clojurians,

 I found passing around the database connection to each function that uses
 it very error prone when you are using transactions as passing the wrong
 one could mean a query runs outside the transaction when in the source code
 it is inside the with-db-transaction function.


 I'll go ahead and make the point that it's error-prone for different
 reasons.

 Pretty much by definition, that database connection is a system boundary.
 It's all about something that's *way* more complex than random global state
 changes inside your program. This is a thing that interacts with the
 outside world, with all the nastiness that implies.

 Everything that everyone else has already written about this approach is
 true, but I don't think they've gone far enough.

 Even if you pass that database connection around as a parameter
 everywhere, you're talking about throwing away a huge part of the benefit
 of using a functional language.

 Isolate your side-effects.

 Think of a castle. You have a moat surrounding it, and a few gates that
 you use to allow your peasants to enter/exit. This particular gate opens up
 to a swamp full of alligators.

 Your approach amounts to letting the gators wander around loose.

 Passing the connection around to each function in the call chain is like
 tying a ribbon around the gator's neck and hoping you can use that as a
 leash.

 You can use either approach to great effect. If you're really, really
 good. And so is everyone else on your team (you did mention a 200 KLOC
 project).

 One of the main benefits to functional programming is that admitting you
 aren't really, really good is incredibly liberating. I don't have the
 time/energy to dedicate to trying to maintain this sort of code. (Yes, I
 spent lots of time recently thinking about how java was designed for very
 average programmers, but it really takes much better programmers than a
 functional language to actually write correct programs). Even if I were
 that good...I'd rather be focused on the problems that make my customers
 happy.

 I'm going to appeal to authority here for the right answer:
 http://prog21.dadgum.com/23.html (in my defense, it's a great blog). Have
 your web response handler (which is another system boundary...this one is
 next to an active volcano populated by fire-breathing dragons) build up a
 list of all the nasty side-effects that will eventually have to happen.

 Don't just isolate your side-effects. Quarantine those suckers as if each
 and every one means you're dealing with the most diabolical hacker you can
 imagine.

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




-- 
J. Pablo Fernández pup...@pupeno.com (http://pupeno.com)

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-31 Thread J . Pablo Fernández


On Friday, 31 July 2015 11:48:54 UTC+1, Colin Yates wrote:

 I am away from the code at the moment, but is there any reason why the 
 dynamic connection can’t be private? This goes some way to providing safety.


No, I don't think there's a problem with it being private, I just didn't 
think of it and my code to handle transactions is in a different namespace, 
but it should go in the db namespace anyway and then it can easily made 
private. 

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-07-31 Thread J . Pablo Fernández
Hello James,

Thanks for your answer. I do understand your point. Pure functions are
easier to reason about and my use of dynamic here breaks that purity. I'm
not doing it lightly. It already happened to me, that one of those
functions that was running inside the transaction, was not passed the
transaction connection and instead got the global one and the failure was
silent and very hard to debug, and this was with a project that has less
than 200 lines of code. I'm trying to find patterns that will work when
this project has 200k lines of code.

For me, the thing is, I have a traditional relational database here, this
is already far from pure. For example, calling (db/create-user 
pup...@pupeno.com) twice will not only not return the same thing the
second time, it'll actually raise an exception the second time. Also, the
database connection is *global state* unless each function creates its own
connection, which would be terrible. So, this global state also breaks
functional purity.

The problem with the second aspect of breaking purity as far as I can see
is this: at some point, this global state has to be picked up and used, so
at some point a function will *not* get a database connection passed to it
but *will* access the database by using this global connection. I haven't
advanced this project enough to say this with 100% certainty, but, I think
there's going to be more than one function like that and at some point I'll
need to have one inside the other so I need them to be composable. Let me
show you a naive example:

db/create-user is the low level database function that creates a record in
the user table
user/create is the function used to create a user, it takes care of, for
example, encrypting the password.
account/register is the function to register a new user, it takes care of
creating a user but also validation, sending a welcome email and so on.

So each function calls the predecessor there and would pass the database
connection, account/register, being the entry point, would grab it from the
global state so it doesn't get a connection passed to it. So far, a lot of
it looks like pure functions (let's ignore the fact that a database breaks
that purity). The problem arises when I get another function,
account/invite, that is used to register a bunch of people one after the
other, so that account/invite would call account/register many times. The
problem is that account/invite *can't* start a transaction and have
account/register and all its inner functions use that transaction when that
makes a lot of sense.

To make account/register composable it needs to accept an optional database
connection and use that one if it's present, or the global one if it's not.
Every time a function does that there's a high risk of picking the wrong
database and account/invite and account/register shouldn't be dealing with
database connection management. That feels to me like lower level details
leaked into higher level abstractions.

Now, I know this is a naive example and you could push the grabbing of the
global connection higher and higher, as long as the example is naive and
simple like this, but it does represent what in my experience is the
reality of web application development at least in another languages and I
haven't seen anything to make me think Clojure will be radically different
here (at least when using a patterns such as compojure).

So yes, it's not purely function but with a database that's already
impossible and if I wanted purely functional I would probably be using
Haskell instead of Clojure. What I like about Clojure is this:

Clojure is a practical language that recognizes the occasional need to
 maintain a persistent reference to a changing value and provides 4 distinct
 mechanisms for doing so in a controlled manner - Vars, Refs, Agents and
 Atoms.


I'm just trying to be practical here. But I'm new and I'm not sure if an
atom that is a dynamic var has some hidden issues that I'm not seeing
(other than the fact of it being state that changes and that I have to
manage explicitly because the language is not protecting me from shooting
myself in the foot with it).

Does it make sense?



On 31 July 2015 at 03:16, James Reeves ja...@booleanknot.com wrote:

 On 31 July 2015 at 01:44, J. Pablo Fernández pup...@pupeno.com wrote:

 I found passing around the database connection to each function that uses
 it very error prone when you are using transactions as passing the wrong
 one could mean a query runs outside the transaction when in the source code
 it is inside the with-db-transaction function. So I ended up defining the
 db namespace like this:

 (ns db)

 (defonce ^:dynamic conn (atom nil))

 (defn connect!
   (reset conn (generate-new-connection)))

 (defn run-query
   [query] (run-query query @conn)
   [query conn] (run-the-query-in-connection query conn))


 This style of code is generally considered to be unidiomatic in Clojure.
 The reason for this is that it significantly

Using a dynamic var for my database connection for implicit connections+transactions

2015-07-30 Thread J . Pablo Fernández
Hello Clojurians,

I found passing around the database connection to each function that uses 
it very error prone when you are using transactions as passing the wrong 
one could mean a query runs outside the transaction when in the source code 
it is inside the with-db-transaction function. So I ended up defining the 
db namespace like this:

(ns db)

(defonce ^:dynamic conn (atom nil))

(defn connect!
  (reset conn (generate-new-connection)))

(defn run-query 
  [query] (run-query query @conn)
  [query conn] (run-the-query-in-connection query conn))


This is pseudo-code of course, simplified to highlight the part that I'm 
most unfamiliar with:

(defonce ^:dynamic conn (atom nil))

The reason why it's an atom is so that connect! can *set* it and the reason 
why it's a dynamic var is so I can do this:

(jdbc/with-db-transaction
[db-connection-with-transaction @db/conn]
(binding [db/conn (atom db-connection-with-transaction)]
  (db/run-query SELECT *))

and the query will be implicitly run inside the transaction. Does it make 
sense? Is this wrong? will it fail in unexpected ways? Is there a better 
way?

Thanks.


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


Re: (flatten non-sequential) has a surprising result

2015-07-02 Thread J . Pablo Fernández
Yes, reading the source code and trying to understand why rest was being
called there is how I came up with this case.

On 2 July 2015 at 07:54, icamts ica...@gmail.com wrote:

 Hi Pablo,
 I think you're right. Have a look at flatten source

 (defn flatten
   Takes any nested combination of sequential things (lists, vectors,
   etc.) and returns their contents as a single, flat sequence.
   (flatten nil) returns an empty sequence.
   {:added 1.2
:static true}
   [x]
   (filter (complement sequential?)
   (rest (tree-seq sequential? seq x

 it is the rest function that causes this behavior and it seems to be just
 an optimization to avoid filtering the first element of tree-seq that is
 known to be the whole sequence. A simpler definition of flatten seems to
 have the behavior you expected.

 (defn flatten1 [x] (filter (complement sequential?) (tree-seq sequential?
 seq x)))




 Il giorno mercoledì 1 luglio 2015 13:55:28 UTC+2, J. Pablo Fernández ha
 scritto:

 Hello Clojurists,

 Today I was surprised by the result of (flatten 1) which is '(). I was
 expecting '(1) or an error. Talking in some other people in #clojure @
 clojurians.net, not everybody agrees that '(1) is a good result but that
 '() is somewhat surprising. Would it be better if it raised an error when
 the attribute is not sequential?

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




-- 
J. Pablo Fernández pup...@pupeno.com (http://pupeno.com)

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


(flatten non-sequential) has a surprising result

2015-07-01 Thread J . Pablo Fernández
Hello Clojurists,

Today I was surprised by the result of (flatten 1) which is '(). I was 
expecting '(1) or an error. Talking in some other people in #clojure @ 
clojurians.net, not everybody agrees that '(1) is a good result but that 
'() is somewhat surprising. Would it be better if it raised an error when 
the attribute is not sequential?

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


Re: (flatten non-sequential) has a surprising result

2015-07-01 Thread J . Pablo Fernández
I agree with you Mikera, it also maintains the homogeneity of always
returning a sequence but some people disagreed with it, so an error might
be better.

--
J. Pablo Fernández pup...@pupeno.com
http://pupeno.com
On Jul 1, 2015 4:22 PM, Mikera mike.r.anderson...@gmail.com wrote:

 On Wednesday, 1 July 2015 12:55:28 UTC+1, J. Pablo Fernández wrote:

 Hello Clojurists,

 Today I was surprised by the result of (flatten 1) which is '(). I was
 expecting '(1) or an error. Talking in some other people in #clojure @
 clojurians.net, not everybody agrees that '(1) is a good result but that
 '() is somewhat surprising. Would it be better if it raised an error when
 the attribute is not sequential?


 From an array programming / core.matrix perspective '(1) would be the most
 logical result.

 Consider the logical sequence:
 [[[1]]] = 3 dimensional array with elements '(1)
 [[1]] = 2 dimensional array with elements '(1)
 [1] =1 dimensional array with elements '(1)
 1 = 0 dimensional array (or scalar) with elements '(1)

 I am not saying that this is necessarily the best behaviour to follow for
 flatten, but it is an analogy worth considering.


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


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


Re: More functional Quil

2014-03-19 Thread J . Pablo Fernández
Hello Nikita,

I think Quil should definitely provide a way to write functional style 
processing code. At the moment, my knowledge of both Clojure and Processing 
is not enough to evaluate these solutions. I'm certainly going to write my 
code following some of this and if someone proposes a solution to be part 
of Quil 2, I would happily adopt it and report back on my experiences.

BTW, I noticed you had some discussions on IRC, you can find me there as 
Pupeno.

On Monday, March 10, 2014 12:29:00 AM UTC, Nikita Beloglazov wrote:

 Hi Pablo

 You can find similar old thread on Quil github repo: 
 https://github.com/quil/quil/pull/19 It may serve as good background what 
 other people considered to make Quil more functional-style.

 I like your suggestion though I would split your :draw function to 2 fns: 
 an :update function, which only purpose is to update state and :drawwhich 
 draws state and doesn't change the world at all. If this approach is 
 implemented - other handler functions like :mouse-move, :key-pressed are 
 also need to become update-like functions - they should take state as 
 argument and return new state.

 The only problem is that it is not backward compatible at all. But 
 probably we still can do it... We can add option :fun-mode? true (stands 
 for functional-mode) which enables all these changes - :draw takes state 
 as argument, new :update function is added for modifying state, all 
 handlers behave like :update. This option is enabled per-sketch. It 
 requires additional work on Quil internals, but I think it is doable. This 
 option can be implemented in coming quil 2.0 and it would be great feature 
 to have. 

 One more thing we could do to make it more functional-like - pass 
 changed values to handlers directly. Currently when :key-pressedhandler is 
 called - no argument is passed to the function and you need to 
 use (key-code) or (raw-key) functions to identify which key was pressed. 
 I think this parameters should be explicitly passed to the function.

 What do you think?

 Nikita

 On Sunday, March 9, 2014 1:21:58 PM UTC, J. Pablo Fernández wrote:



 On Sunday, March 9, 2014 1:02:52 PM UTC, Laurent PETIT wrote:

 Hello, 

 To be honest I don't see any fundamental difference between your first 
 attempt and the improvement: both share the fact that the mutation of the 
 state happens within the draw function. So in both cases, you have a 
 temporal coupling between updating the state of the app and rendering a new 
 view of the app's state.


 Yes, what's happening in both cases is very similar, but the function 
 draw in the functional style, in my opinion, is easier to read and maybe 
 it's also easier to test.
  

 I would suggest that you don't swap! at all within draw, just deref and 
 render the result of the dereffing.

 And, in another thread, at potentially a totally different pace than the 
 redrawing's pace, update the application's state accordingly to business 
 rules / constraints.

 Schematically, something like this: 

 (def app-state (atom (init-state)))

 (defn draw [...]
   (let [app-snapshot (deref app-state)]
   ... call quil primitives to render the application state snapshot 
 ...))

 (future
   ... logic which updates the app-state atom depending on business rules 
 / constraints, in a separate thread ...)


 I never worked with future, this is exciting, but I have some questions. 
 Do you mean that future is completely separate from draw? I'm just getting 
 started, but draw is not only a function to draw, but as a side effect is 
 the clock of the app, as it's called according to the set frames per second 
 and you normally *take a step* en each draw. Would draw create these 
 futures for the next draw?



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


More functional Quil

2014-03-09 Thread J . Pablo Fernández
Hello Clojurians,

I'm starting to play with Processing and I want to use my favorite 
programming language for it, so I started using 
Quilhttps://github.com/quil/quil. 
The problem is that Processing has a imperative architecture and makes my 
Clojure code look bad. For those that don't know Processing/Quil, here's a 
little overview that's relevant to this email.

Processing is a language and a library that makes it easy to draw on the 
screen to do generative art, simulations, etc. Processing programs have two 
methods, a setup method that is run once, at the beginning, and then a draw 
method that is run over and over. Literally something like:

Walker w;

void setup() {
  w = new Walker();
}

void draw() {
  w.render();
  w.walk();
}

I'm using a hypothetical walker, an entity that walks around the screen. 
More or less taken from here: http://natureofcode.com/book/introduction/

My understanding is that the equivalent Clojure code using Quil would look 
like this:

(defn setup []
  (set-state! :walker (atom (create-walker

(defn draw []
  (render-walker @(state :walker))
  (swap! (state :walker) walk))

Quil stores a map in the meta-data of the Processing applet and let's you 
access it. Since I need the state to change, I'm storing the walker in an 
atom. I found examples out there following more or less this structure. I'm 
not happy with this structure, it doesn't feel functional enough.

When thinking about this, I got reminded of Erlang processes, specially 
with OTP, where you have a function that's called over and over to which 
the state is passed and which returns the next state. Following that 
structure I would like to implement it like this:

(defn setup []
  [(create-walker)])

(defn draw [walker]
  (render-walker walker)
  [(walk walker)])

The result of calling setup is a vector containing the attributes to draw, 
and the result of draw is a vector containing the attributes that will be 
used in the next call to draw.

Does this make sense? Does it look cleaner to you guys?

I achieved that by writing this wrappers for setup and draw:

(defn setup-wrapper []
  (set-state! :state (atom (setup

(defn draw-wrapper []
  (swap! (state :state)
 (fn [s] (apply draw s

My concern with this is that now the whole state is in one single atom that 
I'm replacing on each frame and that might not be good. Is it copying the 
whole state or can Clojure use its copy-on-demand feature even for atoms? 
Is there a better way of doing this?

Thanks.

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


Re: More functional Quil

2014-03-09 Thread J . Pablo Fernández


On Sunday, March 9, 2014 1:02:52 PM UTC, Laurent PETIT wrote:

 Hello, 

 To be honest I don't see any fundamental difference between your first 
 attempt and the improvement: both share the fact that the mutation of the 
 state happens within the draw function. So in both cases, you have a 
 temporal coupling between updating the state of the app and rendering a new 
 view of the app's state.


Yes, what's happening in both cases is very similar, but the function draw 
in the functional style, in my opinion, is easier to read and maybe it's 
also easier to test.
 

 I would suggest that you don't swap! at all within draw, just deref and 
 render the result of the dereffing.

 And, in another thread, at potentially a totally different pace than the 
 redrawing's pace, update the application's state accordingly to business 
 rules / constraints.

 Schematically, something like this: 

 (def app-state (atom (init-state)))

 (defn draw [...]
   (let [app-snapshot (deref app-state)]
   ... call quil primitives to render the application state snapshot 
 ...))

 (future
   ... logic which updates the app-state atom depending on business rules / 
 constraints, in a separate thread ...)


I never worked with future, this is exciting, but I have some questions. Do 
you mean that future is completely separate from draw? I'm just getting 
started, but draw is not only a function to draw, but as a side effect is 
the clock of the app, as it's called according to the set frames per second 
and you normally *take a step* en each draw. Would draw create these 
futures for the next draw?

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


Is The Joy if Clojure up to date?

2013-11-30 Thread J . Pablo Fernández
Hello,

I have a copy of The Joy of Clojure that I bought a couple of years ago. Is 
it still a good way to learn Clojure or is it out of date?

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.


New Clojure Brush for Alex Gorbatchev's SyntaxHighlighter

2011-09-27 Thread J . Pablo Fernández
Hello,

I took Travis Whitton's brush for Clojure[1] for Alex Gorbatchev's 
SyntaxHighlighter[2] and put it in a git repo in GitHub, with an index file 
to easy development and trying it out. I also fixed some bugs and did some 
improvements. The new code is here:

https://github.com/pupeno/clojure_brush

Cheers!

[1] 
http://travis-whitton.blogspot.com/2009/06/syntaxhighlighter-for-clojure.html?showComment=1317124626851#c3205000945287389700

[2] http://alexgorbatchev.com/SyntaxHighlighter/

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

Re: REPL and Leiningen checkouts

2011-08-19 Thread J . Pablo Fernández
Thanks for the reply Chas. Does that mean that I have to create a Java 
project inside IntelliJ, instead of just opening the directory containing a 
Clojure/Lein project?

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

Errors in Clojure

2011-08-19 Thread J . Pablo Fernández
Hello Clojurians,

I'm struggling to work with errors in Clojure. This is one example, one 
case, but I had many like these before:

user= (load-file /Users/pupeno/Projects/mgr/src/lobos/migrations.clj)
org.postgresql.util.PSQLException: FATAL: role lobos does not exist 
(config.clj:1)

It just gives one line, no stack trace. config.clj looks like this:

(ns lobos.config)

(def db
  {:classname org.postgresql.Driver
   :subprotocol postgresql
   :subname //localhost:5432/mgr
   :user mgr
   :password chi1lie7Wai3ioP6aing3ooci})

What now? how do I start to unravel this? How would you do it?

Thanks.

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

Re: Errors in Clojure

2011-08-19 Thread J . Pablo Fernández
Petr, I do not care about this particular error, but about how to deal with 
this one liners. Ambrose's reply is what I needed, and no, it's not 
PostgreSQL problem. It's a library trying to establish a connection when it 
shouldn't with credentials that should never be used because I never 
specified them anywhere, so, I kinda need the stack trace to track down the 
problem.

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

REPL and Leiningen checkouts

2011-08-18 Thread J . Pablo Fernández
Hello,

I want to play around with a library I'm using so I started using the 
Leiningen checkouts feature and if I do lein repl it works. But when I'm 
running the REPL inside my editor I'm not running it through lein. Any ideas 
how to get my REPL to pick up checkouts like when I run it with lein?

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

Re: REPL and Leiningen checkouts

2011-08-18 Thread J . Pablo Fernández
I'm currently using La Clojure. Not sure if I can directly hook it to lein.

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

Uploaded Clinorm, an ORM-like system for Clojure

2008-11-28 Thread J. Pablo Fernández
CLinorm Is Not an ORM. Basically because it is not object oriented. It's
in its very very early stages of development. It's basically useless and
I'm developed on a need-to-function basis for another project I'm doing
which is not public yet. The reason to upload it is so that other people
can take a look and give me the feedback about the design and my code
(I'm not an expert Lisper) and in case anybody else needs such a system,
collaboration is welcome.

Clinorm comes with various parts. The two *external* ones are
com.kvardekdu.clinorm and com.kvardekdu.clinorm.sql. Let's start with
the first as it is the most important one. This package allows you to
define models like this: 

(clinorm/defmodel :users
  [[:username :string]
   [:age :integer]
   [:email :string]])

that generates a structure called users with three fields, username, age
and email and generates, for now, two functions (many, many more in the
future), create-table-users and drop-table-users. These functions have
very self-explanatory names. The table has all the fields defined there.
The plan is to also contain an auto-increment id, but it'll be stored as
meta-data in the structure objects. Many other functions will be
generated in the function, such as (get-users ...), (delete-users ...),
etc. I still don't know how relationships are going to be managed, but I
have an idea in my mind.

The second most important package, over which the previous one is built,
is com.kvardekdu.clinorm.sql which allows you to connect using JDBC and
a nice syntax like this:

(clinorm.sql/connect {
  :type :derby
  :file-name /tmp/blah.db
  :create true}))

Note: only derby supported at the moment, and not very extensively.
That returns the connection, but also the sql package manages
connections, maybe in a non-lispy way. There's a global default
connection (many, many programs only talk to one and only one database)
and also a map of named connections (some programs talk to a fixed set
of databases, like two, very distinctive, like one is derby, the other
is mysql, or one is production, the other is qa). But if that's not good
enough for you, just take the connection returned by connect and manage
it anyway you want. All SQL functions and methods should take an
optional connection parameter.

And it also allows you to run queries like this:

(clinorm.sql/create-table :users 
  [[:id :integer :auto-increment]
   [:username :string]
   [:age :intere]]))

and it should also allow to run things like

(clinorm.sql/select [:table1 :table2]
  [:where (= (user_id table1) (id table2))])

or similar; but only creating and dropping table is supported for now.
This is heavily inspired in CL-SQL. It should be a portable SQL-like
language that gets converted into various different SQLs in the back. So
far only Derby is supported and no preparations for others have been
made, the design is in-flux at the moment! Hey, this was only the work
of my little free time in a week. 

Yes, feel free to consider this whole thing vapor-ware, you'd probably
be right. Or you can help me build it ;) Note that I didn't say
released, I only uploaded it to:

http://github.com/pupeno/clinorm

Enjoy!
-- 
J. Pablo Fernández [EMAIL PROTECTED] http://pupeno.com


signature.asc
Description: This is a digitally signed message part


Compojure and Clojure 1094+

2008-11-16 Thread J . Pablo Fernández

Hello,

I've just forked Compojure and made it work with Clojure 1094+, the
change is here:

http://github.com/pupeno/compojure/commit/3cac756c89f63bbe009dcb6abbeb4646c252dee4

I haven't updated the clojure.jar and clojure-contrib.jar because I
don't believe Compojure should distribute those or any other jars at
all, so I'm moving my fork into the direction where it would be only a
library. Nevertheless, that patch can be pulled in to have Clojure
1094+ in any repo.

Enjoy!
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Concerned about Clojure's license choice.

2008-11-03 Thread J . Pablo Fernández

One thing that might be doable and acceptable is dual licensing. If
Clojure is realsed as CPL *and* GPL, it can be combined with GPL
programs and it is not in any way more free than the CPL (say, like if
you add BSD in the bag). In that way you can keep GPLists happy and
still use CPL.

On Nov 1, 6:33 pm, [EMAIL PROTECTED]
[EMAIL PROTECTED] wrote:
 Hello.  I am an open source programmer and fan of Clojure!
 I wanted to express my concern about your wonderful language project
 in the
 hopes it may help it succeed even more.

 Are you really sure you want/need to use the Common Public License for
 your
 language?  The biggest problem I see with this license is that it is
 not
 compatible with the GPL.  This means a lot to many people and I would
 hate to
 see you have to wasted time with discussing license issues when a new
 license
 would avoid all these problems.

 You may find this article informative

 http://www.dwheeler.com/essays/gpl-compatible.html

 Chris
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Concerned about Clojure's license choice.

2008-11-03 Thread J . Pablo Fernández

Hello,

On Nov 3, 7:54 pm, [EMAIL PROTECTED]
[EMAIL PROTECTED] wrote:
 On Nov 3, 5:35 am, J. Pablo Fernández [EMAIL PROTECTED] wrote:

  One thing that might be doable and acceptable is dual licensing. If
  Clojure is realsed as CPL *and* GPL, it can be combined with GPL
  programs and it is not in any way more free than the CPL (say, like if
  you add BSD in the bag). In that way you can keep GPLists happy and
  still use CPL.

 It doesn't even have to be dual-licensed with the GPL.  It just has to
 be dual licensed
 with a GPL *compatible* license.

True, it can be LGPL, BSD, etc. I proposed GPL because is the one that
leaves less freedom, thus changing as little as possible the current
situation.
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: offtopic - where are you come from? (poll)

2008-10-19 Thread J . Pablo Fernández

I think it might be more important where people are, where they live,
than where they come from. I live in Zürich, Switzerland.

On Oct 17, 11:27 am, Rastislav Kassak [EMAIL PROTECTED] wrote:
 Hello Clojurians,

 I think after 1st year of Clojure life it's good to check how far has
 Clojure spread all over the world.

 So wherever are you come from, be proud and say it.

 I'm from Slovakia. :)

 RK

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---