Ann: factorhouse/slipway - A Clojure Companion to Jetty.

2022-12-21 Thread Derek Troy-West
Slipway by Factor House is now open-source and published to Clojars:

https://github.com/factorhouse/slipway

https://clojars.org/io.factorhouse/slipway-jetty9
https://clojars.org/io.factorhouse/slipway-jetty10
https://clojars.org/io.factorhouse/slipway-jetty11

Slipway is a Clojure companion to embedded Jetty with websocket support.

We take great utility from Jetty in our product. Over time our requirements 
out-grew the libraries that are currently available in this space, so we 
built our own.

Hopefully our experience is useful in the broader Clojure community.

Best (and happy holidays),
 Derek





-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/3a6aa4fd-ad22-4485-91ba-5eee467887d3n%40googlegroups.com.


Re: Tour of our 250k line Clojure codebase

2021-06-03 Thread Derek Troy-West
Hi Nathan (& team), thanks for the post/update it's filled with interesting 
info on a mature Clojure codebase.

One quick question from me - do you have any open-source projects planned? 
In a purely selfish sense I would love to take a look at the custom 
language!

I look forward to seeing the product when it's available, this is very much 
in my area of interest.

Best,
 Derek

On Friday, June 4, 2021 at 4:06:16 AM UTC+10 natha...@gmail.com wrote:

> I published a post today giving on overview of our codebase at Red Planet 
> Labs and the many ways it leverages the unique qualities of Clojure: 
> https://tech.redplanetlabs.com/2021/06/03/tour-of-our-250k-line-clojure-codebase/
>
> Clojure has been a huge reason why we've been able to tackle such an 
> ambitious project as a small team. Please give the post a read, and I'm 
> happy to answer any questions.
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/543a0abf-0c79-4d05-95a1-56f7ec4b00afn%40googlegroups.com.


Re: Idiomatic program for someone new to Clojure

2020-12-16 Thread Derek Troy-West
Hello James,

 Aditya links to one of Stuart Sierra's Do's and Don't posts.

That series of posts really influenced my basic Clojure style and I'd 
suggest reading them all: https://stuartsierra.com/tag/dos-and-donts, 
they're (mostly!) great and simple advice.

Best,
 Derek

On Tuesday, December 15, 2020 at 2:18:49 AM UTC+11 jamesl...@gmail.com 
wrote:

> Hello all,
> This is my first Clojure program and I was hoping to get some advice on it 
> since I don't know any experienced Clojure devs. I'm using it locally to 
> print the latest build numbers for a list of projects.
>
> ```
> (ns jlorenzen.core
>   (:gen-class)
>   (:require [clj-http.client :as client])
>   (:require [cheshire.core :refer :all]))
>
> (defn fetch-pipeline
> [pipeline]
> (client/get (str "https://example.com/go/api/pipelines/; pipeline 
> "/history")
> {:basic-auth "username:password"}))
>
> (defn get-latest-build
> [pipeline]
> (let [response (fetch-pipeline pipeline)
> json (parse-string (:body response) true)]
> (let [[pipeline] (:pipelines json)]
> (:counter pipeline
>
> (def core-projects #{"projectA"
> "projectB"
> "projectC"
> "projectD"})
>
> (defn print-builds
> ([]
> (print-builds core-projects))
> ([projects]
> (let [builds (pmap #(str % " " (get-latest-build %)) projects)]
> (map #(println %) (sort builds)
> ```
>
> This will output the following:
> ```
> projectA 156
> projectB 205
> projectC 29
> projectD 123
> (nil nil nil nil)
> ```
>
> A few questions:
>
>- How can this program be improved?
>- How idiomatic is it?
>- How can I prevent it from returning the nils at the end? I know this 
>is returning nil for each map'd item; I just don't know the best way to 
>prevent that.
>
> Thanks,
> James Lorenzen
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/d3c2e1a2-bb6e-42af-a412-f2c92d01d123n%40googlegroups.com.


Re: Feedback on datafy/nav project

2020-01-31 Thread Derek Troy-West
Hi Dimitris.

I think your library is an excellent idea. Like the other replies I'd 
prefer if it used Datafiable.

Would you consider adopting an explicit options map instead of the jdt/now! 
varags destructuring? I'm not sure if that style is adopted throughout, but 
in general I prefer maps to the syntactic sugar.

Finally, just a suggestion that 'objectify' might be a bit more explicit in 
intent to 'undatafy'.

I look forward to getting it in the REPL once it's up on clojars, thanks!

On Saturday, 1 February 2020 08:50:31 UTC+11, Jim foo.bar wrote:
>
> Sean, 
>
> I've already done that ;)
>
> I will publish to clojars either this weekend or the next - I just want to 
> add some more tests...
>
>
> On 31/01/2020 21:34, Sean Corfield wrote:
>
> Dimitris,
>
>  
>
> As a follow-up to Alex’s comments: if you change your lib to extend the 
> clojure.datafy version, I’ll almost certainly use your library  
>
>  
>
> Sean Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
>
>  
>
> *From: *dimitris 
> *Sent: *Friday, January 31, 2020 1:23 PM
> *To: *clo...@googlegroups.com 
> *Subject: *Re: Feedback on datafy/nav project
>
>  
>
> Ok, thanks a million Alex
>
>  
>
> On 31/01/2020 21:13, Alex Miller wrote:
>
> Datafiable is not special, the guidelines (recently refreshed with Rich's 
> input at https://clojure.org/reference/protocols#_guidelines_for_extension) 
> still make sense, but are still just guidelines for your thinking not Laws 
> whose breakage will land you in Clojure Jail.
>
>  
>
> If you want to make protocol extensions for java time objects to 
> datafiable and put it in a lib, go for it. No one is making anyone else use 
> it. Maybe some day we'll do that in core, maybe not.
>
>  
>
> I'm certain that copying Datafiable to your own version however would lead 
> only to a) confusion and b) a certainty that no one else would actually use 
> it, and that seems like a waste of time.
>
>  
>
>
> On Friday, January 31, 2020 at 1:24:09 PM UTC-6, Jim foo.bar wrote: 
>
> I tend to agree with you in where the benefit is - it's just that the way 
> the protocol docs are phrased, and some of the language used in that 
> mailing discussion from 10 years ago (from authoritative sources like Rich 
> and Stuart), implies that *no library is to extend clojure.core protocols 
> to core Java objects*, and that only Clojure itself is allowed do that. 
> The example Stuart gave back then with the english/spelling-corrector VS 
> spanish/spelling-corrector is pretty telling...
>
> Could it perhaps be the case that `Datafiable` is somewhat special in 
> that, it was conceived for the purpose of open extension by third parties, 
> and that the protocol extension guidelines don't really apply to it (or 
> perhaps not as strictly)?  
>
>  
>
> Thanks for taking the time :)
>
> Dimitris
>
>  
>
> On 31/01/2020 01:23, Sean Corfield wrote:
>
> If your library is intended specifically to provide the ability to 
> datafy/nav java.time objects then it is something optional that users can 
> choose to opt into.
>
>  
>
> The section you meant to link to 
> https://clojure.org/reference/protocols#_guidelines_for_extension says: “To 
> minimize conflicts, consider these guidelines”
>
>  
>
> So they’re a) guidelines and b) just given as a caution to minimize 
> conflicts.
>
>  
>
> There are libraries out there already that exist specifically to give 
> users the option to extend protocols from one library (such as 
> clojure.java.jdbc or next.jdbc) to Java types to provide customized 
> behavior, above and beyond the “base versions for common targets” 
> mentioned in that section provided by the original library.
>
>  
>
> I see benefit in libraries that extend Clojure’s datafy/nav to new domains 
> as a narrow purpose that users can opt into. I see much less benefit in 
> providing the same protocols and function names that core already includes, 
> targeted to new types, in an isolated way such as this. Perhaps that is 
> because I’m already using datafy/nav and I find their utility is enhanced 
> by being extended to other Java types?
>
>  
>
> Yes, if multiple people write multiple libraries A, B, C that extend 
> datafy/nav to java.time types and then other libraries X, Y, Z start 
> pulling in those extenders, consumers of X, Y, Z can be in trouble.
>
>  
>
> Sean Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
>
>  
>
> *From: *dimitris 
> *Sent: *Thursday, January 30, 2020 9:58 AM
> *To: *clo...@googlegroups.com 
> *Subject: *Re: Feedback on datafy/nav project
>
>  
>
> Well, the official Clojure guidelines are to NOT extend protocols, unless 
> you own either the protocol of the type(s) [1].
>
> In particular these lines:
>
> *If you are a library developer, you should not extend if you own neither 
> 

Open-Source Clojure / Kafka Workshop Materials.

2019-05-27 Thread Derek Troy-West
Hello Clojurists!

We recently ran a series of Apache Kafka workshops in Melbourne and Sydney, 
the course materials are open-source and the programming exercise is 
available in Clojure (and Java).

If you have an interest in streaming compute, or just like playing with 
things, you might find them interesting:

All the materials are MIT licensed in GitHub:

https://github.com/troy-west/apache-kafka-three-ways
https://github.com/troy-west/apache-kafka-cli-tools
https://github.com/troy-west/apache-kafka-number-stations
https://github.com/troy-west/apache-kafka-vendor-tools

Along with a solution to the programming exercise, and the Clojure variants.

https://github.com/troy-west/apache-kafka-number-stations-sln
https://github.com/troy-west/apache-kafka-number-stations-clj
https://github.com/troy-west/apache-kafka-number-stations-clj-sln

Bit more information on guided workshops here: 
https://troywest.com/workshops/

At one workshop in Melbourne we had 16 Clojure programmers in the room, all 
of whom program in Clojure in their professional roles, I thought that was 
pretty cool.

Clojure is a brilliant language for delivery in the streaming compute space 
as it's mostly about data and transformations rather than domains and 
modelling.

Contributions welcome if you find any issues or can make improvements.

All the best,
 Derek

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/02f92fac-98c4-45c8-944c-7aa066b0e573%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Attempting to call unbound function in Hadoop (cluster mode) runs fine on single node.

2019-01-04 Thread Derek Troy-West
Bit of a long-shot since my example is related to Storm not Hadoop, and my 
experience was five years ago, but this blog post might help:

http://derek.troywest.com/articles/trident-in-clojure

and this related ticket: https://github.com/sorenmacbeth/marceline/issues/9

I could run a Storm topology locally, or on a single node, but not when 
deployed to a Storm cluster. It came down the the way Storm chops up 
topologies and serialises them across the network to run on remote nodes. 
There a few different ways of implementing interfaces in Clojure, and (at 
the time at least) they had different semantics in the 
serialise-reconstruct-and-run world.

This may also be helpful, it has been fixed since I wrote the blog 
post: http://dev.clojure.org/jira/browse/CLJ-1208

Good luck!

On Saturday, 5 January 2019 08:35:22 UTC+11, cloje wrote:
>
> I have a project that I'm trying to run on Hadoop in cluster mode. 
>
> I have written and executed the code on my local machine and on a single 
> node on Hadoop. But when I try to executed the same jar file in cluster 
> mode with 5 executors, it bombs at a function and says, Attempting to call 
> unbound fn, '#my-func-name.
>
> Has anyone faced the same kind?
> Was there a work around?
>

-- 
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] Cronut: Scheduled Execution via Quartz and Integrant

2018-06-08 Thread Derek Troy-West
Cronut provides a data-first wrapper for the Quartz Job Scheduler.

Github: https://github.com/troy-west/cronut
Clojars: [com.troy-west/cronut "0.1.0"]

Clojure has two existing wrappers for Quartz:

* Quartzite by Michael Klishin / ClojureWerkz
* Twarc by Andrew Rudenko / Prepor

How does Cronut differ?

* Configured entirely from data (with Integrant bindings provided)
* No macros or new protocols, just implement the org.quartz.Job interface
* No global Clojure state
* Latest version of Quartz
* Tagged literals to shortcut common use-cases (#cronut/cron, 
#cronut/interval)
* Easily extensible for further triggers / tagged literals
* Zero dependencies other than Clojure, Quartz, and Integrant.

This is a fairly early release, but we use it internally and will be 
pushing it along as needed.

Ta, 
  Derek

-- 
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] Arche: A Battery Pack for Alia/Cassandra

2017-09-01 Thread Derek Troy-West
Introducing Arche (https://github.com/troy-west/arche).

Using Alia (https://github.com/mpenet/alia) as a base, Arche provides the 
following:

   - Cassandra state management (Cluster / Session / Prepared Statements / 
   Execution Options / UDTs)
   - Optional DI/lifecycle via Integrant 
   <https://github.com/weavejester/integrant> or Component 
   <https://github.com/stuartsierra/component>
   - Externalisation of query definitions via an extension of HugSQL 
   <https://github.com/layerware/hugsql> to support CQL
   - Automatic hyphen/underscore translation with when using HugCQL 
   - Query configuration by simple EDN map of key/cql or key/map (when 
   configuring per-query opts)
   - Prepared statement execution by keyword, supports all Alia execution 
   modes (vanilla, core.async, manifold)
   - User Defined Type (UDT) encoding by keyword
   - As much configuration from EDN as possible (see: tagged literal 
   support)

If you work with Clojure and Cassandra I hope you find this useful.

Best,
 Derek Troy-West




-- 
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 implement a distributed and concurrent system in Clojure?

2017-06-30 Thread Derek Troy-West
I still have Storm topologies in prod, but I'm investigating Kafka Streams 
and Onyx right now.

On Saturday, July 1, 2017 at 9:38:08 AM UTC+10, Bobby Calderwood wrote:
>
> Onyx is super cool, has matured substantially, and has a great team behind 
> it.
>
> I've also had success building with Kafka (and its ecosystem libraries 
> Kafka Connect and Kafka Streams) and Datomic.
>
> Cheers,
> Bobby
>
>

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


Real world Clojure (video).

2017-05-29 Thread Derek Troy-West
I talked recently at the Melbourne Distributed meet-up about my experience 
building HA distributed systems in Clojure, feel free to heckle me about 
the difference between a partition and a token-range:

https://www.troywest.com/blog/2017/5/16/scaling-the-event-stream

To me, Clojure is just leverage. When the problem is broadly one of 
streaming, chopping, stretching, slicing, dicing, and storing data, I have 
never been more effective at providing value to my clients as when I'm at 
the REPL. I'm an unapologetic Java recidivist, I don't know what a monad 
is, and I'll tell you a secret - I don't care.

All the best,
 Derek

p.s. come see us:

https://www.meetup.com/melbourne-distributed/
https://www.meetup.com/clj-melb/

-- 
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: core.async top use cases

2016-10-02 Thread Derek Troy-West
Fine grained control of parallelism is a superb aspect of core.async.

Cassandra is a distributed database, often a query requires you 
resolve-on-read denormalised data partitioned multiple ways (semantically, 
by time, etc). You can think of it like a grid I guess.

Lets say I have a query that I want to execute against Cassandra that 
covers a week of data, where the data is partitioned chronologically by the 
hour, and by modulo 24 to spread data around the cluster, that's going to 
require 4032 queries. Judicious use of core.async/pipeline-async allows me 
to execute those queries in parallel with granular control of the 
chronological / modulo parallelism independent of one another, meaning I 
can play with that parallelism in the REPL by just adjusting a couple of 
numbers and reviewing the results. Twiddling knobs, measuring output.

That allows me to execute those 4032 queries in parallel, sub-second, with 
non-blocking requiring none of the overhead of thread-per-request.

My services are Netty end-to-end (server and driver interface to Cassandra) 
so there are always a fixed number of threads. If I wanted to tune the 
buffers or thread-pool sizes I could probably get an even higher degree of 
throughput / lower-latency on each monolithic cassandra query, the 
constraints are known, quantifiable, and easily configurable.

On Sunday, September 18, 2016 at 6:37:38 PM UTC+12, Matan Safriel wrote:
>
> Hi,
>
> It's very easy to see how core.async solves callback hell for front-end 
> development with clojurescript.
> In what use cases would you use it for server-side? we already have 
> non-blocking IO from Java, and we have clojure agents. So what's a bunch of 
> salient use cases?
> Are there prominent clojure http server implementations which rely on it 
> for transcending the threaded web service paradigm?
>
> Thanks,
> Matan
>
>

-- 
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] components.md

2016-04-30 Thread Derek Troy-West
I've quite enjoyed reading the various approaches to using Component (or 
not as the case may be), so much so that I've added my own two pence:

http://derek.troywest.com/articles/how-i-use-component

On Tuesday, April 5, 2016 at 6:28:48 PM UTC+10, Renzo Borgatti wrote:
>
> Hello clj, 
>
> kinda late into that discussion of a while ago about “how I use 
> components”, I finally wrote-up about it: 
>
> https://github.com/reborg/scccw/blob/master/COMPONENTS.md 
>
> The result is a markdown document that is meant to be used by 
> copy-pasting. So no libraries, no frameworks. The reason is that I’m mainly 
> introducing an architectural convention to handle stateful parts of a 
> Clojure application and I believe your app should bootstrap from these 
> general principles and extend on them, evolutionary. It’s not different 
> from saying that you should isolate impure functions in your code: you 
> wouldn’t create a library out of it. 
>
> Let me know what you think. Between this organization for components and 
> Fluorine for config (https://github.com/reborg/fluorine/), I’m a happier 
> Clojure dev these days :) 
>
> Renzo 
> @reborg

-- 
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: Processing an array

2016-04-25 Thread Derek Troy-West
Hey Olivier,

 You can shorten the body of your function with nil-punning and in lining 
next-time (rather than explicitly letting it), e.g:

(if (empty? events)
timed-events
(let [current (first events)
  next-time (+ (:duration current) time)]
(recur next-time (conj timed-events (assoc current :time time)) 
(rest events)))

 To:

(if-let [current (first remaining)]
  (recur (conj (+ (:duration current) time) timed-events (assoc current 
:time time)) (rest events))
  timed-events)

As a style thing, you might choose to be explicit about the loop/recur, 
rather than having a multi-arity fn, e.g

(defn to-timed-events
  [events]
  (loop [result[]
remaining events
time  0]
(if-let [current (first remaining)]
  (recur (conj result (assoc current :time time)) (rest remaining) (+ 
(:duration current) time))
  result)))

 Derek


On Sunday, April 24, 2016 at 8:01:14 PM UTC+10, Olivier Scalbert wrote:
>
> Hi all,
>
> I am a Clojure beginner 
> And I have an advice to ask !
>
> I have an array of events:
>
> (def events [
>   {:id "1" :duration 100}
>   {:id "2" :duration 200}
>   {:id "3" :duration 300}
> ])
>
> I wanted to transform this array into:
> [
>   {:id 1, :duration 100, :time 0} ; event 1 starts at 0
>   {:id 2, :duration 200, :time 100} ; event 2 starts when event 1 is 
> finished, so at 100
>   {:id 3, :duration 300, :time 300} ; event 3 starts when event 2 is 
> finished, so at 100 + 200
> ]
>
> Here is the function code:
>
> (defn to-timed-events
> ([time events] (to-timed-events time [] events))
> ([time timed-events events]
> (if (empty? events)
> timed-events
> (let [current (first events)
>   next-time (+ (:duration current) time)]
> (recur next-time (conj timed-events (assoc current :time 
> time)) (rest events))
> 
>
> It seems to work, but it looks a bit long for what it is doing. Is it 
> possible to improve it ?
>
> Thanks for your help,
>
> Olivier
>

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


Leiningen, Release Me!

2016-04-15 Thread Derek Troy-West
I had a recent misadventure trying to configure Leiningen to sign releases 
and/or tags with a side-helping of a minor clash with Git Flow.

It turned out to be a convoluted process and I couldn't find a clear guide 
to my setup, which I assume is a fairly common one, so I wrote one:

http://derek.troywest.com/articles/leiningen-release

Ta,
 Derek


-- 
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: Protocols in another namespace, retract-type possible ?

2016-04-04 Thread Derek Troy-West
Hi Neils,

 If I've understood you correctly, can you just redefine the protocol 
implementation for Associative? E.g.

(defprotocol ProtX
  (do-thing [x]))
=> ProtX

(extend clojure.lang.Associative
  ProtX
  {:do-thing (fn [x] (str/lower-case (get x :a-val)))})
=> nil

(do-thing {:a-val "Some String"})
=> "some string"

(extend clojure.lang.Associative
  ProtX
  {:do-thing (fn [x] (str/upper-case (get x :a-val)))})
=> nil

(do-thing {:a-val "Some String"})
=> "SOME STRING"


On Thursday, March 24, 2016 at 10:14:11 PM UTC+13, Niels van Klaveren wrote:
>
> In a project using clojure.java.jmx, I was extending it's Destract protocol 
> object->data function  to transform more of the JMX data structures 
> returned from calls or metadata queries into plain clojure data structures. 
> When I was done with the individual data structures, it should have been 
> possible to do a (walk/prewalk jmx/objects->data (jmx/operations 
> "java.lang:type=Threading")).
>
> However, in the Destract protocol there's an implementation of the 
> objects->data function for the type clojure.lang.Associative that would 
> mean maps would be processed incorrectly. I could add an implementation for 
> clojure.lang.IPersistentMap in my namespace, but since 
> clojure.lang.Associative is also an interface for maps this would not 
> work, and I ended up having to fork clojure.java.jmx because of it. If 
> there would be  a way to retract a protocol for a type within another 
> namespace I wouldn't have had to. Is there such a way, or would it even be 
> feasible to implement something like it?
>

-- 
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: Advice on introducing a Java dev to Clojure

2016-02-10 Thread Derek Troy-West
Hi Johanna,

 You could try the angle that a Clojure REPL is a practical adjunct to 
standard Java tooling, particularly if the developer is using IntelliJ 
since Cursive is extremely accessible.
 
 I wrote something along these 
lines: http://derek.troywest.com/articles/proximity-and-brevity.
 
 This thread is a little old, so I have to ask - have you had any luck?

Derek

On Friday, July 10, 2015 at 8:20:23 AM UTC+10, Johanna Belanger wrote:
>
> Hi :)
>
> I've recently broached the subject of Clojure with another dev in my 
> organization, and his response was basically "What's Clojure"? and I'm not 
> sure how to answer that in a way that might inspire him. "It's a 
> dynamically-typed functional Lisp with persistent immutable data structures 
> that runs on the JVM" doesn't seem like it will grab his interest. =)
>
> I work primarily in .NET, and he does enterprise Java. I don't know him 
> well enough to know how happy he is with it. He did express interest in 
> learning .Net.
>
>  I came to an appreciation of Clojure through 
>
> -CQRS (the power of decomplection!)
> -Sussman and Abelson's SICP class at MIT online (the power of 
> homoiconicity and functions!)
> -the death of Silverlight (alternatives to Javascript in the browser?)
>
> By the time I found Rich Hickey's talks (eg Simple Made Easy) I was pretty 
> well primed to love Clojure. I've been using it for little personal 
> projects and prototyping for a couple of years, but I haven't put it in 
> production because no one else here knows it.
>
> Could anyone tell me how they got from enterprise Java to Clojure?
>
> Thanks very much,
> Johanna
>
>

-- 
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: Examples of core.async usage in production?

2015-11-09 Thread Derek Troy-West
We have a number of back-end services which use core.async fairly 
extensively, some of which have been in production for over a year.

They tend to utilise Netty (Java non-blocking networking framework) to 
serve/send requests, for example Alia (https://github.com/mpenet/alia) is 
an excellent Cassandra client which provides a core.async interface.

On Tuesday, October 27, 2015 at 3:26:19 AM UTC+11, juan.facorro wrote:
>
> Hi all,
>
> From what I've seen/heard/understand core.async has been mostly used in 
> production on the *client side* or UI programming, since it frees us from 
> the dreaded callback hell. There are some instances where *core.async* is 
> used on the *server side* to provide asynchronous communication between 
> client and server [1][2]; and I wonder how many are using those 
> libraries/features and how. 
>
> I'm sure there are a lot more libraries built on top of *core.async* to 
> be used on the server, but my question/survey is related to *how many of 
> those are used in production today*. I have also found some comments 
> about using Pulsar  as an 
> alternative for asynchronous message passing scenarios [3][4]. How many of 
> you have gone that way instead?
>
> Looking forward to your comments & replies.
>
> Cheers!
> Juan
>
> [1] https://github.com/ptaoussanis/sente
> [2] https://github.com/bguthrie/async-sockets
> [3] https://groups.google.com/d/msg/clojure/m6bqGd8vQZQ/hR5rxE4oHSMJ
> [4] 
> http://stackoverflow.com/questions/32299299/is-it-safe-to-use-clojure-core-async-in-production-even-though-its-alpha
>

-- 
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] core.async-0.2.371

2015-10-29 Thread Derek Troy-West

>
>  
>
>> Secondly, I've perhaps mistakenly considered channels more as a conduit 
>> between processes rather than a replacement for single assignment message 
>> passing. I get the value of using a channel and the core.async state 
>> machine for achieving promise-like semantics in a non-blocking way, and I 
>> can achieve that for a single consumer with a normal channel, the rub is 
>> this new buffer allows repeated consumption of a single value, and my 
>> previous understanding of channel semantics 'a channel will return nil when 
>> it is closed after some number of takes' no longer holds in all cases, 
>> because a promise-buffer is never exhausted.
>>
>
> Nothing about channels guarantees they will be closed after some number of 
> takes, so I disagree with this definition.
>

To be clear, I didn't mean that a channel is guaranteed to be closed, 
rather that previously I could count on the ability to drain a channel 
after I have chosen to close it. Closing a promise-chan which has received 
a value has no impact on later takes, it is indistinguishable from a 
channel with an infinite buffer filled with a single value, which feels 
like a deviation from the thought that unbounded buffers are bad. The 
example in my previous message will OOM when used with a promise-chan.

This new behaviour doesn't directly contradict the close! dosctring - "Data 
in the channel remains available for taking, until exhausted, after which 
takes will return nil", but that description could leave you with the 
expectation that data is exhausted.

I guess I'm trying to understand if this new channel type is intended to be 
used with the battery of existing channel macros (pipe, reduce, pipeline, 
mult, etc.), where it may act as an unbounded, uncloseable producer of 
values, or if it's really only intended to be used as a promise which can 
be resolved in a non-blocking manner using put, take, >!, , !!<.

If it's the latter, would it make sense to rename promise-chan to promise, 
i.e. a core.async promise type who's implementation happens to be a 
channel, and expand only those macros relating to puts and takes to accept 
chan-or-promise.

Thanks again.

-- 
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] core.async-0.2.371

2015-10-29 Thread Derek Troy-West
Thanks Alex, I think I can sum up my confusion as: I thought channels were
single take, but understand now that is not necessarily the case.

In his 2013 Strange Loop talk Rich described first-class channels and the
subset of state that they expose:

"But I think what's really cool about first class channels is that they
expose a subset of state, and it's a very interesting and far safer one,
which I'll call flow state, right, which is just about all you can do with
this kind of state is put stuff in it, and then you really don't know
anything more about it. Or you can take stuff out of it, and you really
don't know how it got there."

In particular he drew an analogy that really resonated with me,
shared-state=coat-hook, flow-state=conveyor-belt.

"It's going to go on a conveyor belt. It's going to, you know, somewhere
else. It's going to go down that chute and you can't recover it. The UPS
truck is going to drive away. And that's good because you can't possibly
have your life depend on going back and seeing the same thing there again.
So it's not really like state the way shared state and place oriented state
is. Flow state is much simpler. It's much easier to reason about and much
safer because you do not have this expectation of coming back"

Understanding the limitations of analogies, does this new channel adhere to
that concept of flow-state? Is it a conveyor-belt or a coat-hook? Apologies
if the concept of what state a channel exposes has been updated since then
and I've missed the point. I found that particular analogy a powerful one
when trying to understand channels so perhaps that's why I'm hung up on it.

-
https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/CoreAsync.md

On Fri, Oct 30, 2015 at 10:10 AM, Alex Miller  wrote:

> To be clear, I didn't mean that a channel is guaranteed to be closed,
>> rather that previously I could count on the ability to drain a channel
>> after I have chosen to close it. Closing a promise-chan which has received
>> a value has no impact on later takes, it is indistinguishable from a
>> channel with an infinite buffer filled with a single value, which feels
>> like a deviation from the thought that unbounded buffers are bad. The
>> example in my previous message will OOM when used with a promise-chan.
>>
>
> The buffer is not unbounded - it is of size 1.
>
>
>> This new behaviour doesn't directly contradict the close! dosctring -
>> "Data in the channel remains available for taking, until exhausted, after
>> which takes will return nil", but that description could leave you with the
>> expectation that data is exhausted.
>>
>> I guess I'm trying to understand if this new channel type is intended to
>> be used with the battery of existing channel macros (pipe, reduce,
>> pipeline, mult, etc.), where it may act as an unbounded, uncloseable
>> producer of values, or if it's really only intended to be used as a promise
>> which can be resolved in a non-blocking manner using put, take, >!, > !!>, !!<.
>>
>
> It is primarily useful as a promise, but it can be useful to combine it
> with other channel ops with alts etc. But there may be other use cases
> where it's useful.
>
>
>> If it's the latter, would it make sense to rename promise-chan to
>> promise, i.e. a core.async promise type who's implementation happens to be
>> a channel, and expand only those macros relating to puts and takes to
>> accept chan-or-promise.
>>
>
> We are not going to change the name - it is a channel with promise
> semantics.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/NdQMUs1mTUU/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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

Re: [ANN] core.async-0.2.371

2015-10-29 Thread Derek Troy-West
Hi Alex, thanks for your efforts and the update.

I have a few questions about promise-chan if you have a moment.

Firstly, why provide promise-chan rather than requiring (chan 
(buffers/promise)). The buffer provides the promise semantics and we don't 
similarly have sliding-chan, dropping-chan, etc. Is this an effort to 
delineate channels with promise-buffers from the vanilla variety?

Secondly, I've perhaps mistakenly considered channels more as a conduit 
between processes rather than a replacement for single assignment message 
passing. I get the value of using a channel and the core.async state 
machine for achieving promise-like semantics in a non-blocking way, and I 
can achieve that for a single consumer with a normal channel, the rub is 
this new buffer allows repeated consumption of a single value, and my 
previous understanding of channel semantics 'a channel will return nil when 
it is closed after some number of takes' no longer holds in all cases, 
because a promise-buffer is never exhausted.

Practically I'm sure I'll always be aware of the buffer-flavour of a 
channel that I'm using, but now we have a variety of channels for which 
many channel operations do not make sense, i.e.:

(async/go
  (prn "result" (async/
> I am happy to announce a long-overdue core.async release.
>
> Dependency info:  [org.clojure/core.async "0.2.371"]
>
> There are a few new features in this release:
>
> 1) *promise-chan* is a function that returns a new kind of channel (with 
> a custom buffer) with promise semantics. Specifically, channels make a 
> one-time transition to having a deliverable value. *promise-chan* takes 
> an optional transducer, and an optional exception-handler (like chan). A 
> promise channel can take exactly one value that consumers will receive. 
> Once full, puts complete but val is dropped (no transfer).
> Consumers will block until either a value is placed in the channel or the 
> channel is closed (and nil will be delivered). 
>
> 2) *offer!* and *poll!* are two new non-blocking functions available on 
> channels.
>
> offer! puts a val into a channel if it can do so immediately and will 
> never block. Returns true if offer succeeds.
> poll! takes a val from a channel if it can do so immediately and will 
> never block. Return a value if successful, nil otherwise.
>
> All changes:
>
>- ASYNC-103  - NEW 
>promise-chan
>- ASYNC-104  - NEW 
>non-blocking offer!, poll!
>- ASYNC-124  - dispatch 
>multiple pending takers resulting from expanding transducer
>- ASYNC-101  - 
>async/reduce now respects reduced
>- ASYNC-112  - replace 
>"transformer" with "transducer" in deprecation messages
>- ASYNC-6  - alts! docs 
>updated to explicitly state ports is a vector
>- Support (try (catch :default)) in CLJS exception handling
>- Use cljs.test
>- Updated tools.analyzer.jvm version (and other upstream deps) - fixes 
>various analyzer errors
>
>
>

-- 
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: Minimum Viable Database Component

2015-04-30 Thread Derek Troy-West
Hi Andy, 

 We use component at SMX, and do follow an approach similar to the one you 
hint at but as Stuart suggests we tend to have protocols that are more 
application-centric.
 
 For instance, we use Cassandra extensively and our general interaction 
with that is captured by the protocol:

(defprotocol Connection
  (bind [this stmt vals] bind values to a prepared statement)
  (prepare [this query] provide a prepared statement from a query)
  (execute [this stmt] [this stmt opts] execute a query or statement)
  (execute-batch [this stmts] [this stmts opts] execute a batch of 
statements)

That isn't an attempt to create an abstraction of Cassandra, it captures 
one way in which a number of our applications use Cassandra.

In certain test cases that allows us to use a stub-component which returns 
canned responses, in other cases we integrate with a test Cassandra 
cluster, both have merits.

One further advantage is this protocol would allow us to swap the 
underlying implementation (which is currently based on Alia 
- https://github.com/mpenet/alia) with something else if we ever wanted to 
without impacting consumers of that protocol. That wasn't the driver for it 
though, stubbed tests was.



On Thursday, April 30, 2015 at 1:54:38 PM UTC+10, Andy Chambers wrote:

 Hi All,

 I'm trying to follow the component architecture for an app I'm working 
 on and wondered if I was missing something. In the Just enough structure 
 talk, one of the examples Stuart presents is a DB component that contains 
 just a small selection of DB related functions (i.e. insert, and query 
 IIRC) so that when you need to mock it out for your tests, you don't have 
 to implement the entire JDBC interface.

 This makes sense but I'm wondering if anyone has released such a subset 
 (possibly expanded to include things like transactions, and maybe a few 
 utility query builders) as open source ideally with a corresponding mock 
 implementation. With the popularity of the component library, I'm surprised 
 not to find ready made components I can just plug into my app.

 If there's nothing like this already, then I guess I have an idea for a 
 new project. Anyone think this is a good idea or would everyone's ideal DB 
 component look a little different? Look forward to hearing your thoughts.

 Cheers,
 Andy


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


core.async chan ex-handler

2015-01-22 Thread Derek Troy-West
From the documentation:

(chan buf-or-n xform ex-handler)

If a transducer is supplied a
buffer must be specified. ex-handler must be a fn of one argument -
if an exception occurs during transformation it will be called with
the Throwable as an argument


Is there a reason the ex-handler fn doesn't have a second arity which also 
takes the val which caused the transformation error?


Ta,

 Derek


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