Re: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Jonah Benton
Hi Colin, no worries, responses below-

On Thu, Mar 5, 2015 at 2:31 PM, Colin Yates colin.ya...@gmail.com wrote:

 Hi Jonah,

 Coffee consumed, post read - thoughts emerging:

  - so the 'context' is essentially a service registry as well as
 run-time state?


More the latter- about transient, intermediate state rather than global
state like a registry.

A service registry could properly be a Component that depended on other
components, and then the registry could be delivered in the context map. I
usually include Components in the context map, though not the whole System
map. Flows are like functions, they should be called by Components, not
the other way around.



  - if 'renew-session' and 'return-renewed-token' both needed to
 execute in a single transaction that was separate to
 'some-thing-else', how would that be co-ordinated - would each tx
 boundary mandate a distinct flow for example


Right- generally since transaction boundaries are an edge semantic,
transaction scope should ideally be confined to a single top level edge
function, and data needed for the transaction should be prepared
beforehand- perhaps including generating primary key values separately. If
the transaction is complex and requires in-scope processing, perhaps it
should live inside the database. In theory an isolated flow could be used
*inside* transaction scope, but any complex logic occurring inside
transaction scope is a smell that perhaps transaction scope could be
rethought.


  - the whole thing feels very 'state-machiney' - is that the point?


I would say data-driven.


 Thanks again for sharing. I have to say that the 'flattening' of the
 control, or rather conditional logic seems quite expensive. My mind
 thinks in graphs not flattened lists, but maybe my resistance is just
 the pain of a new paradigm...

 At the moment I am slightly nervous as it seems to be conflating a
 whole bunch for the win of a consistent way of moving state around.


In a way- it's just another view of an execution chain.

We get the stack-based model for free, where functions call into
functions, into other functions, etc, then are popped back out when they're
done, and conditional logic is typically embedded inside functions. When
those functions need data, it's supposed to be available in the class, or
less often, arrive on the stack, or they have to reach out onto the heap-
into global space shared by all threads. Conditional decisions aren't first
class entities- an if doesn't give you a new stack frame. etc. There are
good things about that model for certain kinds of solutions. Clojure begins
to decouple it by, e.g. by not hiding data inside classes.

A data flow model has different priorities and different costs and
benefits, and though it is less native to the JVM one can imagine a data
flow compiler that makes it a little friendlier.



 Thanks for the time to respond and these questions are those of
 clarity not criticism :).


Of course!



 On 5 March 2015 at 16:45, Jonah Benton jo...@jonah.com wrote:
  Hi Colin- a simple example that uses a flow operator would be
 
  (- context
do-something
do-some-io
do-a-last-thing )
 
  with
 
  (defn do-something [context]
(let [some-data (get-in context [:path :to :data :element])
   result (pure-edge-function some-data)]
  (assoc-in context [:path :to :revised :data] result)))
 
  and
 
  (defn do-some-io [context]
(let [some-other-data (get-in context [:path :to :data :to :save])
   database (get-in context [:path :to :database :resource])]
  (save! database some-other-data)
   context)))
 
  Then save! can be a plain function, or
 
  (defprotocol Saver
(save! [this data]))
 
  (defrecord DatabaseSaver [conn ... ]
Saver
(save!  ))
 
  (defrecord AtomSaver [a ... ]
Saver
(save! ))
 
  And context is a map of maps that contains both application state and
 edge
  resources that should provide or receive data.
 
  Encoding conditional steps in a data flow presents a challenge. Several
  variants for doing this are in flow operators in Clojure and there are
 also
  a number of third party approaches. The below is a concrete example from
 an
  internal library that is not open source but doesn't differ significantly
  from approaches that are.
 
  A flow looks like this:
 
  (defflow renew
  { :startvalid-request?
   valid-request?{ true valid-token? false invalid-request }
   valid-token?  { true ingest-token false not-authorized }
   ingest-token  renew-session
   renew-session renewed?
   renewed?  { true return-renewed-token false
 not-authorized
  }
   return-renewed-token   :end
   not-authorized :end
   invalid-request:end })
 
  It's a regular map with at least a :start key and an :end value. Symbols
 in
  a flow map are plain functions that take a context map.
 
  Semantically, those functions represent either 

[ANN] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread Jozef Wagner
I'm happy to announce a project called Dunaj [1], which provides an
alternative core API for Clojure. Its main aim is to experimentally test
major additions to the language.

Dunaj /ˈdunaɪ/ is a set of core language experiments aimed to improve
Clojure language and its core API. It deals with language features that
require changes across different parts of Clojure and which cannot be
evaluated in isolation. Dunaj aims to bring Clojure even more towards
simplicity, consistency and performance.
It is intended to be used by regular Clojure developers, either for
application or library development.

Dunaj was created to test 10 experiments that bring significant changes to
the Clojure language. As there is a substantial number of additions and
changes, I want to try a bit unconventional approach here. Before I'll
release the actual library, I will introduce Dunaj's experiments in a
series of individual posts. Every part states the motivation behind the
experiment, introduces changes and additions to the language and
demonstrates its intended use. If you do not want to miss any of this, you
may want to register for a mailing list at [1] or follow @dunajproject at
Twitter.

-- Jozef Wagner

[1] http://www.dunaj.org/

-- 
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: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Colin Yates
Hi Jonah,

Coffee consumed, post read - thoughts emerging:

 - so the 'context' is essentially a service registry as well as
run-time state?
 - if 'renew-session' and 'return-renewed-token' both needed to
execute in a single transaction that was separate to
'some-thing-else', how would that be co-ordinated - would each tx
boundary mandate a distinct flow for example
 - the whole thing feels very 'state-machiney' - is that the point?

Thanks again for sharing. I have to say that the 'flattening' of the
control, or rather conditional logic seems quite expensive. My mind
thinks in graphs not flattened lists, but maybe my resistance is just
the pain of a new paradigm...

At the moment I am slightly nervous as it seems to be conflating a
whole bunch for the win of a consistent way of moving state around.

Thanks for the time to respond and these questions are those of
clarity not criticism :).


On 5 March 2015 at 16:45, Jonah Benton jo...@jonah.com wrote:
 Hi Colin- a simple example that uses a flow operator would be

 (- context
   do-something
   do-some-io
   do-a-last-thing )

 with

 (defn do-something [context]
   (let [some-data (get-in context [:path :to :data :element])
  result (pure-edge-function some-data)]
 (assoc-in context [:path :to :revised :data] result)))

 and

 (defn do-some-io [context]
   (let [some-other-data (get-in context [:path :to :data :to :save])
  database (get-in context [:path :to :database :resource])]
 (save! database some-other-data)
  context)))

 Then save! can be a plain function, or

 (defprotocol Saver
   (save! [this data]))

 (defrecord DatabaseSaver [conn ... ]
   Saver
   (save!  ))

 (defrecord AtomSaver [a ... ]
   Saver
   (save! ))

 And context is a map of maps that contains both application state and edge
 resources that should provide or receive data.

 Encoding conditional steps in a data flow presents a challenge. Several
 variants for doing this are in flow operators in Clojure and there are also
 a number of third party approaches. The below is a concrete example from an
 internal library that is not open source but doesn't differ significantly
 from approaches that are.

 A flow looks like this:

 (defflow renew
 { :startvalid-request?
  valid-request?{ true valid-token? false invalid-request }
  valid-token?  { true ingest-token false not-authorized }
  ingest-token  renew-session
  renew-session renewed?
  renewed?  { true return-renewed-token false not-authorized
 }
  return-renewed-token   :end
  not-authorized :end
  invalid-request:end })

 It's a regular map with at least a :start key and an :end value. Symbols in
 a flow map are plain functions that take a context map.

 Semantically, those functions represent either actions or decisions. A
 function whose value in the flow map is itself a map with true and false
 keys is a decision. A function whose value in the map is another function is
 an action.

 This particular flow performs a renewal of a web-like session token. It
 runs in a Pedestal interceptor, so it receives a context map (with :request,
 :response and other keys) as a parameter and at the end it populates the
 :response key of the map.

 The way to read this is-

 0. a context map is prepared.
 1. the data flow runner looks for the :start key. the value of :start is
 valid-request?
 2. The value of valid-request? is a map, rather than a function, so the flow
 determines valid-request? is a decision function- an ordinary function that
 takes a context and is expected to return true or false.
 3. the flow runner executes valid-request? If it returns true, the flow
 runner proceeds to valid-token? using the same context map. If false,
 proceed to invalid-request
 4. valid-token? is similarly a decision function, it's executed similarly
 and is also expected to return true or false. invalid-request is an action.
 It's expected to return a new context map- in this case it populates the
 :response with a 4xx :status and some other response attributes.
 5. the flow engine keeps going between keys and values until it comes to a
 value of :end. Then the resulting context is the output of the flow.

 The action function in the above called renew-session can do IO to renew a
 user session in the database. It's copied below.

 (defn renew-session [context]
   (let [database(get-in context [:components :database])
 session-key (get-in context [:work :session-key])
 renewed?(db/renew-session! database session-key)]
 (if (not (nil? renewed?))
   (assoc-in context [:work :renewed-key] session-key)
   context)))

 It simply pulls the database connection from the context, calls into a db
 specific function, db/renew-session!, which takes a connection and a key,
 and could be a protocol function that accepts a Record that encapsulates a
 specific storage resource, or could be 

Re: [ANN] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread Michael Klishin
On 6 March 2015 at 00:45:47, adrian.med...@mail.yu.edu 
(adrian.med...@mail.yu.edu) wrote:
 it strikes me as odd that this project would not come out of  
 direct collaboration with Clojure's core contributors.

I should point out that there's enough people in the community who
do not find Clojure's core contributors, ahem,
exactly open to collaborating
 on stuff not seen as exciting or important in their circle.

 Proposed  
 features should probably go through the official channels if  
 you are serious about getting them included in the language.  

Attempts to introduce major changes to clojure.core have incredibly low
chances to succeed for reasons that are outside of control of Dunai's author.

A completely new 3rd party project has the same low changes of being
*widely* adopted but may influence clojure.core in some areas in the long run
and be useful to some today. Or the day it stops being vaporware with a mailing
list and no source code publicly available.
--  
@michaelklishin, github.com/michaelklishin

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


Re: [ANN] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread adrian . medina
Not sure exactly how to properly express my impression here, but it strikes 
me as odd that this project would not come out of direct collaboration with 
Clojure's core contributors. Proposed features should probably go through 
the official channels if you are serious about getting them included in the 
language. 

On Thursday, March 5, 2015 at 4:33:53 PM UTC-5, Jozef Wagner wrote:

 I'm happy to announce a project called Dunaj [1], which provides an 
 alternative core API for Clojure. Its main aim is to experimentally test 
 major additions to the language. 

 Dunaj /ˈdunaɪ/ is a set of core language experiments aimed to improve 
 Clojure language and its core API. It deals with language features that 
 require changes across different parts of Clojure and which cannot be 
 evaluated in isolation. Dunaj aims to bring Clojure even more towards 
 simplicity, consistency and performance. 
 It is intended to be used by regular Clojure developers, either for 
 application or library development.

 Dunaj was created to test 10 experiments that bring significant changes to 
 the Clojure language. As there is a substantial number of additions and 
 changes, I want to try a bit unconventional approach here. Before I'll 
 release the actual library, I will introduce Dunaj's experiments in a 
 series of individual posts. Every part states the motivation behind the 
 experiment, introduces changes and additions to the language and 
 demonstrates its intended use. If you do not want to miss any of this, you 
 may want to register for a mailing list at [1] or follow @dunajproject at 
 Twitter.

 -- Jozef Wagner

 [1] http://www.dunaj.org/ 



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


Re: How to persist a value while doing do-seq

2015-03-05 Thread Sébastien Bocq


Le mercredi 4 mars 2015 22:08:13 UTC+1, Fluid Dynamics a écrit :

 For examining adjacent items in a sequence, there are a few functional 
 (i.e., no mutable state) approaches.

 When the output is a sequence with an element for each adjacent pair:

 (map (fn [a b] ...) s (next s))

 When the output is a sequence with an element for each adjacent pair that 
 meets some criterion:

 (remove #{::removeme}
   (map
 (fn [a b]
   (if (criterion a b)
 (foo a b)
 ::removeme))
s (next s)))

 OR

 (for [[a b] (map vector s (next s))
   :when (criterion a b)]
   foo a b) 

snip/


The are interesting examples.

For the use case above, I use the following instead of 'for' to avoid the 
extra baggage that comes with it*:

(mapcat (fn [a b]
   (when (criterion a b) [(foo a b)]))
 s (next s))

But if the goal of the OP is to delete all consecutive duplicates in a 
sequence then neither of these are very helpful. Instead, he could do:

user (let [s [1 1 2 2 2 1 1 3 3 3 3 4 5]]
(map first (partition-by identity s)))
;; = (1 2 1 3 4 5)


* For those who wonder what goes under the hood when you use 'for', just 
try this:

user (macroexpand-1 '(for [[a b] (map vector s (next s))
 :when (criterion a b)]
 (foo a b)))

But beware that you might never see 'for' the same way after that :)

-- 
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 map to java instance of pojo class

2015-03-05 Thread Daniel
bean?

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


[ANN] Indigenous, a native library helper

2015-03-05 Thread Philippe Guillebert
Hello

Working with native libraries on the JVM has always been difficult because
you need to deploy dynamic libraries alongside your JAR and tweak the
dreaded java.library.path.

When I was looking for a better solution I discovered a nice hack in
gaverhae/naughtmq, by Gary Verhaegen : keep the native lib in the jar and
load it when we need it. It solves the issue for ZeroMQ but I needed a more
generic solution to the problem. With Gary's approval I kept the heart of
the lib and I'm publishing it hoping it may be useful. As an example, I use
it to load Sigar native deps.

The name's Indigenous and the project is here :
https://github.com/pguillebert/indigenous

Let me know if you find this useful


-- 
Philippe

-- 
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] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread Ben Wolfson
Why? One of the purposes of PyPy, for instance, was to make it easier to
experiment with new features in possible Python interpreters, and that's a
separate project not undertaken in direct collaboration with CPython's
authors.

On Thu, Mar 5, 2015 at 1:45 PM, adrian.med...@mail.yu.edu wrote:

 Not sure exactly how to properly express my impression here, but it
 strikes me as odd that this project would not come out of direct
 collaboration with Clojure's core contributors. Proposed features should
 probably go through the official channels if you are serious about getting
 them included in the language.


 On Thursday, March 5, 2015 at 4:33:53 PM UTC-5, Jozef Wagner wrote:

 I'm happy to announce a project called Dunaj [1], which provides an
 alternative core API for Clojure. Its main aim is to experimentally test
 major additions to the language.

 Dunaj /ˈdunaɪ/ is a set of core language experiments aimed to improve
 Clojure language and its core API. It deals with language features that
 require changes across different parts of Clojure and which cannot be
 evaluated in isolation. Dunaj aims to bring Clojure even more towards
 simplicity, consistency and performance.
 It is intended to be used by regular Clojure developers, either for
 application or library development.

 Dunaj was created to test 10 experiments that bring significant changes
 to the Clojure language. As there is a substantial number of additions and
 changes, I want to try a bit unconventional approach here. Before I'll
 release the actual library, I will introduce Dunaj's experiments in a
 series of individual posts. Every part states the motivation behind the
 experiment, introduces changes and additions to the language and
 demonstrates its intended use. If you do not want to miss any of this, you
 may want to register for a mailing list at [1] or follow @dunajproject at
 Twitter.

 -- Jozef Wagner

 [1] http://www.dunaj.org/

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




-- 
Ben Wolfson
Human kind has used its intelligence to vary the flavour of drinks, which
may be sweet, aromatic, fermented or spirit-based. ... Family and social
life also offer numerous other occasions to consume drinks for pleasure.
[Larousse, Drink entry]

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


Re: [ANN] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread Alex Baranosky
Yeah, I'm excited to see some of the 10 write-ups. What's the ETA on the
first one?

On Thu, Mar 5, 2015 at 6:02 PM, Alex Miller a...@puredanger.com wrote:

 I'm happy to see experiments if we can learn something useful. Can't
 really judge more till the posts are out. Seems perfectly possible that
 something promising could get a design page and move towards inclusion in
 some way.

 Alex

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


-- 
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] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread Ivan L
Just a quick glance at the example project shows integrated type 
definitions.  I'm curious for sure.

-- 
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] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread Alex Baranosky
Where is this example project?

On Thu, Mar 5, 2015 at 7:40 PM, Ivan L ivan.laza...@gmail.com wrote:

 Just a quick glance at the example project shows integrated type
 definitions.  I'm curious for sure.

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


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


Re: [ANN] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread Alex Miller
I'm happy to see experiments if we can learn something useful. Can't really 
judge more till the posts are out. Seems perfectly possible that something 
promising could get a design page and move towards inclusion in some way.

Alex

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


Re: clojure map to java instance of pojo class

2015-03-05 Thread Jeremy Heiler
On Thu, Mar 5, 2015 at 2:42 AM, Xiangtao Zhou tao...@gmail.com wrote:

 hi all,

 is there some library or simple way to do it like the function
 map-to-pojo in the following code ?

 java code
 class A{
   public int a;
   public String b;
 }

 clojure code
 (def a {:a 1 :b 2})
 (def b (map-to-pojo a A))
 (instance? b A)



You'll want to use clojure.java.data: https://github.com/clojure/java.data/

Assuming class A with an integer field, with an appropriate getter and
setter.

user (require '[clojure.java.data :as d])
nil
user (d/to-java A {:x 1})
#A foo.A@6b91ca5c
user (.getX *1)
1

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


GSOC 2015 — tools.reader.cljs

2015-03-05 Thread Matthew West
Hello everyone,

I am an undergraduate student looking to participate in the GSOC this 
summer. I've been looking through the project ideas 
http://dev.clojure.org/display/community/Project+Ideas on the Clojure 
Development site, and the one that looks most interesting to me is 
implementing tools.reader in cljs. That webpage suggests contacting David 
Nolen and/or Nicola Mometto as mentors, but I'm not sure how to contact 
either of them. Does anyone know how I could contact either of those two?

-- 
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: Who's using Clojure?

2015-03-05 Thread Alan Moore
The question of using may have different meanings depending on your 
definition - if you include using libraries or frameworks built with 
Clojure (partly or in whole) you could include all the companies who 
deploy, for example, Apache Storm or use some of Puppet Labs' tools.

The consultancy ThoughtWorks has put Clojure on their radar - several 
Clojure and ClojureScript libraries are also listed (Core Async, Om, 
Reagent.) I can't vouch for the consultancy itself but I think it is 
telling that Clojure has a number of technologies listed there.

Given the fact that, as a hosted language, Clojure is very different than 
say, Go or Erlang, where the language ecosystem (runtimes, libraries, etc.) 
is entirely dependent on the language's popularity in order for it to 
expand into new environments and remain viable. Given that Java (and the 
JVM), CLR, and Javascript effectively boost Clojure into new contexts for 
(mostly) free it can play nice along with existing languages and their 
momentum. See also: React Native.

Additionally, consider that ClojureScript and Om have strongly influenced 
the React community w.r.t. immutability, I'd say that counts as a big win 
for Clojure.

IMHO, job boards are effectively looking backwards in time. It isn't the 
place to look if you are trying new things or being innovative. Sure, if 
you want to hire some easily replaceable tool go for Java... what could 
possibly go wrong? :-)

Alan


On Thursday, March 5, 2015 at 7:47:41 AM UTC-8, Michael Richards wrote:

 I'm about to start training 4 devs on my team at Oracle in Clojure.  My 
 manager is very nervous about putting Clojure into the product.  I'm 
 forging on regardless :)  I rewrote some components of our product in 
 Clojure in my spare time, mainly as a proof of concept that we could do 
 some of our analytics in the streaming model rather than in the data 
 warehousing model.  As sometimes happens, the POC was so simple and fast 
 that the team is now interested in productizing it.

 In our last 1-1 meeting, my manager told me he had searched LinkedIn for 
 Clojure and only got 9000 matches.   Whereas his search for Java turned 
 up 80 million or some such.  My rebuttal is that those are the 9000 
 smartest developers, so you should be trying to recruit them.


 --mike




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


Re: How to persist a value while doing do-seq

2015-03-05 Thread Alex Miller
For the particular use case of removing duplicates there is a new dedupe in 
Clojure 1.7:

http://crossclj.info/fun/clojure.core/dedupe.html

Alex

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


Re: GSOC 2015 — tools.reader.cljs

2015-03-05 Thread Andy Fingerhut
The email they use to correspond on this group are:

David - dnolen.li...@gmail.com
Nicola - brobro...@gmail.com

Daniel (GSoC organizer for Clojure), would there be any objection to
including email addresses of mentors on the Clojure GSOC 2015 projects
page?  The question of what to do if someone is interested in a project has
come up multiple times recently.

Andy


On Thu, Mar 5, 2015 at 5:17 PM, Matthew West matthewwest...@gmail.com
wrote:

 Hello everyone,

 I am an undergraduate student looking to participate in the GSOC this
 summer. I've been looking through the project ideas
 http://dev.clojure.org/display/community/Project+Ideas on the Clojure
 Development site, and the one that looks most interesting to me is
 implementing tools.reader in cljs. That webpage suggests contacting David
 Nolen and/or Nicola Mometto as mentors, but I'm not sure how to contact
 either of them. Does anyone know how I could contact either of those two?

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


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


Re: How to model a rectangle?

2015-03-05 Thread Felix E. Klee
Looks interesting, thanks!

On Thu, Mar 5, 2015 at 4:43 PM, Leon Grapenthin
grapenthinl...@gmail.com wrote:
 (defn rect2 [x y width height]
   (let [lr  [(+ width x) (+ width y)]]
 (reify Rect
   (upper-left [_] [x y])
   (lower-right [_] lr)
   (area [_] (* width height)

Just a quick remark: In JavaScript I purposefully did not use `width`
and `height` for calculating area. That way the garbage collector can
release them, making objects smaller.

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


How to model a rectangle?

2015-03-05 Thread Felix E. Klee
Disclaimer: I’ve never done *any* Clojure programming, but I’m curious.

Here’s how I may model an on-screen rectangle in JavaScript, a classless
object oriented language:

let createRectangle = function (x, y, width, height) {
return {
get upperLeft() {
return [x, y];
},
get lowerRight() {
return [x + width, y + height];
},
get area() {
return width * height;
}
};
};

let r = createRectangle(0, 0, 50, 20);
let s = createRectangle(10, 20, 40, 5);
console.log(r.upperLeft, r.lowerRight, r.area);
console.log(s.upperLeft, s.lowerRight, s.area);

Now I run the profiler. I discover that in the inner loop of my program
there are lots of calls needing the upper left and the lower right
coordinates. So I change the inner workings of the object to store these
instead:

let createRectangle = function (x, y, width, height) {
let upperLeft = [x, y], lowerRight = [x + width, y + height];

return {
get upperLeft() {
return upperLeft;
},
get lowerRight() {
return lowerRight;
},
get area() {
return (lowerRight[0] - upperLeft[0]) *
(lowerRight[1] - upperLeft[1]);
}
};
};

Boom: Now the program is twice as fast, and - what gives me great
comfort - I know that this change breaks nothing. I only had to edit the
code in *one* module. I didn’t need to think too much about efficiency
of data structures in the beginning. I could just start going, then
optimize in the end.

*Can I program in a similar way using Clojure?*

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


Re: How to model a rectangle?

2015-03-05 Thread Leon Grapenthin
You could use Clojure protocols.

(defprotocol Rect
  (upper-left [this])
  (lower-right [this])
  (area [this]))

(defn rect1 [x y width height]
  (reify Rect
(upper-left [_] [x y])
(lower-right [_] [ (+ width x) (+ width y)])
(area [_] (* width height

(defn rect2 [x y width height]
  (let [lr  [(+ width x) (+ width y)]]
(reify Rect
  (upper-left [_] [x y])
  (lower-right [_] lr)
  (area [_] (* width height)



On Thursday, March 5, 2015 at 4:48:11 PM UTC+1, Felix E. Klee wrote:

 Disclaimer: I’ve never done *any* Clojure programming, but I’m curious. 

 Here’s how I may model an on-screen rectangle in JavaScript, a classless 
 object oriented language: 

 let createRectangle = function (x, y, width, height) { 
 return { 
 get upperLeft() { 
 return [x, y]; 
 }, 
 get lowerRight() { 
 return [x + width, y + height]; 
 }, 
 get area() { 
 return width * height; 
 } 
 }; 
 }; 

 let r = createRectangle(0, 0, 50, 20); 
 let s = createRectangle(10, 20, 40, 5); 
 console.log(r.upperLeft, r.lowerRight, r.area); 
 console.log(s.upperLeft, s.lowerRight, s.area); 

 Now I run the profiler. I discover that in the inner loop of my program 
 there are lots of calls needing the upper left and the lower right 
 coordinates. So I change the inner workings of the object to store these 
 instead: 

 let createRectangle = function (x, y, width, height) { 
 let upperLeft = [x, y], lowerRight = [x + width, y + height]; 

 return { 
 get upperLeft() { 
 return upperLeft; 
 }, 
 get lowerRight() { 
 return lowerRight; 
 }, 
 get area() { 
 return (lowerRight[0] - upperLeft[0]) * 
 (lowerRight[1] - upperLeft[1]); 
 } 
 }; 
 }; 

 Boom: Now the program is twice as fast, and - what gives me great 
 comfort - I know that this change breaks nothing. I only had to edit the 
 code in *one* module. I didn’t need to think too much about efficiency 
 of data structures in the beginning. I could just start going, then 
 optimize in the end. 

 *Can I program in a similar way using Clojure?* 


-- 
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: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Jonah Benton
Hi Colin- a simple example that uses a flow operator would be

(- context
  do-something
  do-some-io
  do-a-last-thing )

with

(defn do-something [context]
  (let [some-data (get-in context [:path :to :data :element])
 result (pure-edge-function some-data)]
(assoc-in context [:path :to :revised :data] result)))

and

(defn do-some-io [context]
  (let [some-other-data (get-in context [:path :to :data :to :save])
 database (get-in context [:path :to :database :resource])]
(save! database some-other-data)
 context)))

Then save! can be a plain function, or

(defprotocol Saver
  (save! [this data]))

(defrecord DatabaseSaver [conn ... ]
  Saver
  (save!  ))

(defrecord AtomSaver [a ... ]
  Saver
  (save! ))

And context is a map of maps that contains both application state and edge
resources that should provide or receive data.

Encoding conditional steps in a data flow presents a challenge. Several
variants for doing this are in flow operators in Clojure and there are also
a number of third party approaches. The below is a concrete example from an
internal library that is not open source but doesn't differ significantly
from approaches that are.

A flow looks like this:

(defflow renew
{ :startvalid-request?
 valid-request?{ true valid-token? false invalid-request }
 valid-token?  { true ingest-token false not-authorized }
 ingest-token  renew-session
 renew-session renewed?
 renewed?  { true return-renewed-token false not-authorized
}
 return-renewed-token   :end
 not-authorized :end
 invalid-request:end })

It's a regular map with at least a :start key and an :end value. Symbols in
a flow map are plain functions that take a context map.

Semantically, those functions represent either actions or decisions. A
function whose value in the flow map is itself a map with true and false
keys is a decision. A function whose value in the map is another function
is an action.

This particular flow performs a renewal of a web-like session token. It
runs in a Pedestal interceptor, so it receives a context map (with
:request, :response and other keys) as a parameter and at the end it
populates the :response key of the map.

The way to read this is-

0. a context map is prepared.
1. the data flow runner looks for the :start key. the value of :start is
valid-request?
2. The value of valid-request? is a map, rather than a function, so the
flow determines valid-request? is a decision function- an ordinary function
that takes a context and is expected to return true or false.
3. the flow runner executes valid-request? If it returns true, the flow
runner proceeds to valid-token? using the same context map. If false,
proceed to invalid-request
4. valid-token? is similarly a decision function, it's executed similarly
and is also expected to return true or false. invalid-request is an action.
It's expected to return a new context map- in this case it populates the
:response with a 4xx :status and some other response attributes.
5. the flow engine keeps going between keys and values until it comes to a
value of :end. Then the resulting context is the output of the flow.

The action function in the above called renew-session can do IO to renew
a user session in the database. It's copied below.

(defn renew-session [context]
  (let [database(get-in context [:components :database])
session-key (get-in context [:work :session-key])
renewed?(db/renew-session! database session-key)]
(if (not (nil? renewed?))
  (assoc-in context [:work :renewed-key] session-key)
  context)))

It simply pulls the database connection from the context, calls into a db
specific function, db/renew-session!, which takes a connection and a key,
and could be a protocol function that accepts a Record that encapsulates a
specific storage resource, or could be a multimethod.

This model of a data flow with actions and decisions follows Amazon's
Simple Workflow Service, and the clever encoding of that flow as a map is
due to Cognitect.

A few projects exist now that encode flows in data form with an engine to
process them. There are some trade-offs- it takes practice to read them,
you can trade off a little in performance. In the above there's a fair
amount of boilerplate that could be abstracted away along the lines of of
Prismatic's Graph.

You get a lot of other benefits- a consistent system shape, separation of
concerns between core logic and edge IO, consistent error handling,
logging/auditing, etc. Flows can be reused and can themselves compose,
because everything takes a context map. You could also generate a visual
decision tree of the model, or a real time heat map of decisions or of
action performance.

Anyway- sorry, this isn't intended to pitch an internal library, rather to
share another thought process around the problems you raised that points in
the direction of modeling and 

Re: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Colin Yates
Thanks Jonah - I will digest this over coffee...

On 5 March 2015 at 16:45, Jonah Benton jo...@jonah.com wrote:
 Hi Colin- a simple example that uses a flow operator would be

 (- context
   do-something
   do-some-io
   do-a-last-thing )

 with

 (defn do-something [context]
   (let [some-data (get-in context [:path :to :data :element])
  result (pure-edge-function some-data)]
 (assoc-in context [:path :to :revised :data] result)))

 and

 (defn do-some-io [context]
   (let [some-other-data (get-in context [:path :to :data :to :save])
  database (get-in context [:path :to :database :resource])]
 (save! database some-other-data)
  context)))

 Then save! can be a plain function, or

 (defprotocol Saver
   (save! [this data]))

 (defrecord DatabaseSaver [conn ... ]
   Saver
   (save!  ))

 (defrecord AtomSaver [a ... ]
   Saver
   (save! ))

 And context is a map of maps that contains both application state and edge
 resources that should provide or receive data.

 Encoding conditional steps in a data flow presents a challenge. Several
 variants for doing this are in flow operators in Clojure and there are also
 a number of third party approaches. The below is a concrete example from an
 internal library that is not open source but doesn't differ significantly
 from approaches that are.

 A flow looks like this:

 (defflow renew
 { :startvalid-request?
  valid-request?{ true valid-token? false invalid-request }
  valid-token?  { true ingest-token false not-authorized }
  ingest-token  renew-session
  renew-session renewed?
  renewed?  { true return-renewed-token false not-authorized
 }
  return-renewed-token   :end
  not-authorized :end
  invalid-request:end })

 It's a regular map with at least a :start key and an :end value. Symbols in
 a flow map are plain functions that take a context map.

 Semantically, those functions represent either actions or decisions. A
 function whose value in the flow map is itself a map with true and false
 keys is a decision. A function whose value in the map is another function is
 an action.

 This particular flow performs a renewal of a web-like session token. It
 runs in a Pedestal interceptor, so it receives a context map (with :request,
 :response and other keys) as a parameter and at the end it populates the
 :response key of the map.

 The way to read this is-

 0. a context map is prepared.
 1. the data flow runner looks for the :start key. the value of :start is
 valid-request?
 2. The value of valid-request? is a map, rather than a function, so the flow
 determines valid-request? is a decision function- an ordinary function that
 takes a context and is expected to return true or false.
 3. the flow runner executes valid-request? If it returns true, the flow
 runner proceeds to valid-token? using the same context map. If false,
 proceed to invalid-request
 4. valid-token? is similarly a decision function, it's executed similarly
 and is also expected to return true or false. invalid-request is an action.
 It's expected to return a new context map- in this case it populates the
 :response with a 4xx :status and some other response attributes.
 5. the flow engine keeps going between keys and values until it comes to a
 value of :end. Then the resulting context is the output of the flow.

 The action function in the above called renew-session can do IO to renew a
 user session in the database. It's copied below.

 (defn renew-session [context]
   (let [database(get-in context [:components :database])
 session-key (get-in context [:work :session-key])
 renewed?(db/renew-session! database session-key)]
 (if (not (nil? renewed?))
   (assoc-in context [:work :renewed-key] session-key)
   context)))

 It simply pulls the database connection from the context, calls into a db
 specific function, db/renew-session!, which takes a connection and a key,
 and could be a protocol function that accepts a Record that encapsulates a
 specific storage resource, or could be a multimethod.

 This model of a data flow with actions and decisions follows Amazon's Simple
 Workflow Service, and the clever encoding of that flow as a map is due to
 Cognitect.

 A few projects exist now that encode flows in data form with an engine to
 process them. There are some trade-offs- it takes practice to read them, you
 can trade off a little in performance. In the above there's a fair amount of
 boilerplate that could be abstracted away along the lines of of Prismatic's
 Graph.

 You get a lot of other benefits- a consistent system shape, separation of
 concerns between core logic and edge IO, consistent error handling,
 logging/auditing, etc. Flows can be reused and can themselves compose,
 because everything takes a context map. You could also generate a visual
 decision tree of the model, or a real time heat map of decisions 

Re: partition-when

2015-03-05 Thread Steve Miner
For the transducer version, I don’t think you need to keep track of the 
previous value (fval). The decision to start a new partition group depends only 
on the current item. Here’s my version. (Warning: virtually untested.)  I 
assume that the first item goes into the first partition no matter what so you 
don’t even need to call f.  Maybe you should for side-effects?

(defn partition-when
   Applies f to each value in coll, starting a new partition each time f 
returns a
   true value.  Returns a lazy seq of partitions.  Returns a stateful
   transducer when no collection is provided.
  {:added 1.X
   :static true}
  ([f]
   (fn [rf]
 (let [a (java.util.ArrayList.)]
   (fn
 ([] (rf))
 ([result]
  (let [result (if (.isEmpty a)
 result
 (let [v (vec (.toArray a))]
   ;;clear first!
   (.clear a)
   (unreduced (rf result v]
(rf result)))
 ([result input]
(if (.isEmpty a)
  (do (.add a input)
  result)
  (if (f input)
(let [v (vec (.toArray a))]
  (.clear a)
  (let [ret (rf result v)]
(when-not (reduced? ret)
  (.add a input))
ret))
(do
  (.add a input)
  result

  ([f coll]
  (lazy-seq
   (when-let [s (seq coll)]
 (let [fst (first s)
   run (cons fst (take-while #(not (f %)) (next s)))]
   (cons run (partition-when f (seq (drop (count run) s)


— Steve

 On Mar 5, 2015, at 12:11 PM, Andy- andre.r...@gmail.com wrote:
 
 Tried myself and my first transducer for fun:
 
 (defn partition-when
   [f]
   (fn [rf]
 (let [a (java.util.ArrayList.)
   fval (volatile! false)]
   (fn
 ([] (rf))
 ([result]
(let [result (if (.isEmpty a)
   result
   (let [v (vec (.toArray a))]
 ;;clear first!
 (.clear a)
 (unreduced (rf result v]
  (rf result)))
 ([result input]
 (if-not (and (f input)  @fval)
(do
  (vreset! fval true)
  (.add a input)
  result)
(let [v (vec (.toArray a))]
  (.clear a)
  (let [ret (rf result v)]
(when-not (reduced? ret)
  (.add a input))
ret
 
 
 (into [] (partition-when
   #(.startsWith % ))
   [ 1  2 22  3])
 
 Based on partition-by (on master branch). Would be interesting how fast it is 
 compared to the other implementations.
 
 Any comments appreciated.
 
 Cheers

-- 
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: clojure map to java instance of pojo class

2015-03-05 Thread Xiangtao Zhou
thanks, i test with defrecord. 

On Thursday, March 5, 2015 at 4:39:03 PM UTC+8, Colin Yates wrote:

 Isn't this exactly what defrecord does? 

 On 5 March 2015 at 07:42, Xiangtao Zhou tao...@gmail.com javascript: 
 wrote: 
  hi all, 
  
  is there some library or simple way to do it like the function 
 map-to-pojo 
  in the following code ? 
  
  java code 
  class A{ 
public int a; 
public String b; 
  } 
  
  clojure code 
  (def a {:a 1 :b 2}) 
  (def b (map-to-pojo a A)) 
  (instance? b A) 
  
  
  any solution is good. 
  
  Joe 
  
  
  
  
  -- 
  You received this message because you are subscribed to the Google 
  Groups Clojure group. 
  To post to this group, send email to clo...@googlegroups.com 
 javascript: 
  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/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: clojure map to java instance of pojo class

2015-03-05 Thread Colin Yates
Isn't this exactly what defrecord does?

On 5 March 2015 at 07:42, Xiangtao Zhou tao...@gmail.com wrote:
 hi all,

 is there some library or simple way to do it like the function map-to-pojo
 in the following code ?

 java code
 class A{
   public int a;
   public String b;
 }

 clojure code
 (def a {:a 1 :b 2})
 (def b (map-to-pojo a A))
 (instance? b A)


 any solution is good.

 Joe




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

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


Re: partition-when

2015-03-05 Thread Andy-
Tried myself and my first transducer for fun:

(defn partition-when
  [f]
  (fn [rf]
(let [a (java.util.ArrayList.)
  fval (volatile! false)]
  (fn
([] (rf))
([result]
   (let [result (if (.isEmpty a)
  result
  (let [v (vec (.toArray a))]
;;clear first!
(.clear a)
(unreduced (rf result v]
 (rf result)))
([result input]
(if-not (and (f input)  @fval)
   (do
 (vreset! fval true)
 (.add a input)
 result)
   (let [v (vec (.toArray a))]
 (.clear a)
 (let [ret (rf result v)]
   (when-not (reduced? ret)
 (.add a input))
   ret

(into [] (partition-when
  #(.startsWith % ))
  [ 1  2 22  3])


Based on partition-by (on master branch). Would be interesting how fast it 
is compared to the other implementations.

Any comments appreciated.

Cheers


On Tuesday, March 3, 2015 at 2:46:29 PM UTC-5, Frank wrote:

 Hi all,

 for some tests I need a function which starts a new partition each time a 
 predicate returns true, for instance:

 (partition-when
   (fn [s] (.startsWith s ))
   [ 1 2 3  4 5 6])
 := [[ 1 2 3] [ 4 5 6]]

 Since I haven't found a built-in function, I copied, pasted, and modified 
 the core function partition-by:

 (defn partition-when
   [f coll]
   (lazy-seq
(when-let [s (seq coll)]
  (let [fst (first s)
run (cons fst (take-while #(not (f %)) (next s)))]
(cons run (partition-when f (seq (drop (count run) s

 Is there a better (more idiomatic) way to achieve the same result?

 Thank you in advance.

 Frank


-- 
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: Any Lispers in South Devon, UK?

2015-03-05 Thread Martin Rist
Hi Stephen

Just seconding John Kane's post below - there are a few of us (including 
John and Dan Stone) who met up at the Exeter Web session last week.  I'd 
definitely be interested in meeting up if something in Exeter works for you.

Martin

-- 
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: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Colin Yates
Hi Jonah,

This sounds very much like the model layer in DDD, which ironically is
exactly what I am building.

However, in the middle of a data flow a function needs to reach out to
a repository to make a decision - how does that fit in with the data
flow approach?


On 5 March 2015 at 13:39, Jonah Benton jo...@jonah.com wrote:
 Hi Colin,

 Another option, other than HOFs or dynamic binding, is what might be called
 a data flow approach.

 At the edge of the application are the functions that explicitly take
 parameterized resources to perform edge state IO. These might be bare
 functions, or they might be protocol implementations that await the delivery
 of a type to perform their operation, or multimethods.

 At the center are functions that take a context map, which contains all
 relevant application state- IO resources and transient state data. Those
 functions are arranged in a data flow and capture the logic or state
 transitions of the application independent of any specific IO commitments.
 They can use schema or type annotation or pre/post conditions to enforce
 invariants.

 When data flow processing arrives at a place where some edge IO should
 occur, these data flow functions act as adapters to get-in the appropriate
 resource or Record from the context map and call the edge functions to
 perform IO.

 The result is a wider, flatter system, propagating state explicitly rather
 than implicitly through the call stack.

 Jonah



 On Wed, Mar 4, 2015 at 12:58 PM, Colin Yates colin.ya...@gmail.com wrote:

 Hi,

 I am looking for the Clojure equivalent of:

 class Whatever {
 @Transactional
 void doSomething(IDoSomething one, IDoSomethingElse two) {
   one.doSomething()
   two.doSomething()
 }
 }

 where both one and two are dependency injected with a proxy which resolves
 to a thread local database connection. In addition, one might itself have a
 collaborator which itself has a collaborator which needs a datasource.

 So far I have two protocols:

 (defprotocol IDoSomething
  (do-something [this ...])

 (defprotocol IDoSomethingElse
  (do-something [this ...])

 Each protocol may have a number of implementations, one of which is a JDBC
 implementation:

 (defrecord JdbcIDoSomething [db]
   (do-something [this ...] ...))

 The problem is that the calling code only gets provided an IDoSomething
 and an IDoSomethingElse and it wants to do something like:

 (let [one (-JdbcDoSomething db) two (-JdbcDoSomethingElse db)]
   (with-transaction [tx db]
 (do-something one)
 (do-something-else two)))

 The problem here is that the implementations of do-something and
 do-something-else won't have access to the local bound 'tx', they will have
 their own 'db'.

 I realise the general argument is to be explicit and pass a db as the
 first argument to the protocol but this isn't appropriate in this case as
 there are validly multiple implementations. I could abstract a
 'unit-of-work' and pass that as the first argument to the protocols but that
 seems a bit painful.

 Also, these protocols may be used quite far away from where the database
 code lives and passing a parameter all the way through the call stack is
 painful.

 I am using Stuart Sierra's components if that makes any difference.

 I can't be the first person to run into this but google is surprisingly
 unhelpful which makes me think I have missed something fundamental, and that
 I have something upside down.

 What do you all do?


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


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

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, 

Re: Any Lispers in South Devon, UK?

2015-03-05 Thread Thomas
There are also a few of us in the Southampton/Winchester area

Get in touch if you are interested.

Thomas

On Tuesday, 3 March 2015 21:53:57 UTC, Stephen Wakely wrote:

 Hi,

 Are there any other Lispers in South Devon who would be interested in 
 meeting up and talking code? Clojure, Common Lisp, Scheme, anything as long 
 as there are loads of parentheses!

 Please get in touch.


 Cheers

 Stephen



-- 
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: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Jonah Benton
Yes, exactly.

That's fine, a node in the middle of the data flow can be responsible for
reaching out to the edge to synchronously get some data to feed into a
decision performed by the data flow. It would just do that through the edge
functions.

A request for data could also be asynchronously initiated once enough
context had been determined by the data flow, and a promise added to the
context map for later derefing (likely with a timeout).

If the request for the data is context-free, it could be pulled in at the
start of the data flow.

By edge, it's is not that IO can't be done in the middle of a dataflow,
it's just that functions that deal with dataflow follow one pattern (taking
a context map) so they can be easily composed and rearranged, while
functions that deal with edge resources take those resources along with
other parameters more explicitly, so the data flow can run in an insulated
fashion.



On Thu, Mar 5, 2015 at 8:55 AM, Colin Yates colin.ya...@gmail.com wrote:

 Hi Jonah,

 This sounds very much like the model layer in DDD, which ironically is
 exactly what I am building.

 However, in the middle of a data flow a function needs to reach out to
 a repository to make a decision - how does that fit in with the data
 flow approach?


 On 5 March 2015 at 13:39, Jonah Benton jo...@jonah.com wrote:
  Hi Colin,
 
  Another option, other than HOFs or dynamic binding, is what might be
 called
  a data flow approach.
 
  At the edge of the application are the functions that explicitly take
  parameterized resources to perform edge state IO. These might be bare
  functions, or they might be protocol implementations that await the
 delivery
  of a type to perform their operation, or multimethods.
 
  At the center are functions that take a context map, which contains all
  relevant application state- IO resources and transient state data. Those
  functions are arranged in a data flow and capture the logic or state
  transitions of the application independent of any specific IO
 commitments.
  They can use schema or type annotation or pre/post conditions to enforce
  invariants.
 
  When data flow processing arrives at a place where some edge IO should
  occur, these data flow functions act as adapters to get-in the
 appropriate
  resource or Record from the context map and call the edge functions to
  perform IO.
 
  The result is a wider, flatter system, propagating state explicitly
 rather
  than implicitly through the call stack.
 
  Jonah
 
 
 
  On Wed, Mar 4, 2015 at 12:58 PM, Colin Yates colin.ya...@gmail.com
 wrote:
 
  Hi,
 
  I am looking for the Clojure equivalent of:
 
  class Whatever {
  @Transactional
  void doSomething(IDoSomething one, IDoSomethingElse two) {
one.doSomething()
two.doSomething()
  }
  }
 
  where both one and two are dependency injected with a proxy which
 resolves
  to a thread local database connection. In addition, one might itself
 have a
  collaborator which itself has a collaborator which needs a datasource.
 
  So far I have two protocols:
 
  (defprotocol IDoSomething
   (do-something [this ...])
 
  (defprotocol IDoSomethingElse
   (do-something [this ...])
 
  Each protocol may have a number of implementations, one of which is a
 JDBC
  implementation:
 
  (defrecord JdbcIDoSomething [db]
(do-something [this ...] ...))
 
  The problem is that the calling code only gets provided an IDoSomething
  and an IDoSomethingElse and it wants to do something like:
 
  (let [one (-JdbcDoSomething db) two (-JdbcDoSomethingElse db)]
(with-transaction [tx db]
  (do-something one)
  (do-something-else two)))
 
  The problem here is that the implementations of do-something and
  do-something-else won't have access to the local bound 'tx', they will
 have
  their own 'db'.
 
  I realise the general argument is to be explicit and pass a db as the
  first argument to the protocol but this isn't appropriate in this case
 as
  there are validly multiple implementations. I could abstract a
  'unit-of-work' and pass that as the first argument to the protocols but
 that
  seems a bit painful.
 
  Also, these protocols may be used quite far away from where the database
  code lives and passing a parameter all the way through the call stack is
  painful.
 
  I am using Stuart Sierra's components if that makes any difference.
 
  I can't be the first person to run into this but google is surprisingly
  unhelpful which makes me think I have missed something fundamental, and
 that
  I have something upside down.
 
  What do you all do?
 
 
  --
  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
  

Re: Who's using Clojure?

2015-03-05 Thread Michael Richards
I'm about to start training 4 devs on my team at Oracle in Clojure.  My 
manager is very nervous about putting Clojure into the product.  I'm 
forging on regardless :)  I rewrote some components of our product in 
Clojure in my spare time, mainly as a proof of concept that we could do 
some of our analytics in the streaming model rather than in the data 
warehousing model.  As sometimes happens, the POC was so simple and fast 
that the team is now interested in productizing it.

In our last 1-1 meeting, my manager told me he had searched LinkedIn for 
Clojure and only got 9000 matches.   Whereas his search for Java turned 
up 80 million or some such.  My rebuttal is that those are the 9000 
smartest developers, so you should be trying to recruit them.


--mike


On Tuesday, April 19, 2011 at 7:38:14 AM UTC-7, Damien wrote:

 Hi Everyone,

 I'm on a mission: introducing Clojure in my company, which is a big 
 consulting company like many others.

 I started talking about Clojure to my manager yesterday.
 I was prepared to talk about all the technical benefits and he was 
 interested.
 I still have a long way to go but I think that was a good start.

 However I need to figure out how to answer to one of his questions: who is 
 using Clojure?

 Obviously I know each of you is using Clojure, that makes almost 5,000 
 people.
 I know there is Relevance and Clojure/core.
 I read about BackType or FlightCaster using Clojure.

 But, let's face it, that doesn't give me a killer answer.

 What could help is a list of success stories, a bit like MongoDB published 
 here:
 http://www.mongodb.org/display/DOCS/Production+Deployments

 Is there a place where I could find this kind of information for Clojure?

 Thanks

 -- 
 Damien Lepage
 http://damienlepage.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: partition-when

2015-03-05 Thread Martin Harrigan
Hi Frank,

I use a similar function that combines partition-by and partition-all:

(defn partition-when
  [f coll]
  (map (partial apply concat) (partition-all 2 (partition-by f coll

Martin.


On Wed, Mar 4, 2015 at 10:19 PM, Ivan L ivan.laza...@gmail.com wrote:

 I went though almost the exact same exercise and my code is almost
 identical to yours.  I called it partition-every and I use it a lot.  A
 more determined individual might submit this for inclusion into core!


 On Tuesday, March 3, 2015 at 2:46:29 PM UTC-5, Frank wrote:

 Hi all,

 for some tests I need a function which starts a new partition each time a
 predicate returns true, for instance:

 (partition-when
   (fn [s] (.startsWith s ))
   [ 1 2 3  4 5 6])
 := [[ 1 2 3] [ 4 5 6]]

 Since I haven't found a built-in function, I copied, pasted, and modified
 the core function partition-by:

 (defn partition-when
   [f coll]
   (lazy-seq
(when-let [s (seq coll)]
  (let [fst (first s)
run (cons fst (take-while #(not (f %)) (next s)))]
(cons run (partition-when f (seq (drop (count run) s

 Is there a better (more idiomatic) way to achieve the same result?

 Thank you in advance.

 Frank

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


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


Re: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Colin Yates
Sounds interesting - are there are instances that I can look at?

On 5 March 2015 at 14:15, Jonah Benton jo...@jonah.com wrote:
 Yes, exactly.

 That's fine, a node in the middle of the data flow can be responsible for
 reaching out to the edge to synchronously get some data to feed into a
 decision performed by the data flow. It would just do that through the edge
 functions.

 A request for data could also be asynchronously initiated once enough
 context had been determined by the data flow, and a promise added to the
 context map for later derefing (likely with a timeout).

 If the request for the data is context-free, it could be pulled in at the
 start of the data flow.

 By edge, it's is not that IO can't be done in the middle of a dataflow, it's
 just that functions that deal with dataflow follow one pattern (taking a
 context map) so they can be easily composed and rearranged, while functions
 that deal with edge resources take those resources along with other
 parameters more explicitly, so the data flow can run in an insulated
 fashion.



 On Thu, Mar 5, 2015 at 8:55 AM, Colin Yates colin.ya...@gmail.com wrote:

 Hi Jonah,

 This sounds very much like the model layer in DDD, which ironically is
 exactly what I am building.

 However, in the middle of a data flow a function needs to reach out to
 a repository to make a decision - how does that fit in with the data
 flow approach?


 On 5 March 2015 at 13:39, Jonah Benton jo...@jonah.com wrote:
  Hi Colin,
 
  Another option, other than HOFs or dynamic binding, is what might be
  called
  a data flow approach.
 
  At the edge of the application are the functions that explicitly take
  parameterized resources to perform edge state IO. These might be bare
  functions, or they might be protocol implementations that await the
  delivery
  of a type to perform their operation, or multimethods.
 
  At the center are functions that take a context map, which contains all
  relevant application state- IO resources and transient state data. Those
  functions are arranged in a data flow and capture the logic or state
  transitions of the application independent of any specific IO
  commitments.
  They can use schema or type annotation or pre/post conditions to enforce
  invariants.
 
  When data flow processing arrives at a place where some edge IO should
  occur, these data flow functions act as adapters to get-in the
  appropriate
  resource or Record from the context map and call the edge functions to
  perform IO.
 
  The result is a wider, flatter system, propagating state explicitly
  rather
  than implicitly through the call stack.
 
  Jonah
 
 
 
  On Wed, Mar 4, 2015 at 12:58 PM, Colin Yates colin.ya...@gmail.com
  wrote:
 
  Hi,
 
  I am looking for the Clojure equivalent of:
 
  class Whatever {
  @Transactional
  void doSomething(IDoSomething one, IDoSomethingElse two) {
one.doSomething()
two.doSomething()
  }
  }
 
  where both one and two are dependency injected with a proxy which
  resolves
  to a thread local database connection. In addition, one might itself
  have a
  collaborator which itself has a collaborator which needs a datasource.
 
  So far I have two protocols:
 
  (defprotocol IDoSomething
   (do-something [this ...])
 
  (defprotocol IDoSomethingElse
   (do-something [this ...])
 
  Each protocol may have a number of implementations, one of which is a
  JDBC
  implementation:
 
  (defrecord JdbcIDoSomething [db]
(do-something [this ...] ...))
 
  The problem is that the calling code only gets provided an IDoSomething
  and an IDoSomethingElse and it wants to do something like:
 
  (let [one (-JdbcDoSomething db) two (-JdbcDoSomethingElse db)]
(with-transaction [tx db]
  (do-something one)
  (do-something-else two)))
 
  The problem here is that the implementations of do-something and
  do-something-else won't have access to the local bound 'tx', they will
  have
  their own 'db'.
 
  I realise the general argument is to be explicit and pass a db as the
  first argument to the protocol but this isn't appropriate in this case
  as
  there are validly multiple implementations. I could abstract a
  'unit-of-work' and pass that as the first argument to the protocols but
  that
  seems a bit painful.
 
  Also, these protocols may be used quite far away from where the
  database
  code lives and passing a parameter all the way through the call stack
  is
  painful.
 
  I am using Stuart Sierra's components if that makes any difference.
 
  I can't be the first person to run into this but google is surprisingly
  unhelpful which makes me think I have missed something fundamental, and
  that
  I have something upside down.
 
  What do you all do?
 
 
  --
  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 

Re: Any Lispers in South Devon, UK?

2015-03-05 Thread Alan Forrester
On 5 March 2015 at 14:08, Thomas th.vanderv...@gmail.com wrote:

 There are also a few of us in the Southampton/Winchester area

 Get in touch if you are interested.

I am in Southampton and would be interested in meeting some Clojurians.

Alan

-- 
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] Understanding the Persistent Vector

2015-03-05 Thread danle...@gmail.com
This was fantastic.  Really looking forward to the RRB Tree.



On Wednesday, March 4, 2015 at 12:31:54 PM UTC-5, Jean Niklas L'orange 
wrote:

 Hi Frank,

 On Wednesday, March 4, 2015 at 12:24:42 PM UTC+1, Frank Castellucci wrote:

 Will you be doing this for other data types?


 I will have a small break first, but I intend to do the same kind of 
 series for persistent hash maps/sets. Maybe even RRB-trees if people are 
 interested (I found them to be pretty hard to grasp by the paper alone).

 Again, Great Work!


 Thanks! =)

 -- Jean Niklas


 Frank

 On Saturday, February 28, 2015 at 11:14:17 AM UTC-5, Jean Niklas L'orange 
 wrote:

 Hello fellow Clojurians,

 I am happy to announce that I have finished my blogpost series on the 
 persistent
 vector. It consists of five parts:

1. The basic algorithms 
http://hypirion.com/musings/understanding-persistent-vector-pt-1
2. Indexing 
http://hypirion.com/musings/understanding-persistent-vector-pt-2
3. The tail optimisation 
http://hypirion.com/musings/understanding-persistent-vector-pt-3
4. Transients 
http://hypirion.com/musings/understanding-clojure-transients
5. Performance 
http://hypirion.com/musings/persistent-vector-performance-summarised 
(which is a summary of this detailed blogpost 
http://hypirion.com/musings/persistent-vector-performance)

 I hope this will help you to get a good understanding of how the 
 algorithms on
 the data structure work, how the optimisations work, and how efficient 
 it is on
 the JVM.

 Constructive criticism, both positive and negative, is appreciated.

 Enjoy!

 (NB: I haven't gotten around to fix the illustrations in part 3, so
 unfortunately it will be a bit hard to read if you print it out in 
 grayscale.
 It's on my todo-list.)

 -- Jean Niklas L'orange



-- 
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: Idiomatic way to co-ordinate 'disconnected' services into a single transaction (ala Spring's @Transactional functionality)?

2015-03-05 Thread Jonah Benton
Hi Colin,

Another option, other than HOFs or dynamic binding, is what might be called
a data flow approach.

At the edge of the application are the functions that explicitly take
parameterized resources to perform edge state IO. These might be bare
functions, or they might be protocol implementations that await the
delivery of a type to perform their operation, or multimethods.

At the center are functions that take a context map, which contains all
relevant application state- IO resources and transient state data. Those
functions are arranged in a data flow and capture the logic or state
transitions of the application independent of any specific IO commitments.
They can use schema or type annotation or pre/post conditions to enforce
invariants.

When data flow processing arrives at a place where some edge IO should
occur, these data flow functions act as adapters to get-in the appropriate
resource or Record from the context map and call the edge functions to
perform IO.

The result is a wider, flatter system, propagating state explicitly rather
than implicitly through the call stack.

Jonah



On Wed, Mar 4, 2015 at 12:58 PM, Colin Yates colin.ya...@gmail.com wrote:

 Hi,

 I am looking for the Clojure equivalent of:

 class Whatever {
 @Transactional
 void doSomething(IDoSomething one, IDoSomethingElse two) {
   one.doSomething()
   two.doSomething()
 }
 }

 where both one and two are dependency injected with a proxy which resolves
 to a thread local database connection. In addition, one might itself have a
 collaborator which itself has a collaborator which needs a datasource.

 So far I have two protocols:

 (defprotocol IDoSomething
  (do-something [this ...])

 (defprotocol IDoSomethingElse
  (do-something [this ...])

 Each protocol may have a number of implementations, one of which is a JDBC
 implementation:

 (defrecord JdbcIDoSomething [db]
   (do-something [this ...] ...))

 The problem is that the calling code only gets provided an IDoSomething
 and an IDoSomethingElse and it wants to do something like:

 (let [one (-JdbcDoSomething db) two (-JdbcDoSomethingElse db)]
   (with-transaction [tx db]
 (do-something one)
 (do-something-else two)))

 The problem here is that the implementations of do-something and
 do-something-else won't have access to the local bound 'tx', they will have
 their own 'db'.

 I realise the general argument is to be explicit and pass a db as the
 first argument to the protocol but this isn't appropriate in this case as
 there are validly multiple implementations. I could abstract a
 'unit-of-work' and pass that as the first argument to the protocols but
 that seems a bit painful.

 Also, these protocols may be used quite far away from where the database
 code lives and passing a parameter all the way through the call stack is
 painful.

 I am using Stuart Sierra's components if that makes any difference.

 I can't be the first person to run into this but google is surprisingly
 unhelpful which makes me think I have missed something fundamental, and
 that I have something upside down.

 What do you all do?


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


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


Re: Om design query

2015-03-05 Thread Tom Lynch
One workable possibility: 

* init a core.async channel in the container
* pass the channel from the container into each child component at build 
time using :opts or :state
* send the discovered size of each child component, with identifying data, 
as a channel message during IDidMount

I don't find these sorts of solutions terribly elegant but it would be 
usable I think. 

Tom

On Friday, 6 March 2015 12:42:12 UTC+8, James Reeves wrote:

 I've been writing an application using Om, and I've come across a problem 
 I haven't been able to find a good solution for. I'd be grateful for any 
 ideas people might have on how to proceed.

 In a nutshell, I have a bunch of elements that need to be arranged 
 according to a specific algorithm. They cannot overlap, so I need to know 
 the sizes of all the elements in order to arrange them.



-- 
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] Dunaj project, an alternative core API for Clojure

2015-03-05 Thread sesm
Ivan was probably talking about dunaj-starter repo on github:
https://github.com/dunaj-project/dunaj-starter/blob/master/src/dunaj_starter/core.clj

пятница, 6 марта 2015 г., 9:42:00 UTC+3 пользователь Alex Baranosky написал:

 Where is this example project?

 On Thu, Mar 5, 2015 at 7:40 PM, Ivan L ivan.l...@gmail.com javascript: 
 wrote:

 Just a quick glance at the example project shows integrated type 
 definitions.  I'm curious for sure.

 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com 
 javascript:
 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/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.


Om design query

2015-03-05 Thread James Reeves
I've been writing an application using Om, and I've come across a problem I
haven't been able to find a good solution for. I'd be grateful for any
ideas people might have on how to proceed.

In a nutshell, I have a bunch of elements that need to be arranged
according to a specific algorithm. They cannot overlap, so I need to know
the sizes of all the elements in order to arrange them.

Om has an IDidMount protocol which is called after the component has been
mounted into the DOM. I can use this to find out the size of the element:

(let [node (get-node owner)]
  [(.-offsetWidth node) (.-offsetHeight node)])

Elements can be hidden with visibility: hidden until their sizes are
known.

The problem that's stumping me is how to deliver the sizes back to the
containing component so that all the elements can be arranged correctly.

The most obvious way is via the cursor, but I don't like the idea of mixing
application state with local display information. Can anyone think of a
better way?

- James

-- 
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: Om design query

2015-03-05 Thread Dave Della Costa
(cc'ing clojurescr...@googlegroups.com)

Hi James,

Let me make sure I understand what you're asking: you have a parent
enclosing component that has to do calculations to position a set of
child component element, but you can only properly calculate positioning
for those child elements (in the parent?) after you get offset position
information for each one, once they have mounted?

DD


On 2015/03/06 13:40, James Reeves wrote:
 I've been writing an application using Om, and I've come across a
 problem I haven't been able to find a good solution for. I'd be grateful
 for any ideas people might have on how to proceed.
 
 In a nutshell, I have a bunch of elements that need to be arranged
 according to a specific algorithm. They cannot overlap, so I need to
 know the sizes of all the elements in order to arrange them.
 
 Om has an IDidMount protocol which is called after the component has
 been mounted into the DOM. I can use this to find out the size of the
 element:
 
 (let [node (get-node owner)]
   [(.-offsetWidth node) (.-offsetHeight node)])
 
 Elements can be hidden with visibility: hidden until their sizes are
 known.
 
 The problem that's stumping me is how to deliver the sizes back to the
 containing component so that all the elements can be arranged correctly.
 
 The most obvious way is via the cursor, but I don't like the idea of
 mixing application state with local display information. Can anyone
 think of a better way?
 
 - James
 
 -- 
 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
 mailto: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.