Re: Migrating from Java/Spring to Clojure

2016-01-31 Thread Mikera
On Monday, 1 February 2016 05:19:17 UTC+8, John Krasnay wrote:
>
> Hi all,
>
> I'm migrating an application from Java/Spring to Clojure and I'm searching 
> for a good, functional approach. The app exposes a REST interface using 
> compojure-api and primarily interacts with a relational database and sends 
> email.
>
> I think most people end up passing their database connection (and other 
> stateful resources as required) around to non-pure functions that do the 
> side-effectful work, while trying to push as much business logic into pure 
> functions possible. My problem with this approach is that most of my app's 
> functionality is in database interactions, so most of my functionality ends 
> up being non-pure and difficult to test. For example, to unit test my 
> functions it seems I'd have to mock my database connection.
>
> Instead of this, I'm considering an approach where my functions instead 
> return a data structure containing a description of the side-effects to be 
> performed (e.g. "insert these rows into this table", "send this email", 
> ...), and having a single non-pure function that does all the 
> side-effectful work described by the structure.
>
> From what I've read, it seems is sort of how Haskell does IO in a pure 
> functional manner, using their IO monad.
>
> Has anyone tried this sort of approach? Are there any libraries that might 
> help? Any pitfalls I might be setting myself up for?
>

I'm sure that you could get this approach to work, but it sets off some 
alarm bells in my head.

Problems you may face:

a) You are effectively developing a programming language, where your 
state-affecting code is represented in data. Clojure already does that 
why reinvent the wheel? I'm reminded of Grrenspun's tenth rule of 
programming: "Any sufficiently complicated C or Fortran program contains an 
ad hoc, informally-specified, bug-ridden, slow implementation of half of 
Common Lisp."

b) Representing operations in code seems neat, but it gets tricky when you 
have dependencies between them. What if one operation requires conditional 
execution that depends on the result of a previous operation? You'll need 
branching and control flow to handle this in a general way, which is 
non-trivial. What if one set of side effects writes to places that are 
subsequently "read" by later operations? You'll need to mock or model a 
database engine if you want to test / simulate this directly.

c) Clojure is an dynamically typed language (sadly, one of it's few 
flaws) . The lack of compiler support for type verification makes it 
harder to keep track of exactly the type of data passing through your 
deeply composed functions and data structures. Trying to represent graphs 
of operations as data as well is only likely to make things worse. Yes 
there are tools such as Schema, but they have their own cost in terms of 
runtime performance (if you use them for validation) and runtime 
complexity. It's possible to get right, but I would predict quite a lot of 
pain along the way.

I'd strongly suggest trying this the more conventional Clojure way first 
(e.g. using Stuart Sierra's component approach). This can get pretty close 
to being a nice functional style, and is very easy to test (you just need 
to mock one or two components and you are usually good). You may ultimately 
find some areas why you want to implement a DSL, but trying to write the 
whole application in this fashion from the beginning seems to me like a bit 
of a high risk strategy. 
 

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


Clojure compiler options

2016-01-31 Thread Alex Miller
I believe both of those guesses are correct - compiler options was added when 
the number increased and also the individual vars are easier to deal with 
individually.

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


Clojure compiler options

2016-01-31 Thread Reid McKenzie
One for those of you who've been around longer.

Is there a reason for *warn-on-reflection* etc rather than just adding
kvs to *compiler-options*?

My guess is that the former is more CL/traditional/just came first and
that the latter seems to have been added to support
-Dclojure.compiler.foo=bar but I thought I'd ask. There may also be an
argument here for relative ease of pushing/popping some options when you
have individual vars.

Thanks,

Reid

-- 
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: Migrating from Java/Spring to Clojure

2016-01-31 Thread Sean Corfield
John Krasnay wrote on Sunday, January 31, 2016 at 10:11 AM:
Instead of this, I'm considering an approach where my functions instead return 
a data structure containing a description of the side-effects to be performed 
(e.g. "insert these rows into this table", "send this email", ...), and having 
a single non-pure function that does all the side-effectful work described by 
the structure.

See https://github.com/seancorfield/engine which I built to investigate exactly 
that approach. We haven’t started using it at work (World Singles) but that is 
the plan so I’d be interested in getting more feedback on it. I have not yet 
released it to Clojars.

Sean



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


Re: [ANN] boot-new 0.3.1 -- Templates for Boot!

2016-01-31 Thread Sean Corfield
William la Forge wrote on Sunday, January 31, 2016 at 3:53 PM:
>Ah, but my understanding is that the hoplon template itself does not work. 
>Micha made a fix some time back to the handler wrapper order--it was backwards 
>in the template, but can not himself release it to clojars.

No idea. I don’t use Hoplon. Alan Dipert tried to use boot-new to generate a 
project from the Hoplon template and it failed (in boot-new). He reported that 
bug to me, I fixed it. Boot-new can now successfully generate projects from the 
Hoplon template. I did run the generated skeleton project and it worked. 
Whether more complex use cases work in the generated template, I can’t say.

Sean


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


Re: [ANN] boot-new 0.3.1 -- Templates for Boot!

2016-01-31 Thread William la Forge
 
levitanong  *[*11:30 AM*]* 
 yay I’m 
not crazy!
1 

*[*11:30*]* 
 
thanks, @micha , @laforge49 
  and @flyboarder 


micha  *[*11:30 AM*]* 
 :+1:
*[*11:30*]* 
 
i thought i fixed the lein template, no?

laforge49  *[*11:31 AM*]* 
 doesn't 
look like it.

micha  *[*11:31 AM*]* 
 i think i 
didn't have permission to push it to clojars
*[*11:31*]* 
 
but the git repo should be fixed



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


Re: [ANN] boot-new 0.3.1 -- Templates for Boot!

2016-01-31 Thread William la Forge
Heres the rest...


levitanong  *[*11:12 AM*]* 
 @flyboarder 
: Do you think I should file 
an issue somewhere, like the hoplon castra repo? After all, you seem to 
think the order shouldn’t matter much. Or perhaps I should tag micha or 
alan?

micha  *[*11:27 AM*]* 
 hello
*[*11:28*]* 
 
@levitanong : the order in 
which middleware are applied definitely matters

laforge49  *[*11:28 AM*]* 
 On advice 
from micha,, I have this which works:
 (-> app-routes
 (castra/wrap-castra
   'castra-notify-chat.chat-api
   'castra-notify-chat.user-api
   'notify.notification-api)
 (castra/wrap-castra-session "a 16-byte secret")
 (d/wrap-defaults d/api-defaults)))
So like @flyboarder  I have 
defaults on the bottom. And like @levitanong 
 's arrangement that works, I 
have wrap castra thingie on top.
The actual problem is that the template is backwards because -> reverses 
the order.

micha  *[*11:28 AM*]* 
 because 
it's a pipeline, each layer adding information for the subsequent layers to 
use
*[*11:29*]* 
 

```(-> foo bar baz) ; is the same as:
(baz (bar foo))
```

(edited)
*[*11:29*]* 
 
so the order definitely matters

laforge49  *[*11:30 AM*]* 
 So where 
do I file the issue? :simple_smile:

levitanong  *[*11:30 AM*]* 
 yay I’m 
not crazy!
1 

*[*11:30*]* 
 
thanks, @micha , @laforge49 
  and @flyboarder 
(edited)

micha  *[*11:30 AM*]* 
 :+1:
*[*11:30*]* 
 
i thought i fixed the lein template, no?

laforge49  *[*11:31 AM*]* 
 doesn't 
look like it.

micha  *[*11:31 AM*]* 
 i think i 
didn't have permission to push it to clojars
*[*11:31*]* 
 
but the git repo should be fixed

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


Re: [ANN] boot-new 0.3.1 -- Templates for Boot!

2016-01-31 Thread William la Forge
Ah, but my understanding is that the hoplon template itself does not work. 
Micha made a fix some time back to the handler wrapper order--it was 
backwards in the template, but can not himself release it to clojars.

>From the hoplon channel:
>
>

levitanong  *[*10:56 AM*]* 
 @laforge49 
, @flyboarder 
, I figured out what the 
problem was. It wasn’t with my code! (refresher: My problem is the thing 
with `*session*` not working as expected) Turns out the problematic bit was 
the handler, as generated by `lein new hoplon-castra`.

```(def app
  (-> app-routes
  (d/wrap-defaults d/api-defaults)
  (castra/wrap-castra-session "a 16-byte secret")
  (castra/wrap-castra 'thingy.api)))
```


If I rearrange it by moving the form up to the top like so:

```(def app
  (-> app-routes
  (castra/wrap-castra 'thingy.api)
  (d/wrap-defaults d/api-defaults)
  (castra/wrap-castra-session "a 16-byte secret")))
```


`*session*` suddenly works. Which is great, except I don’t exactly know why 
this is causing the screwup. Do you guys have any idea?(edited)

flyboarder  *[*10:58 AM*]* 
 Could be 
something else interacting with session, in the stack
*[*10:58*]* 
 
I have all my Castra forms up top and wrap defaults last

levitanong  *[*10:58 AM*]* 
 hmm
*[*10:58*]* 
 
thing is, when i apply that to the demos
*[*10:59*]* 
 
sessions stop working
*[*10:59*]* 
 
i mean, when i use the arrangement as in the hoplon castra template, the 
demo breaks
*[*10:59*]* 
 
specifically, castra-chat

flyboarder  *[*11:01 AM*]* 
 That may 
be something we need to fix in the template, I'm not sure who usually works 
on that but I'm sure they are open to a PR

levitanong  *[*11:12 AM*]* 
 @flyboarder 
: Do you think I should file 
an issue somewhere, like the hoplon castra repo? After all, you seem to 
think the order shouldn’t matter much. Or perhaps I should tag micha or 
alan?

micha  *[*11:27 AM*]* 
 hello
*[*11:28*]* 
 
@levitanong : the order in 
which middleware are applied definitely matters

laforge49  *[*11:28 AM*]* 
 On advice 
from micha,, I have this which works:
 (-> app-routes
 (castra/wrap-castra
   'castra-notify-chat.chat-api
   'castra-notify-chat.user-api
   'notify.notification-api)
 (castra/wrap-castra-session "a 16-byte secret")
 (d/wrap-defaults d/api-defaults)))
So like @flyboarder  I have 
defaults on the bottom. And like @levitanong 
 's arrangement that works, I 
have wrap castra thingie on top.
The actual problem is that the template is backwards because -> reverses 
the order.

micha  *[*11:28 AM*]* 
 because 
it's a pipeline, each layer adding information for the subsequent layers to 
use
*[*11:29*]* 
 

```(-> foo bar baz) ; is the same as:
(baz (bar foo))
```

(edited)
*[*11:29*]* 
 
so the order definitely matters

laforge49  *[*11:30 AM*]* 


Migrating from Java/Spring to Clojure

2016-01-31 Thread John Krasnay
Hi all,

I'm migrating an application from Java/Spring to Clojure and I'm searching 
for a good, functional approach. The app exposes a REST interface using 
compojure-api and primarily interacts with a relational database and sends 
email.

I think most people end up passing their database connection (and other 
stateful resources as required) around to non-pure functions that do the 
side-effectful work, while trying to push as much business logic into pure 
functions possible. My problem with this approach is that most of my app's 
functionality is in database interactions, so most of my functionality ends 
up being non-pure and difficult to test. For example, to unit test my 
functions it seems I'd have to mock my database connection.

Instead of this, I'm considering an approach where my functions instead 
return a data structure containing a description of the side-effects to be 
performed (e.g. "insert these rows into this table", "send this email", 
...), and having a single non-pure function that does all the 
side-effectful work described by the structure.

>From what I've read, it seems is sort of how Haskell does IO in a pure 
functional manner, using their IO monad.

Has anyone tried this sort of approach? Are there any libraries that might 
help? Any pitfalls I might be setting myself up for?

Thanks.

jk

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


Re: [ANN] fudje - unit testing library vaguely resembling midje, but with less 'calories'

2016-01-31 Thread Timothy Baldridge
It's also interesting to note that I most often write my clojure.test code
thusly:

(is (= (some-function some-val)
 42))

Which reads pretty much the same way, but without (many) macros.
Technically `is` is a deep walking macro, but that's more about error
reporting than DSLs.

Timothy

On Sun, Jan 31, 2016 at 9:05 AM, Brian Marick  wrote:

>
>
> Timothy Baldridge wrote:
>
>> This is a good example of a DSL, and it falls under the criticisms I
>> level at most DSLs, mainly they aren't Clojure. If we dive into
>>
>
> I note that Midje once had an intermediate “semi-sweet” functional
> interface that the `fact` macro expanded into. (It was most similar to
> Expectations’.) That’s because I was originally thinking the syntax was a
> little extreme and people would prefer something Lispy or to invent their
> own.
>
> At some point, the extra level of translation got annoying, so I asked on
> the mailing list if anyone objected to my deleting it. No one did.
>
> So there is some user demand for a DSL.
>
> And I think there’s probably a reason why /The Joy of Clojure/ and other
> books write examples in a left-right format like:
>
>  (if true :truthy :falsey);=> :truthy
>
> … rather than:
>
>  (is (= :truthy (if true :truthy :falsey)))
>
> I broadly agree with the idea of avoiding complex macros as DSLs. But
> testing - like textbooks - is a domain where understandability by someone
> new to an API is really important. So it’s a place where user experience
> might trump general principles.
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> --- You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



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

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


Re: In search of the little transducer

2016-01-31 Thread Mars0i
Thanks jjttjj, Magomimmo.  I do prefer reading to videos, but I'll consider 
getting Baldridge's series anyway.  Seems worth it.  I don't mind paying.

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


Re: [ANN] fudje - unit testing library vaguely resembling midje, but with less 'calories'

2016-01-31 Thread Brian Marick



Timothy Baldridge wrote:

This is a good example of a DSL, and it falls under the criticisms I
level at most DSLs, mainly they aren't Clojure. If we dive into


I note that Midje once had an intermediate “semi-sweet” functional 
interface that the `fact` macro expanded into. (It was most similar to 
Expectations’.) That’s because I was originally thinking the syntax was 
a little extreme and people would prefer something Lispy or to invent 
their own.


At some point, the extra level of translation got annoying, so I asked 
on the mailing list if anyone objected to my deleting it. No one did.


So there is some user demand for a DSL.

And I think there’s probably a reason why /The Joy of Clojure/ and other 
books write examples in a left-right format like:


 (if true :truthy :falsey);=> :truthy

… rather than:

 (is (= :truthy (if true :truthy :falsey)))

I broadly agree with the idea of avoiding complex macros as DSLs. But 
testing - like textbooks - is a domain where understandability by 
someone new to an API is really important. So it’s a place where user 
experience might trump general principles.


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