Re: partition-all in clojure.core.asyncn channel does not work

2017-12-06 Thread Ray Miller
On 6 December 2017 at 11:23, Jacek Grzebyta  wrote:
>
> I have to populate a triple store with a big number of data (~38k records
> x 12) and there is a deadly narrow bottleneck - IO operations speed. To fix
> it I did:
> 1. To avoid threads overflow I put all compute results into channel.
> 2. Loading data in chunks is better than single transaction for single
> record
>
> I tried to do by creating channel with poputale-all traversal but it seems
> doesn't work properly. In the following mock example it works when the
> chunk size is  equal the data vector (i.e. 6): "value:  [of made is fruit
> soup Berry]" - for now I do not care the order.
>
> (let [q (a/chan 500 (partition-all 6))
>   in ["Berry" "soup" "is" "made" "of" "fruit"]]
>   (a/go-loop [j (a/ (when j
>   (println "value: " j)
>   (recur (a/   (doseq [itm in]
> (a/go (a/>! q itm
>
>
> I cannot see any problem. How can I solve it? In the following example
> chunk size should be max 6? I expected partition-all will work the same way
> as itself:
>
> (partition-all 5 ["Berry" "soup" "is" "made" "of" "fruit"]) ==>
> (("Berry" "soup" "is" "made" "of") ("fruit"))
>
>
I think you just need to close the channel when you've finished populating
it:

(let [q (a/chan 500 (partition-all 5))
  in ["Berry" "soup" "is" "made" "of" "fruit"]]
  (a/go-loop [j (a/! q itm))
(a/close! q)))

-- 
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: Lazy Flatten; One seq at a Time

2017-11-24 Thread Ray Miller
If I've understood your problem correctly, clojure.core/lazy-cat does
exactly what you need.

Ray.

On 22 November 2017 at 22:31, Stephen Nelson  wrote:

> ```
> (->> (repeatedly
>(fn []
>  (lazy-seq
>(println "New seq...")
>(map (fn [x] + x (rand-int 10)) (range 4)
>  (apply concat)
>  (take 1))
> New seq...
> => (3)
> ```
>
> Lazy-flatten is unnecessary because concat already does what you want –
> the generalised problem you're running in to is that function arguments are
> eagerly realised. In your case, your use of concat realises the first two
> seqs, in my example, `apply` realises the first four elements (see the
> implementation of apply).
>
> If you wrap the seq generator in `lazy-seq` you can delay the realisation
> of the 'expensive' inner sequence until concat reaches that list. In
> implementation terms, lazy-seq is a macro returns a thunk that will delay
> the println (and the sequence generation) until it's required by concat.
>
> On Thu, Nov 23, 2017 at 2:32 AM Matt Anderson 
> wrote:
>
>> Thanks! The `aconcat` solution from plumbing works great for this use
>> case.
>>
>> The `lazy-gen`/`yield` fn's in Tupelo are exactly what I was searching
>> for in terms of a larger abstraction, but couldn't quite put into words.
>> Thanks for the tip!
>>
>>
>>
>> On Wednesday, November 22, 2017 at 2:36:18 AM UTC-5, Alan Thompson wrote:
>>
>>> You can also solve this using `lazy-gen` and `yield-all` from the
>>> Tupelo library
>>> .
>>> It allows you to make
>>> a lazy generator function (a la Python):
>>>
>>>   (let [seq-of-seqs [(range  0  5)
>>>  (range 10 15)
>>>  (range 20 25)]
>>> flat-seq(lazy-gen
>>>   (doseq [curr-seq seq-of-seqs]
>>> (yield-all curr-seq)))]
>>> (is= flat-seq [0 1 2 3 4 10 11 12 13 14 20 21 22 23 24]))
>>>
>>>
>>> Alan
>>>
>>> On Tue, Nov 21, 2017 at 4:47 PM, Jason Wolfe  wrote:
>>>
>> I think this
 
 will do it:

 (lazy-cat (first coll) (when-let [n (next coll)] (lazy-flatten n


 On Tuesday, November 21, 2017 at 2:34:15 PM UTC-8, Matt Anderson wrote:
>
> I have a function that is returning a lazy-seq of lazy-seq's.
>
>
> (seq (seq [1 2 3]) (seq [4 5 6]) ...)
>
>
> The end-user API, however, should be able to get back a lazy-seq of
> the individual items across all lazy-seq's--essentially a flattening of 
> the
> output of my function--instead of the "top level" seqs.
>
>
> (seq [1 2 3 4 5 6 ...])
>
> Each of the internal lazy-seq's is expensive in terms of memory usage
> so I'd like to only "load" one at a time.  I've been trying to find a way
> to only calculate one of the top-level lazy-seq's at a time and then not
> "take" the next until the user gets to the end of the first and needs the
> first item from the next (eg: (seq [4 5 6]) doesn't get calculated until 
> we
> have consumed 3 and are asking for the next), but haven't found a way to 
> do
> it. Best I've gotten is "loading" 2 "top level" seqs at a time and I'm
> afraid that may be the best I get, but I thought it might be an exercise
> worth presenting in case anyone had ideas. Here's a contrived example:
>
>
> (defn lazy-flatten
>
>  [coll]
>
>  (when-let [s (seq coll)]
>
>(lazy-seq
>
>  (if (seq? (first s))
>
>(concat (lazy-flatten (first s)) (lazy-flatten (rest s)))
>
>(cons (first s) (lazy-flatten (rest s)))
>
> (->> (repeatedly
>(fn []
>  (println "New seq...")
>  (map (fn [x] + x (rand-int 10)) (range 4
>  lazy-flatten
>  (take 1))
>
>
>
> Prints:
>
>
> New seq...
>
> New seq...
>
> => (8)
>
>
> I realize this is because 2 items must be taken for "concat", so there
> would need to be another approach (this was just my best shot
> implementation).
>
>
> Any ideas on how to get the bottom form to only print 1 "New seq..."?
>
 --
 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

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

>>>
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 ---
 You received this message because 

Clojure for big data

2017-10-18 Thread Ray Miller
Hi,

Here at Metail we have been using Clojure for medium-sized data processing
on AWS EMR. We started out with Cascalog about 5 years ago, switched to
Parkour 2 years ago, and are now considering a move to Spark.

My question is: is Clojure still a good choice for medium/large data
processing on EMR?

This is partly prompted by the lack of activity on the Github repos. Are
the Parkour, Flambo and Sparkling libraries rock solid, or simply not
getting enough use to trigger bugs and feature requests?

The #bigdata channel over on Clojurians slack is also suspiciously quiet,
as are many of the Google groups.

Ray.

-- 
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: Starting Clojure again

2017-09-06 Thread Ray Miller
On 6 September 2017 at 11:01, Cecil Westerhof 
wrote:

> ​With the help of this list I rewrote it to:
> (def digits
>  (apply str (map char (range (int \0) (inc (int \9))
> (def hex-digits
>  (apply str digits (map char (range (int \A) (inc (int \F))
>
> (defn create-pin
>   ([] (create-pin 8))
>   ([n]
>{:pre [(<= n 16)
>(>= n 4)]}
>(reduce str (repeatedly n #(rand-nth digits)
>
> (defn create-pin-hex
>   ([] (create-pin-hex 8))
>   ([n]
>{:pre [(<= n 16)
>(>= n 4)]}
>(reduce str (repeatedly n #(rand-nth hex-digits)
>
> Indention is not great: I have to find out how to modify emacs for it.
> ​
> By the way does has clojure something like super? Using:
> (defn create-pin-hex
>   ([] (create-pin-hex 8))
>
> is asking for trouble. After copy/pasting from create-pin I almost forgot
> to change it.
>
>
If your base function takes chars as its first argument, you can use
partial:

 (defn create-pin-base
  ([chars]
   (create-pin chars 8))
  ([chars n]
   {:pre [(<= 4 n 16)]}
   (apply str (repeatedly n #(rand-nth chars)

(def create-pin (partial create-pin-base digits))
(def create-pin-hex (partial create-pin-base hex-digits))

-- 
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: Starting Clojure again

2017-09-06 Thread Ray Miller
On 6 September 2017 at 09:50, Cecil Westerhof 
wrote:

>
> ​I am trying the following throwaway code:
> (defn create-pin
>   ([] (create-pin 8))
>   ([n]
>{:pre [(<= n 128)
>(>= n 4)]}
>(let [chars (into [] (concat (range (int \0) (inc (int \9))) (range
> (int \A) (inc (int \F)]
> (println chars)
> (reduce str (repeatedly n #(rand-nth chars))
>
> When calling:
> (create-pin 100)
>
> I get:
> [48 49 50 51 52 53 54 55 56 57 65 66 67 68 69 70]
> "51536767526968546665516749515149494848515665705749516870
> 675155706548684865546767695170695066514869707065676954675548
> 665154655470686969555069685167705468495368666948535649515452
> 66554857545648515454"
> ​
> ​So it looks like chars is filled correctly, but it only uses 0-9 and not
> A-F. So what am I doing wrong?​
>

The variable you call "chars" is actually a vector of integers, so you are
selecting random integers and joining them together into a string. You
could try:

(let [chars (mapv char (concat (range (int \0) (inc (int \9))) (range (int
\A) (inc (int \F)]
 ...)

Ray.

-- 
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: Deploying multiple Clojure apps on one server using Reagent, Nginx, and Supervisor (Solved)

2017-01-07 Thread Ray Miller
If you're using ring, you can use the lein-ring plugin to build the
uberwar: simply `lein ring uberwar`. Check out the README for options if
you need to deviate from the defaults:
https://github.com/weavejester/lein-ring

You'll end up with an uberwar for each application you want to deploy.
These have to be deployed to a servlet container; there are several options
here, but jetty is a popular choice. This tutorial looks helpful:
https://github.com/ddellacosta/Clojure-under-Jetty-and-Apache

On 7 January 2017 at 00:01, Seth Archambault  wrote:

> Thanks! Sounds like multiple war files would be the right way for me.
> Unfortunately, I'm falling into the original problem with finding
> information on how to do this...
>
> Got any links to articles on how to do this?
> Thanks!
>
>
> On Tuesday, January 3, 2017 at 7:12:54 PM UTC-5, Sean Corfield wrote:
>>
>> 1GB is certainly pretty small for the JVM world, if you’re thinking of
>> running multiple apps / sites as separate JVM processes.
>>
>>
>>
>> However, there are several ways around that.
>>
>>
>>
>> It’s common in the JVM world to have a single “web server” process load
>> and run multiple “web applications”. A servlet container (Tomcat, Jetty,
>> JBoss…) runs multiple apps each packaged as a WAR file (a zip file with
>> some additional metadata).
>>
>>
>>
>> Another option is to package multiple applications into one uberjar and
>> start up multiple apps on different ports directly inside your own code, or
>> you could use a single app with middleware that selects a different set of
>> routes for each different domain / port / however you distinguish between
>> your apps externally.
>>
>>
>>
>> Bottom line: having each app as a separate uberjar, spinning up in a
>> separate JVM isn’t the most scalable way of running multiple apps on a
>> single server.
>>
>>
>>
>> For comparison, at World Singles, we have about 100 sites running on (a
>> cluster of instances of) a single web application under the hood. The
>> domain being requested determines how the request is handled – in our case
>> the skin and theme of each site, along with a lot of other metadata, is all
>> dynamic and based on the domain name. Our sites are similar enough that
>> this is possible. That’s for the main customer-facing sites. We also have
>> an affiliate web site and an internal admin web site. Those three codebases
>> are each, essentially, a WAR-based app and all three can run on a single
>> Tomcat instance (on each server in the cluster). We run a single JVM with
>> 10GB heap configured for Tomcat on each of a cluster of servers, each with
>> 64GB RAM (our database servers are in a separate cluster and have 128GB RAM
>> each, I believe).
>>
>>
>>
>> Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
>> An Architect's View -- http://corfield.org/
>>
>> "If you're not annoying somebody, you're not really alive."
>> -- Margaret Atwood
>>
>>
>>
>> On 1/3/17, 2:16 PM, "Seth Archambault" > behalf of seth...@gmail.com> wrote:
>>
>>
>>
>> Haha thanks for pointing that out - I mispoke - 1024 mb of ram - 1 gig of
>> ram. Using a $10 a month Vultr account. 1000 gigs would be a tad expensive!
>>
>> On Monday, January 2, 2017 at 8:27:19 PM UTC-5, William la Forge wrote:
>>
>> Seth, something seems amiss. 1,000 GB is 1,000,000 MB. At 84 mb per jar,
>> you can spin up 11,904 jar files. Which is worse than only being able to
>> run only dozens of PHP apps.
>>
>>
>>
>> --b
>>
>> --
>> 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
>> 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
>> 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.
>> 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 

Problem with buddy.core.keys/private-key in uberjar

2016-12-21 Thread Ray Miller
Hi,

I ran into a problem reading a private key from a file using buddy-core
version 1.1.1. I created a private key using:

openssl genrsa -aes256 -out resources/auth_privkey.pem 2048

Here's the code:

(ns tryme-buddy.core
  (:require [buddy.core.keys :as ks]
[clojure.java.io :as io])
  (:gen-class))

(defn read-key
  []
  (ks/private-key (io/resource "auth_privkey.pem") "secret"))

(defn -main
  [& args]
  (read-key)
  (println "OK"))

This works as expected when invoked with `lein run`, but if I create an
uberjar with `lein do clean, uberjar` and invoke with `java -jar ...` I get
the following exception:

Exception in thread "main" org.bouncycastle.openssl.PEMException: Unable to
create OpenSSL PBDKF: PBKDF-OpenSSL SecretKeyFactory not available
at org.bouncycastle.openssl.jcajce.PEMUtilities.getKey(Unknown Source)
at org.bouncycastle.openssl.jcajce.PEMUtilities.getKey(Unknown Source)
at org.bouncycastle.openssl.jcajce.PEMUtilities.crypt(Unknown Source)
at
org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder$1$1.decrypt(Unknown
Source)
at org.bouncycastle.openssl.PEMEncryptedKeyPair.decryptKeyPair(Unknown
Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
at buddy.core.keys$read_pem__GT_privkey.invokeStatic(keys.clj:60)
at buddy.core.keys$read_pem__GT_privkey.invoke(keys.clj:51)
at buddy.core.keys$private_key.invokeStatic(keys.clj:96)
at buddy.core.keys$private_key.invoke(keys.clj:91)
at tryme_buddy.core$read_key.invokeStatic(core.clj:8)
at tryme_buddy.core$read_key.invoke(core.clj:6)
at tryme_buddy.core$_main.invokeStatic(core.clj:12)
at tryme_buddy.core$_main.doInvoke(core.clj:10)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at tryme_buddy.core.main(Unknown Source)
Caused by: java.security.NoSuchAlgorithmException: PBKDF-OpenSSL
SecretKeyFactory not available
 at javax.crypto.SecretKeyFactory. (SecretKeyFactory.java:122)
javax.crypto.SecretKeyFactory.getInstance (SecretKeyFactory.java:160)
org.bouncycastle.jcajce.util.DefaultJcaJceHelper.createSecretKeyFactory
(:-1) org.bouncycastle.openssl.jcajce.PEMUtilities.getKey (:-1)
org.bouncycastle.openssl.jcajce.PEMUtilities.getKey (:-1)
org.bouncycastle.openssl.jcajce.PEMUtilities.crypt (:-1)
org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder$1$1.decrypt
(:-1) org.bouncycastle.openssl.PEMEncryptedKeyPair.decryptKeyPair (:-1)
sun.reflect.NativeMethodAccessorImpl.invoke0
(NativeMethodAccessorImpl.java:-2)
sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke
(Method.java:498) clojure.lang.Reflector.invokeMatchingMethod
(Reflector.java:93) clojure.lang.Reflector.invokeInstanceMethod
(Reflector.java:28) buddy.core.keys$read_pem__GT_privkey.invokeStatic
(keys.clj:60) buddy.core.keys$read_pem__GT_privkey.invoke (keys.clj:51)
buddy.core.keys$private_key.invokeStatic (keys.clj:96)
buddy.core.keys$private_key.invoke (keys.clj:91)
tryme_buddy.core$read_key.invokeStatic (core.clj:13)
tryme_buddy.core$read_key.invoke (core.clj:11)
tryme_buddy.core$_main$fn__109.invoke (core.clj:19)
tryme_buddy.core$_main.invokeStatic (core.clj:18)
tryme_buddy.core$_main.doInvoke (core.clj:15) clojure.lang.RestFn.invoke
(RestFn.java:397) clojure.lang.AFn.applyToHelper (AFn.java:152)
clojure.lang.RestFn.applyTo (RestFn.java:132) tryme_buddy.core.main (:-1)

What do I need to do to create a working uberjar?

Ray.

-- 
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: Is Pallet abandoned? Alternatives?

2016-09-30 Thread Ray Miller
I also got excited about pallet a year or so ago. There are some awesome
ideas in there, but I found that in practice it was slow to develop with
and much less flexible than it promised. In the end I switched to ansible
and achieved more in 1 day than I had in a week's effort with pallet. I
think the main problem is the small user base. The more mainstream
solutions in this space have better documentation and are better tested in
the wild. There's a much better chance you'll find someone else has already
done the thing you're trying to do, so you will either find a module to do
the work or an example to help you along.

Ray.

On 30 September 2016 at 03:38, Miroslav Kubíček 
wrote:

> Hi there,
> I just got super excited about Pallet only to find out that the last
> commit was 3 years ago and that it is not being actively maintained (using
> now old version of jCoulds etc.).
> Are there any alternatives that would work well with Clojure paradigm?
>
> Or are my options only to either go with chef/puppet or to fork pallet? I
> am also interested to hear what works for people and what not so much.
>
> Thanks!
> Miro
>
> --
> 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: Macro usage within Clojure community and naming functions which perform actions under certain conditions

2016-04-26 Thread Ray Miller
On 25 April 2016 at 21:03, Rafał Cieślak  wrote:

> Hi,
>
> I'm writing a turn-based game and one of the biggest functions is the one
> which handles player moves. It receives the current game state (a map) and
> the index of the cell that the player clicked on (an integer).
>
> It has to make a couple of decisions based on the game state. So far I
> just used -> and cond->. The code looks more or less like this, I removed
> a bunch of function calls for brevity.
>
> (-> game-state
> ; This stuff happens on each move.
> (reveal-cell cell-index)
> ; And this stuff happens only under certain conditions.
> (cond->
>   (zero? (:surrounding-power cell))
>   (reveal-safe-cells cell-index)))
>
> The code looks clear IMHO. But then I wanted to add another feature which
> requires me to make decisions based on the updated value of game-state
> (the one that is being threaded inside cond->).
>
> I thought about cond-> a bit and came to the conclusion that the reason
> you can't access the currently threaded value is to keep you from writing
> order-dependent statements. But in my case, I sometimes do want to write
> order-dependent code. For example, I want to give player exp for killing a
> monster and then if the exp is above certain threshold, I want to level up
> his character.
>
> So the problem is that I have to check the current value being threaded,
> but cond-> doesn't allow me to do that.
>
>
You don't need a macro for this sort of thing, and can get some way with
reduce. For example:

(defn apply-conditional-actions
  [game-state & pred-actions]
  (reduce (fn [game-state [pred action]]
(if (pred game-state)
  (action game-state)
  game-state))
  game-state
  (partition 2 pred-actions)))

Then call this function with the game-state and a list of pred/action pairs:

(apply-conditional-actions game-state
   safe-cell? reveal-safe-cells
   monster-killed? inc-exp-points)

-- 
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: best practice with forked libraries

2015-11-17 Thread Ray Miller
On 17 November 2015 at 13:21, Bobby Bobble  wrote:

> Say there's a dependency that I fork and add some features I need for my
> team's project. I can use my fork locally with lein install no problem, and
> so can others *if* they clone my fork and do the same. It would be more
> convenient if I could publish my fork to Clojars and depend on that, and
> maybe down the line I can return to depending on the original if my PR is
> accepted. What's the best thing to do here ?
>

There's a convention in Clojars of deploying a non-canonical fork by
renaming the project to org.clojars.USERNAME/PROJ_NAME and deploying that
to Clojars.

See, for example: https://clojars.org/search?q=clj-aws-s3

-- 
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.cache limits?

2015-11-03 Thread Ray Miller
On 3 November 2015 at 01:23, William la Forge  wrote:

> There was just so much more there than I had ever dreamed. I had looked at
> destructuring, but had been unaware of the various directives. :D
>
> I found this post by Jay Fields a useful resource for learning about
destructuring:

http://blog.jayfields.com/2010/07/clojure-destructuring.html

-- 
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: newbie Q: where is isSymbolicLink function and how to access it ?

2015-10-05 Thread Ray Miller
You need Java interop for this:

(import 'java.nio,file.Files)

(Files/isSymbolicLink (.toPath (io/file "/some/path")))

See http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html
for the other methods provided by this class.

On 5 October 2015 at 16:47,   wrote:
>
> In the clojure.java.io  there are these two functions:
> isDirectory
> isFile
>
> But there is no isSymbolicLink (for unix, linux).
>
> (1) Could someone tell me where I can find such a function ?
>  In another library not listed on clojure,org ??
>
> (2) What do I need to do in order to use it ?
>
> Thanks
> HP
>
> --
> 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: Code Review

2015-05-15 Thread Ray Miller
If I've understood the problem correctly, you can simplify the code by
implementing a transpose function:

(defn transpose [xs] (apply map vector xs))

Then define a wanted? function for filtering the lines you want to include:

(defn wanted? [xs] (some zero? xs))

...and a helper function to left-pad a vector with zeroes:

(defn lpad [n xs] (vec (concat (repeat (- n (count xs)) 0) xs)))

So your main function would look something like:

(defn process [xs] (let [n (count (first xs))] (vec (map (partial lpad
n) (transpose (filter wanted? (transpose xs)))

On 15 May 2015 at 09:01, Sven Richter sver...@googlemail.com wrote:
 HI,

 I just posted a question to stackoverflows code review
 page:http://codereview.stackexchange.com/questions/90809/remove-lines-from-a-2d-vec-in-clojure

 As there is not much traffic regarding clojure I also double post to this
 list in the hope to get some good answers. You might respond here or there,
 whatever you like best.

 I have some code here that I am very unhappy with. The task I am trying to
 accomplish is this.

 Given a 2d vec like this:

 [[0 2 0] [1 3 5] [3 3 0]]
 which can contain positive ints including zero I want to remove all _lines_
 that are greater zero.
 Whereas the definition of _line_ is the following:
 A _line_ is represented by the position n in every vec inside the 2d vec. So
 my example above has three lines:

 [0 1 3], [2 3 3] and [0 5 0].

 The line that I want to remove from it according to my algortihm is **[2 3
 3]** because every element is greater than zero.

 So my 2d vec would now look like this:

 [[0 0] [1 5] [3 0]]

 And finally I want to pad the vecs to their original size filling them with
 zero for every removed line, so that it looks finally like this:

 [[0 0 0] [0 1 5] [0 3 0]]

 This is what I came up with:

 (defn in?
   true if seq contains elm
   [seq elm]
   (some #(= elm %) seq))

 (defn not-in?
   true if seq does not contain elm
   [seq elm]
   (not (in? seq elm)))

 (defn all-greater-zero-at
   Given a 2-d vec [[0 1] [0 2]] return true if all elements at 'at' are
   greater than zero
   [v at]
   (not-in? (map #(if ( (nth % at) 0) true false) v) false))

 (defn to-be-removed
   Returns a seq of positions to be removed (0 3 4)
   [v width]
   (reduce (fn [a b] (if (all-greater-zero-at v b) (conj a b) a)) []
 (range width)))

 (defn remove-at
   Removes an element from a 1d vec
   [v at]
   (into [] (concat (subvec v 0 at) (subvec v (+ at 1) (count v)

 (defn insert-at
   inserts an element into a 1d vec
   [v elm at]
   (into [] (concat (subvec v 0 at) elm (subvec v at (count v)

 (defn remove-and-replace-all-at
   [v at]
   (map #(insert-at (remove-at % at) [0] at) v))

 (defn replace-full-by-zero [v width]
   (reduce (fn [a b] (remove-and-replace-all-at a b)) v (to-be-removed v
 width)))

 (defn remove-zeros [v at]
   (reduce (fn [a b] (conj a (remove-at b at))) [] v))

 (defn fill-with-zeros
   Takes a 2d vec and pads ith with zeros up to width
   [v width]
   (map #(into [] (concat (take (- width (count (first v))) (repeat 0))
 %)) v))

 (defn clean-grid
   removes all full lines
   [fbz tbr]
   (loop [acc fbz tbr tbr i 0]
 (if (empty? tbr)
   acc
   (recur (remove-zeros acc (- (first tbr) i)) (rest tbr) (inc i)

 (defn remove-full-lines [v width]
   (let [fbz (replace-full-by-zero v width)
 tbr (to-be-removed v width)
 cleaned-grid (clean-grid fbz tbr)]
 (into [] (fill-with-zeros cleaned-grid width

 This seems like a lot of code for such a simple algorithm and I assume
 there are a lot of better ways to do that, but just did not come up with a
 better one, so, please, go ahead and fix it, if you want to :-)

 Best Regards,
 Sven

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

Re: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn

2015-05-08 Thread Ray Miller
Looks like the exception is thrown during config parsing. You probably
need to enclose the email addresses in a vector [] rather than a list
().

Ray.

On 8 May 2015 at 08:01, Alexey Astafyev av.astaf...@gmail.com wrote:
 I'm new to Riemann and Clojure. All I want to do is to send email
 notifications to three email groups when some service's TTL is expired. I
 created some sort of config file where I store a list of emails:

 {
   :email_group_1 (
   fi...@example.com
   sec...@example.ru
  )
   :email_group_2 (
   th...@example.com
  )
 }


 My riemann config looks like this:

 (logging/init {:console true})
 (import org.apache.log4j.Level)
 (logging/set-level Level/DEBUG)

 (require '[clojure.java.io :as io])
 (import '[java.io PushbackReader])

 (let [host 0.0.0.0]
   (tcp-server {:host host :port 60001})
   (udp-server {:host host})
   (ws-server  {:host host :port 60003}))
 (repl-server  {:host 127.0.0.1})

 (def cwd (System/getProperty user.dir))

 (def emails
   (with-open [r (io/reader (str cwd /etc/emails.clj))]
  (read (PushbackReader. r

 (periodically-expire 5)

 (def email (mailer))

 (defn notify [ egroups]
   (for [egroup egroups]
 (rollup 1 60 (apply email (emails egroup)

 (let [index (index)]
   (streams
 (default :ttl 60
   index

   (expired
   (where (service service_connect_active)
 #(info expired %)
 (notify :email_group_1 :email_group_2))


 Code looks good (for me), but when this service is expired I get the
 following error:

 09:45:39 riemann.1  | INFO [2015-05-08 10:45:39,313] Thread-5 -
 riemann.config - expired {:ttl 60, :time 357766884827/250, :state expired,
 :service service_connect_active, :host ava.local}
 09:45:39 riemann.1  | WARN [2015-05-08 10:45:39,319] Thread-5 -
 riemann.config - clojure.lang.LazySeq@841649b8 threw
 09:45:39 riemann.1  | java.lang.ClassCastException: clojure.lang.LazySeq
 cannot be cast to clojure.lang.IFn
 09:45:39 riemann.1  |   at
 riemann.config$eval66$stream__70$fn__75.invoke(riemann.development.config:34)
 09:45:39 riemann.1  |   at
 riemann.config$eval66$stream__70.invoke(riemann.development.config:45)
 09:45:39 riemann.1  |   at
 riemann.streams$match$stream__3514$fn__3525.invoke(streams.clj:1209)
 09:45:39 riemann.1  |   at
 riemann.streams$match$stream__3514.invoke(streams.clj:1209)
 09:45:39 riemann.1  |   at
 riemann.streams$default$stream__3731$fn__3742.invoke(streams.clj:1328)
 09:45:39 riemann.1  |   at
 riemann.streams$default$stream__3731.invoke(streams.clj:1328)
 09:45:39 riemann.1  |   at
 riemann.core$stream_BANG_$fn__4415.invoke(core.clj:19)
 09:45:39 riemann.1  |   at riemann.core$stream_BANG_.invoke(core.clj:18)
 09:45:39 riemann.1  |   at
 riemann.core$reaper$worker__4529$fn__4539.invoke(core.clj:303)
 09:45:39 riemann.1  |   at
 riemann.core$reaper$worker__4529.invoke(core.clj:297)
 09:45:39 riemann.1  |   at
 riemann.service.ThreadService$thread_service_runner__1973$fn__1974.invoke(service.clj:71)
 09:45:39 riemann.1  |   at
 riemann.service.ThreadService$thread_service_runner__1973.invoke(service.clj:70)
 09:45:39 riemann.1  |   at clojure.lang.AFn.run(AFn.java:22)
 09:45:39 riemann.1  |   at java.lang.Thread.run(Thread.java:745)


 Could someone please help me? Thanks.

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

-- 
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: [OT?] Best DB/architecture for n-gram corpus?

2015-03-10 Thread Ray Miller
On 10 March 2015 at 20:03, Sam Raker sam.ra...@gmail.com wrote:
 That's honestly closer to what I was originally envisioning--I've never
 really looked into graph dbs before, but I'll check out Neo4j tonight. Do
 you know whether you can model multiple edges between the same nodes?

Yes, certainly possible.

If you go for Neo4j you have two options for Clojure: embedded (with
the borneo library and reading Javadoc, or plain Java interop) or
stand-alone server with REST API (with the well-documented Neocons
library from Clojurewerkz). You'll also have to think about how to
model which text (song) each phrase came from - likely another node
type in the graph with a linking edge to the start of the phrase.

Great book on Neo4j available for free download, also covers data
modelling: http://neo4j.com/books/

 I'd love to be able to have POS-based wildcarding as a feature, so you could
 search for e.g. the ADJ goose, but that's a whole other layer of stuff, so
 it might go in the eventually, maybe pile.

Sounds like fun, but means doing some natural language processing on
the input texts, which is a much more difficult problem than simply
tokenizing.

Ray.

-- 
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: [OT?] Best DB/architecture for n-gram corpus?

2015-03-10 Thread Ray Miller
On 10 March 2015 at 17:58, Sam Raker sam.ra...@gmail.com wrote:
 I more meant deciding on a maximum size and storing them qua ngrams--it
 seems limiting. On the other hand, after a certain size, they stop being
 ngrams and start being something else--texts, possibly.

Exactly. When I first read your post, I almost suggested you model
this in a graph database like Neo4j or Titan. Each word would be a
node in the graph with an edge linking it to the next word in the
sentence. You could define an index on the words (so retrieving all
nodes for a given word would be fast), then follow edges to find and
count particular n-grams. This is more complicated than the relational
model I proposed, and will be a bit slower to query. But if you don't
want to put an upper-bound on the length of the n-gram when you index
the data, it might be the way to go.

Ray.

-- 
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: [OT?] Best DB/architecture for n-gram corpus?

2015-03-07 Thread Ray Miller
On 7 March 2015 at 00:25, Sam Raker sam.ra...@gmail.com wrote:
 I'm trying to create an n-gram[1] corpus out of song lyrics. I'm breaking
 individual songs into lines,  which are then split into words, so you end up
 with something like

 {0 {0 go 1 tell 2 aunt 3 rhodie} 1 {0 the 1 old 2 grey 3
 goose 4 is 5 dead}...}

Why split into lines? In this example, rhodie the is just as valid a
bigram as tell aunt. It would be more natural to split at a sentence
boundary.

 (Yes, maps with integer keys is kind of dumb; I thought about using vectors,
 but this is all going into MongoDB temporarily, and I'd rather just deal
 with maps instead of messing with Mongo's somewhat lacking array-handling
 stuff.)

 The idea, ultimately, is to build a front-end that would allow users to,
 e.g., search for all songs that contain the (sub)string aunt rhodie, or
 see how many times The Rolling Stones use the word woman vs how many times
 the Beatles do, etc. The inspiration comes largely from projects like
 COCA[2].

 I'm wondering if any of you have opinions about which database to use (Mongo
 is most likely just a stopgap), and how best to architect it. I'm most
 familiar with MySQL and Mongo, but I'd rather not be limited by just those
 two if there's a better option out there.

First up, I think you'll likely want to trade space for speed, and the
simplest way to do this is to store every n-gram you're interested in.
This means deciding up-front the maximum size of the n-gram you're
interested in. You could fairly easily model this in any relational
database as:

tracks

id (serial, primary key)
name (text)

n_grams

id (serial, primary key)
n (integer)
n_gram (text)

track_n_gram
---
track (references tracks.id)
n_gram (references n_grams.id)
num_occurrences (integer)

With that schema, you should be able to answer all of the queries you
posed with some simple SQL.

Of course, this being the Clojure mailing list you should also
consider Datomic, and I think the above could be mapped to a Datomic
schema without too much effort.

Ray.

-- 
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 beginner: angst about doing things right

2014-09-22 Thread Ray Miller
A general rule of thumb is to prefer higher-order functions to explicit
recursion. When you are trying to accumulate something (here, you are
accumulating a list of zeroes and ones), you can usually use reduce. This
is a little bit more tricky here as you need to keep track of which bits of
the input string you have consumed as well as your accumulator:

(defn days-to-numbers
  [day-string]
  (first (reduce (fn [[accum day-string] day]
   (let [next-day-string (clojure.string/replace day-string
day )]
 [(conj accum (if (= day-string next-day-string) 0 1))
  next-day-string]))
 ['() day-string]
 [SU S F TH W T M])))

We'd have to work a bit harder if we weren't so lucky with the order the
two-character days appear above, as we *must* inspect the string for SU
before S and TH before T. But here we can get away with it.

Equivalently, but with an explicit loop/recur:

(defn days-to-numbers
  [day-string]
  (loop [day-string day-string days [SU S F TH W T M] accum
'()]
(if-let [day (first days)]
  (let [next-day-string (clojure.string/replace day-string day )]
(recur next-day-string
   (rest days)
   (conj accum (if (= day-string next-day-string) 0 1
  accum)))

Another note on your code, you'll commonly see the thread-first macro used
to avoid nested calls to functions like clojure.string/replace; if you
(require '[clojure.string :as str]) you could then write:

(- day-string (str/replace SU N) (str/replace TH R))

Ray.

On 22 September 2014 19:45, J David Eisenberg jdavid.eisenb...@gmail.com
wrote:

 As part of a larger program, I'm testing a function that will turn a
 string of days on which a class occurs (such as MWF) into a list of seven
 numbers: (1 0 1 0 1 0 0).
 I first translateTH (Thursday) to R and SU (Sunday) to N to make
 things a bit easier.

 I came up with the following code:

 (defn days-number-maker
   Recursively compare first item in days of week with
 first item in string of days. If matching, add a 1,
 else add a zero to the result
   [all-days day-string result]
   (if (empty? all-days) (reverse result)
 (if (= (first all-days) (first day-string))
   (recur (rest all-days)(rest day-string) (conj result 1))
   (recur (rest all-days) day-string (conj result 0)

 (defn days-to-numbers
   Change string like MTTH to (1 1 0 1 0 0 0)
   [day-string]
   (let [days (clojure.string/replace
(clojure.string/replace day-string #TH R) #SU N)]
 (days-number-maker MTWRFSN days (list

 The good news: the code works. The bad news: I'm convinced I'm doing it
 wrong, in the moral purity sense of the word. Something inside of me says,
 You could have just used (map...) to do this the *right* way, but I can't
 see how to do it with (map). So, my two questions are:

 1) Is there such a thing as the Clojure way, and if so,
 2) How can I rewrite the code to be more Clojure-ish?

  --
 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: Lein feature to check for updates in dependencies?

2014-09-11 Thread Ray Miller
https://github.com/xsc/lein-ancient

On 11 September 2014 14:41, Jonathon McKitrick jmckitr...@gmail.com wrote:
 I thought for sure I saw this feature, but I can't find it.

 Isn't there a way to scan for possible updates to dependencies in a project?

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

2014-08-30 Thread Ray Miller
On 30 August 2014 06:26, Colin Fleming colin.mailingl...@gmail.com wrote:

 I want to use a map to cache values based on a key. I'm planning to use an
 atom for this. My basic operation is give me the value for this key - if
 the value exists in the map then that value should be returned, otherwise a
 new value should be calculated, inserted in the map and then returned. My
 plan is to implement something like the following:


 (defn ensure [cache key]
   (if (contains? cache key)
 cache
 (assoc cache key (calc-value key

 (let [value (get (swap! cache ensure key) key)]
   ... do my thing with value ...)

Why not just use memoize?

(def calc-value (memoize (fn [key] ...))

If you need more control over the cache, check out core.memoize (which
builds on top of core.cache).

Ray.

-- 
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: Help with writing a function to merge two maps

2014-06-17 Thread Ray Miller
On 17 June 2014 13:24, Shoeb Bhinderwala shua...@gmail.com wrote:
 Can someone help me write the following function:

 I have two lists of maps as inputs:

 (def xs [{:id 1 :val 10}
  {:id 2 :val 20}
  {:id 3 :val 30}
  {:id 4 :val 40}])

 (def ys [{:id 2 :val 20}
  {:id 3 :val 30}
  {:id 5 :val 50}
  {:id 6 :val 60}])

 I want to create a result zs which is the union of xs and ys, except that if
 the :id occurs in BOTH then I want to multiply the corresponding :val.

 The result zs should be:

 [{:id 1 :val 10}
   {:id 2 :val 400}  -- :id 2 occurs in both collections, so multiply the
 :val fields
   {:id 3 :val 900}  -- :id 3 occurs in both collections, so multiply the
 :val fields
  {:id 4 :val 40}merge
  {:id 5 :val 50}
  {:id 6 :val 60}]

Not too different from the other solutions proposed, but how about:

(defn merge-with-multiply [ xs]
  (map (fn [[k v]] {:id k :val v}) (reduce (partial merge-with *) (map
#(into {} (map (juxt :id :val) %)) xs

(merge-with-multiply xs ys)
;;= ({:id 6, :val 60} {:id 5, :val 50} {:id 1, :val 10} {:id 2, :val
400} {:id 3, :val 900} {:id 4, :val 40})

The basic idea is to coerce your input to maps then take advantage of
`merge-with`. Note that this solution assumes that each :id appears at
most once in each of `xs` and `ys`. Here's an alternative solution
without this constraint:

(map (fn [[id vs]] {:id id :val (reduce * (map :val vs))}) (group-by
:id (concat xs ys)))

-- 
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 unit test (defn-) functions?

2014-06-12 Thread Ray Miller
On 12 June 2014 09:44, Hussein B. hubaghd...@gmail.com wrote:
 Hi,

 I like to use (defn-) when it comes to internal implementation functions.
 But since they aren't exposed, how to unit test them?

 Of course, I'm using Lein and clojure.test

It feels like a bit of a hack, but:

(#'other-ns/private-fn ...)

should get you by.

-- 
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: clj-commons-exec/sh adding newline to command

2014-06-09 Thread Ray Miller
On 9 June 2014 02:03, gvim gvi...@gmail.com wrote:
 (ns gh1.tmp
   (:require [clj-commons-exec :as exec]
 [clj-time.core :as t]))

 

 (defn calc [day month year hour min sec zone]
   (let [bin /Users/zephyr/html/astro/bin/swetest
 data (str -p0123456789t -fPZl -b day . month . year  -ut
 hour : min)
 flags -roundmin -head -true -eswe]
 (exec/sh [bin data flags])))


 gh1.tmp @(calc 31 11 1967 16 45 0 Europe/London)
 {:exit 1, :out illegal option -roundmin -head -true -eswe\n, :err nil,
 :exception #ExecuteException org.apache.commons.exec.ExecuteException:
 Process exited with an error: 1 (Exit value: 1)}


 Why has exec/sh added a newline to the command line? How to get rid of it?

It hasn't. That is the output from the command you executed.

Ray.

-- 
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: clj-commons-exec/sh adding newline to command

2014-06-09 Thread Ray Miller
On 9 June 2014 12:39, gvim gvi...@gmail.com wrote:
 Then why does this work when executed manually in the shell?

 ./swetest  -p0123456789t  -fPZl  -b14.10.1960  -ut13:45  -roundmin -head
 -true  -eswe

I suspect exec/sh is expecting a list of options. The way you are
calling it, swetest is called with only two arguments (data and
flags). When you type the command at the shell, the shell splits on
whitespace before invoking exec, so it sees 8 arguments.

I would expect this to work:

(exec/sh [/Users/zephyr/html/astro/bin/swetest -p0123456789t
-fPZl  -b14.10.1960  -ut13:45  -roundmin -head  -true
-eswe])

Ray.

-- 
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] monarch 0.2.0 - Simple database migrations for Clojure.

2014-05-27 Thread Ray Miller
On 27 May 2014 01:02, Michael Cramm gmcr...@gmail.com wrote:
 Good question. I had originally wanted a separate, untracked config file but
 couldn't decide on a format. (like separating out protocol, host, port, etc)
 Exporting the environment variable felt the most non-committal at the time.

Don't underestimate the value of using environment variables for
configuration: they are simple and effective, and allow for a lot of
flexibility in testing and deployment.

 It wouldn't be too much work to have a file living in
 `resources/monarch/...`, and add another optional param to `project.clj` to
 tell monarch where to look. I'll see about adding this to the next version.

Do configuration files really belong in resources? They will then be
shipped with the compiled jar. From a DevOps point of view, we like to
separate code from config, and certainly don't want to compile a new
jar just to deploy with a different database configuration.

Ray.

-- 
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] monarch 0.2.0 - Simple database migrations for Clojure.

2014-05-27 Thread Ray Miller
On 27 May 2014 09:35, Manuel Paccagnella manuel.paccagne...@gmail.com wrote:

 I've found confijulate, here. It might be useful.


 Well, ok. Another configuration library that I wasn't aware of when I wrote
 confunion. Another one that I found after writing mine is carica, which
 seems quite good. There are a bunch of them out there, you can look into
 Clojure Toolbox, probably there is already one that satisfies your use
 cases.

Thank you for drawing all these configuration libraries to my
attention, this is something I've done in an ad hoc way for the
different applications I've written. I'll take a look at these before
rolling my own next time.

Ray.

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


What is fn* ?

2014-05-26 Thread Ray Miller
I was looking at the source for clojure.java.jdbc, and came across the
following macro:

(defmacro with-db-transaction
  [binding  body]
  `(db-transaction* ~(second binding)
(^{:once true} fn* [~(first binding)] ~@body)
~@(rest (rest binding

I understand all of that apart from fn*, which I can't find any
documentation for. Can anyone enlighten me?

Also, why is the :once tag needed?

Ray.

-- 
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: What is fn* ?

2014-05-26 Thread Ray Miller
On 26 May 2014 16:31, Timothy Baldridge tbaldri...@gmail.com wrote:
 All functions are eventually created via fn*. If you look for the source
 code of fn it's a macro that emits a call to fn*. It's done this way so that
 things like destructuring can be defined in clojure.core (and in Clojure)
 instead of in Compiler.java (and in java).

Ah, thanks, that makes sense. But I think I asked the wrong question :-)

What I really wanted to know was why clojure.java.jdbc needs fn* in
this macro rather than a simple fn, and why it needs the :once tag. I
found the answer here:

http://clj-me.cgrand.net/2013/09/11/macros-closures-and-unexpected-object-retention/

Ray.

 On Mon, May 26, 2014 at 9:08 AM, Ray Miller r...@1729.org.uk wrote:

 I was looking at the source for clojure.java.jdbc, and came across the
 following macro:

 (defmacro with-db-transaction
   [binding  body]
   `(db-transaction* ~(second binding)
 (^{:once true} fn* [~(first binding)] ~@body)
 ~@(rest (rest binding

 I understand all of that apart from fn*, which I can't find any
 documentation for. Can anyone enlighten me?

 Also, why is the :once tag needed?

 Ray.

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




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

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

-- 
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: determining repl environment vs. uberjar environment?

2014-05-08 Thread Ray Miller
On 8 May 2014 16:22, Dave Tenny dave.te...@gmail.com wrote:
 James, All well and good, but you still need to know if you're running in a
 REPL environment, and make sure you do NOT call System/exit for any
 (typical) reason in that environment.  The idea is to test your (-main)
 function from the REPL, without having to restart the lisp every time.

I think James's point was that, if your -main function is a thin
wrapper that calls (app ...), then it's (app ...) you'd test at the
REPL (apologies if I'm putting words into your mouth, James).

Ray.

-- 
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: what's the elegant way to write this code in clojure?

2014-04-18 Thread Ray Miller
On 18 April 2014 15:05, sd song sd.s...@gmail.com wrote:
 i use clojure and korma libs.
 now i need to add some search conditions to users-sql at
 need_do_something_here,i can describe it in imperative style:

 if ( nick_name != nil)
 users-sql = (where users-sql (like :nick_name nick_name)

 if (max_age != nil)
 users-sql = (where uses-sql ( :birthday blabla))

 if (min_age != nil)
 users-sql = (where uses-sql ( :birthday blabla))

 how to do this in an elegant way with functional style?

You should be able to do something with the cond- threading macro:

(cond- users-sql
  nick_name  (where (like :nick_name nick_name))
  max_age (where ( :birthday ...)
  min_age  (where ( :birthday ...))

 another question is: i think code like: (if (nil? page) lmt page) is ugly.
 is there some functions in clojure like (get_default_value_3_if_a_is_null a
 3) ?

(or page 3)

-- 
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: dependencies from github

2014-03-27 Thread Ray Miller
Have you considered pushing your build of the package to Clojars under
the org.clojars.USERNAME group?

Ray.

On 27 March 2014 09:16, t x txrev...@gmail.com wrote:
 Hi,

 ## Context:

   * I'm using lein.
   * In my project.clj, I have something like:

 :dependencies[ [org.clojure/clojure 1.5.1]
   [org.clojure/clojurescript 0.0.-2173]
   [not-really-trusted-package version]]

   Now, I don't like pulling not-really-trusted-package, which can
 change under me. Instead I'd prefer to:

   (1) git fork the not-really-trusted package to
 github/txrev319/not-really-trusted
   (2) have lein pull from github/txrev319/not-really-trusted

 ## Question:

   How do I achieve the above?

 Thanks!

 (I still don't trust the package, but atleast I want to use the same
 untrusted package every time.)

 --
 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: Where is the rotations function?

2014-02-11 Thread Ray Miller
I'm not sure if that function exists in a new contrib library, but
it's trivial to implement:

(defn rotations [xs] (take (count xs) (partition (count xs) 1 (cycle xs

On 11 February 2014 05:53, Mars0i marsh...@logical.net wrote:
 At one time there was a function named rotations in clojure.contrib.seq,
 and at another time in clojure.contrib.seq-utils .  Neither of these
 libraries seem to be present as of Clojure 1.5, and I am not finding
 rotations anywhere else.  Does rotations exist?  I can write it myself, but
 don't want to duplicate something that's part of a library.  (Maybe I'm just
 being clueless and missing something obvious.)

 (rotations returned rotated versions of a seq, I believe:

 (rotations [1 2 3])
 =
 ((1 2 3) (2 3 1) (3 2 1))

 perhaps in a different order.

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

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


Re: tools.cli and required arguments

2014-01-22 Thread Ray Miller
On 22 January 2014 13:21, Alf Kristian Støyle alf.krist...@gmail.com wrote:
 Thanks! That does explain it :)

 Would be nice to be able to specify that an option must be specified in
 every invocation though. I think it would lead to better error messages,
 e.g. if several mandatory options are forgotten, they will be shown at
 once. That is a bit of a hassle when doing it yourself.

Take a look at Cliopatra; they have added a :required flag to the
option specification which does just what you want. I've had great
success using Cliopatra to build Clojure command-line tools.

https://github.com/runa-dev/cliopatra

Ray.

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


[Job Opportunity] Clojure Web Developer Role

2014-01-20 Thread Ray Miller
A UK-based Clojure job for a change... Metail is a start-up with a tech
team based in the centre of Cambride. We are looking to recruit a junior
developer to work on a mix of RESTful API handlers and frontend web
applications, all build using Clojure. This is an ideal job for a recent
graduate or someone relatively new to Clojure and looking to build out
their skillset.

Check out the job listing for more details:

 http://metail.com/job/junior-web-software-engineer-clojure/

Ray.

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


Re: How can I improve this?

2014-01-10 Thread Ray Miller
On 10 January 2014 14:59, Colin Yates colin.ya...@gmail.com wrote:

 I have a sequence of file names and I want to make them unique.  (uniquify
 [a b c a]) = [a b c a_1])

 This is what I have come up with, but surely there is a better way?


I would do something like:

 (defn uniquify
  ([xs]
 (uniquify xs (fn [x n] (str x _ n
  ([xs formatter]
 (letfn [(uniquify* [xs seen]
   (lazy-seq
(when (not-empty xs)
  (let [x (first xs)
n (seen x 0)]
(if ( n 0)
  (cons (formatter x n) (uniquify* (rest xs) (assoc
seen x (inc n
  (cons x (uniquify* (rest xs) (assoc seen x (inc
n)]
   (uniquify* xs {}

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


Re: java.jdbc DSLs (java.jdbc.sql / java.jdbc.ddl)

2013-11-20 Thread Ray Miller
On 20 November 2013 22:25, Sean Corfield seancorfi...@gmail.com wrote:


 Is anyone using the java.jdbc.sql namespace? (besides World Singles :)


Only the 'where' function, in a few places.

Ray.

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


Re: How could you solve this problem

2013-11-18 Thread Ray Miller
Just for contrast, here's a fairly succinct solution I put together:

https://gist.github.com/ray1729/7534528#file-ring_of_primes-clj

It uses a basic depth-first search.

Ray.

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


Re: [ANN] Yesql 0.2.1 - Clojure SQL queries rethought.

2013-11-18 Thread Ray Miller
Hi Gary et al,

On 15 November 2013 23:55, Gary Johnson gwjoh...@uvm.edu wrote:

 I really like your approach, but I've also been feeling the burn a bit
 with having to store each SQL query in its own file (especially since my
 data exploration frequently leaves me cataloging hundreds of them). Take a
 look at the approach used in sql-phrasebook:

   https://github.com/ray1729/sql-phrasebook

   I'm hoping it will give you some ideas to extend Yesql to address this
 particular issue, ideally with a nicer syntax than that used in
 sql-phrasebook. Otherwise, I think Yesql is bound for great things!


Is it the syntax of the phrasebook you don't like, or the API for the
library?

This was just something I put together quickly, so there's a lot of room
for improvement. The phrasebook parser is very simplistic and, although it
works for the simple cases where I've used it, I'm concerned it's not
robust. It's trivial to change the place-holder syntax from ${var-name} if
that's the problem.

My biggest concern is more philosophical. Although there are advantages to
defining the queries in an SQL file, the code where you use them needs to
know the details of the query (what columns does it return? what bind
parameters are needed? is any post-processing aggregation needed?) So I
don't like the distance between the Clojure and SQL implied by a
phrasebook-based approach.

My current thinking is to do something like:

(defselect select-user
  SELECT user.* FROM user
   WHERE user_id = {{user_id}})

with appropriate syntactic sugar. This would return a function of a
database connection, which would return the rows. The next step would be to
support a post-processing option for the cases where you modify the
returned results in some way:

(defselect select-user-roles
  SELECT user.*, role.name AS role_name
   FROM user
   LEFT OUTER JOIN user_role USING(user_id)
   LEFT OUTER JOIN role USING(role_id)
   ORDER BY user.user_id
  :post-process (fn [rows] (map (fn [user-rows]
 (assoc (select-keys (first
user-rows) [:user_id :user_name])
   :roles (map
:role_name user-rows))
(partition-by :user_id rows)))

That way, the post-processing of the results is kept close to the query.

Just some food for thought...

Ray.

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


Re: SQL to logic rule mapping

2013-10-30 Thread Ray Miller
On 30 October 2013 11:47, Kris Jenkins krisajenk...@gmail.com wrote:

 FWIW, I too am interested in a better SQL tool for Clojure, but my take on
 it is that we don't need a new language on top of SQL, but a better way to
 use SQL directly.

 My thinking, plus an *alpha-grade* library, can be found here:
 https://github.com/krisajenkins/yesql#rationale


Something similar I'm using in production on a couple of sites:

https://github.com/ray1729/sql-phrasebook

Ray.

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


Re: Current state of the art in Web deployment?

2013-08-18 Thread Ray Miller
On 18 August 2013 17:21, John Jacobsen eigenhom...@gmail.com wrote:

 On Aug 17, 2013, at 4:52 PM, Ray Miller r...@1729.org.uk wrote:

 One option is simply to write an upstart script that invokes 'lein
 ring server-headless' and sit an apache or nginx proxy in front of it.
 That's how my website is currently running. Alternatively, you could
 deploy your application as a war to tomcat or jetty.

 The upstart configuration, which is installed to /etc/init/cms.conf,
 can be found here: https://gist.github.com/ray1729/6258845

 That's very helpful -- can you be a little more specific about what you mean 
 by sit an apache or nginx proxy in front of it?  It looks like your example 
 is self-contained (need Clojure/lein + upstart, and that's it).

The Ring server is listening on localhost (port 3000 by default). I've
set up an apache reverse proxy that routes requests to the Compojure
application. This gives a bit more flexibility e.g. if you have other
services on the same machine, or want apache to serve static content
directly.

Ray.

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


Re: vec to map with consolidated vals

2013-08-18 Thread Ray Miller
On 18 August 2013 12:31, Timo Mihaljov t...@mihaljov.info wrote:
 On 17.08.2013 08:40, David Chelimsky wrote:
 Which led me to this:

 (defn to-consolidated-map [parts]
   (apply merge-with + (map (partial apply hash-map) parts)))

 This is exactly what I came up with after reading your first message.
 Apparently Jay Fields took the same approach. I think it's fair to say
 that this is the idiomatic solution, now that three people have come to
 the same result independently. :)

For the record, I don't like this approach at all. You're creating
temporary hash-map's just so you can use the core merge-with function.
I prefer to reduce with a custom accumulator function (I think someone
already posted something along these lines):

(defn accumulate-keys [xs] (reduce (fn [accum [k v]] (assoc accum k (+
v (get accum k 0 {} xs))

Mostly a matter of taste, of course.

Ray.

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


Fwd: Hands-on Clojure: Collaborative Filtering

2013-08-17 Thread Ray Miller
if any of you are in Cambridge (UK) next Thursday evening, you're be
welcome to join us at the next Camclj Meetup. Details below.

-- Forwarded message --
From: Ray Miller r...@1729.org.uk
Date: 17 August 2013 15:47
Subject: Hands-on Clojure: Collaborative Filtering
To: cam...@googlegroups.com


Our next meetup will be a hands-on coding session along similar lines
to the London Clojure Dojos [*]. We will have a go at implementing
some collaborative filtering algorithms to make movie recommendations.

Where? Upstairs at The Fountain, 12 Regent Street, Cambridge, CB2 1DB

When? Thursday 22nd August 2013, from 1900-2200.

Who? This event is open to all, from beginner to expert.

Free beer! This meetup is sponsored by Metail, who are covering venue
hire and the drinks. Metail is recruiting! If you want to work in an
exciting startup  environment where you can build out your Clojure
webdev skils, check out the job listing
http://metail.com/job/junior-web-software-engineer-clojure/.

You don't need any prior Clojure experience to attend this event; we
hope to have enough experienced developers on hand to get everyone
started.

Please sign up on Meetup if you plan to attend: http://meetu.ps/1Y34WR

If you have a laptop, please bring it along. There are a couple of
things you can do before the Meetup, you'll find some setup notes and
suggested background reading (entirely optional!) here:
http://github.com/cam-clj/Recommendations.
It would be particularly useful if you could download the test data
set and suggested dependencies before the Meetup, just in case the
pub's wi-fi proves unreliable.

On the day, look for us in the first floor room at the Fountain, which
we have exclusive use of until 10pm. The pub doesn't do a wide range
of food, but you will be able to order from a selection of flat breads
at the bar until 9pm.

I hope to see you next week!

Ray.

[*] 
http://otfrom.wordpress.com/2012/07/04/how-to-run-a-london-clojure-dojo-in-20ish-easy-steps/

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


Re: Current state of the art in Web deployment?

2013-08-17 Thread Ray Miller
On 17 August 2013 21:52, John Jacobsen eigenhom...@gmail.com wrote:

 So, what do all y'all do?  What is a good lightweight but robust way to get
 a fairly simple Compojure/Ring app backed by Datomic facing the outside
 world?  Not too worried about massive scalability at this point; simplicity
 will be a plus (am worried that e.g. Immutant / JBoss are too heavyweight).

One option is simply to write an upstart script that invokes 'lein
ring server-headless' and sit an apache or nginx proxy in front of it.
That's how my website is currently running. Alternatively, you could
deploy your application as a war to tomcat or jetty.

The upstart configuration, which is installed to /etc/init/cms.conf,
can be found here: https://gist.github.com/ray1729/6258845

Ray.

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


Re: Clojure: Elegance vs. Performance?

2013-07-09 Thread Ray Miller
On 9 July 2013 16:11, Alexander Gunnarson alexandergunnar...@gmail.comwrote:


 *Example 1: Tail-call recursion*

 *Scheme*
 One example would be tail-call recursion. For instance, normally in Scheme
 I'd naively implement an iterative exponent function like this:

 (define (expt x n)

 (cond ((= 0 n) 1)

   ((= 1 n) x)

   (else (expt (* x x) (- n 1)

 Pure. Simple. Beautiful. (Not that I'm the best Scheme programmer ever,
 but to me it looks beautiful, and it conforms well to the base of the
 problem. You get the point.)


This is not implementing expt as it is usually known, it looks more like
repeated squaring to me.

Ray.

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




Re: clojure.set/union bug?

2013-07-02 Thread Ray Miller
On 1 July 2013 21:39, Cedric Greevey cgree...@gmail.com wrote:


 What bugs me is that sorted-set-by needs apply to convert a coll into
 a sorted set; there's no short-and-pithy into for that case, and no
 coll-taking and varargs version pair like vec/vector either.


(into (sorted-set) coll)

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




Re: clojure.set/union bug?

2013-07-02 Thread Ray Miller
On 2 July 2013 08:10, Cedric Greevey cgree...@gmail.com wrote:

 Er...that won't use my custom comparator. :)


Sorry, I thought it was clear how to generalize from my previous example.
Here it is with a custom comparator:

(into (sorted-set-by ) [1 2 4 2 1 2 3])
;; = #{4 3 2 1}


 On Tue, Jul 2, 2013 at 2:40 AM, Ray Miller r...@1729.org.uk wrote:

 On 1 July 2013 21:39, Cedric Greevey cgree...@gmail.com wrote:


 What bugs me is that sorted-set-by needs apply to convert a coll
 into a sorted set; there's no short-and-pithy into for that case, and no
 coll-taking and varargs version pair like vec/vector either.


 (into (sorted-set) coll)



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




Cambridge (UK) Clojure user group

2013-06-23 Thread Ray Miller
The Cambridge (UK) Clojure group used to meet monthly, but has recently 
lost momentum. I'm trying to turn that around and get us back on track with 
a regular monthly meet-up. If you are in the Cambridge area and might be 
interested in attending these meet-ups, please take a few minutes to 
complete our short survey: http://www.surveymonkey.com/s/5BRRCZX.

Ray.

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




DBM libraries

2013-06-16 Thread Ray Miller
Hi,

Is there a maintained and widely-adopted Clojure interface to any of
the Java DBM libraries (jdbm, jdbm2, BerkeleyDB or MapDB) ?

If not, is there a preferred alternative for persisting a large
hash-map to disk? (Ideally I'd like random access to records without
reading the whole thing into memory, so would prefer something more
sophisticated than printing a Clojure data structure to a file.)

Ray.

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




Re: with-open and for

2013-06-11 Thread Ray Miller
The 'reduce' solution is very elegant, but you can simplify it further:

(defn filter-file [filename]
  (with-open [rdr (io/reader filename)]
(reduce (fn [words line]
  (into words (filter #(= 4 (count %) 9) (str/split line #\s+
#{}
(line-seq rdr

Ray.

On 10 June 2013 18:20, Thomas Heller i...@zilence.net wrote:
 Hey,

 I pasted the code into gist ( https://gist.github.com/thheller/5734642 ) and
 copypasted that into the post.

 Cheers,
 /thomas


 On Mon, Jun 10, 2013 at 6:01 PM, Alan Thompson thompson2...@gmail.com
 wrote:

 Hey Thomas - How'd you get the nice syntax highlighting in your post?
 Alan


 On Sat, Jun 8, 2013 at 7:16 PM, Steven D. Arnold
 thoth.amon.i...@gmail.com wrote:

 Thanks for the responses!  As suggested, wrapping in 'doall' does work.


 On Jun 8, 2013, at 3:28 AM, Thomas Heller th.hel...@gmail.com wrote:

 (defn filter-file [filename]
  (with-open [rdr (io/reader filename)]
(reduce (fn [words line]
  (- (str/split line #\s+)
   (filter #(and (= (count %) 9)
 (= (count %) 4)))
   (set)
   (set/union words)))
#{}
(line-seq rdr


 That code is really graceful and clean.  I like it a lot.  But for some
 reason I've never loved 'reduce' before, which probably means I've never
 used it where it is called for.  Reduce just seems so generic... it's what
 you say when you haven't got anything better to say, something like all
 right, do this.

 But, having said that, I'd pick your implementation over mine, because I
 think it's conceptually cleaner (as recursive algorithms often are).  Nice.
 Thanks!

 steven

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

 For more options, visit https://groups.google.com/groups/opt_out.




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




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



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




Re: CLI sub-commands in an uberjar?

2013-05-12 Thread Ray Miller
On 12 May 2013 10:37, Dick Davies rasput...@hellooperator.net wrote


 I've got a half-decent utility written that i want to provide to our
 ops team (and not let them know it's Clojure based ssshhh).

 Works great with 'lein run -m thingy.core/fn1 arg', but there are several
 functions
 I want to expose as 'subcommands' e.g.

 java -jar thingy.jar fn1 arg

 java -jar thingy.jar fn2 arg1 arg2


Sounds like a good fit for cliopatra:

 https://github.com/runa-dev/cliopatra

Ray.

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




Re: why do I get Null pointer on this GMT SimpleDateFormat?

2013-03-04 Thread Ray Miller
You've assigned to date-formatter-set-to-gmt-time the return value
from the setTimeZone method call. This method returns null, hence the
null pointer exception when you try to call the format method. 'doto'
might help here, like:

(let [gmt-date-formatter (doto (SimpleDateFormat. -MMM-dd HH:mm:ss)
   (.setTimeZone
(TimeZone/getTimeZone GMT)))]
(.format gmt-date-formatter (Date.)))

On 4 March 2013 16:50, larry google groups lawrencecloj...@gmail.com wrote:
 I need to get a GMT date. I found this page on StackOverflow:

 http://stackoverflow.com/questions/308683/how-can-i-get-the-current-date-and-time-in-utc-or-gmt-in-java

 It gives this example:

 SimpleDateFormat dateFormatGmt = new SimpleDateFormat(-MMM-dd
 HH:mm:ss);
 dateFormatGmt.setTimeZone(TimeZone.getTimeZone(GMT));

 I thought I was following it closely with (this is inside of a (let)
 statement):

  date-formatter (new SimpleDateFormat -MM-dd'T'HH:mm:ss)
  gmt-timezone (TimeZone/getTimeZone GMT)
  date-formatter-set-to-gmt-time (.setTimeZone date-formatter gmt-
 timezone)
  created (.format date-formatter-set-to-gmt-time (new Date))

 but this line:

   created (.format date-formatter-set-to-gmt-time (new Date))

 gives me:

 java.lang.NullPointerException: null
  Reflector.java:26 clojure.lang.Reflector.invokeInstanceMethod
omniture.clj:52 mpdv-clojure.omniture/omniture-make-headers-
 for-api-call

 Can anyone tell me why?







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



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




Re: Vector of different refs?

2012-12-11 Thread Ray Miller
(repeatedly 10 #(ref 100))

Ray.


On 11 December 2012 16:44, Thomas th.vanderv...@gmail.com wrote:

 Hi,

 How do I create a vector of different refs?

 I would like to have a vector with in each cell a ref so that I can
 manipulate them independently from each other (Is that a good idea
 anyway?). But when I do

 (def x (into [] (repeat 10 (ref 100

 I end up with the same ref ten times (not surprisingly), but I would like
 to have ten different refs instead.

 TIA,
 Thomas

  --
 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 post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: Parsing Log Files with Interspersed Multi-line Log Statements

2012-10-21 Thread Ray Miller
As Dave says, you can do this using line-seq, but you'll have to
accumulate some state as you read the lines so you can return all the
lines for a given thread's ReqStart to ReqEnd. Once you've returned
that block, you can delete the state for that thread-id, so your
accumulated state will only contain the 'active' requests. If you're
processing a very large file, you're best returning a lazy sequence of
the data.

Something like this should get you started:

(require [clojure.java.io :as io])

(defn parse-line
  [s]
  (let [[_ thread_id tag value] (re-find #^(\d+)\s+(\S+)\s+(.+)$ s)]
[thread_id tag value]))

(defn parse-lines
  ([lines]
 (parse-lines lines {}))
  ([lines state]
 (lazy-seq
  (when (seq lines)
(let [[thread-id tag value] (parse-line (first lines))
  state (assoc-in state [thread-id tag]
  (conj (get-in state [thread-id tag] []) value))]
  (if (= tag ReqEnd)
(cons (get state thread-id) (parse-lines (rest lines)
(dissoc state thread-id)))
(parse-lines (rest lines) state)))

(defn parse-log-file
  [file]
  (with-open [logfile (io/reader file)]
(doall
 (filter #(and (get % ReqStart) (get % ReqEnd))
 (parse-lines (line-seq logfile))


On 21 October 2012 02:54, Dave d...@sevenventures.net wrote:
 Clojurists - I'm fairly new to Clojure and didn't realize how broken I've
 become using imperative languages all my life.  I'm stumped as to how to
 parse a Varnish (www.varnish-cache.org) log file using Clojure.  The main
 problem is that for a single request a varnish log file generates multiple
 log lines and each line is interspersed with lines from other threads.
 These log files can be several gigabytes in size (so using a stable sort of
 the entire log by thread id is out of the question).

 Below I've included a small example log file and an example output Clojure
 data structure.  Let me thank everyone in advance for any hints / help they
 can provide on this seemingly simple problem.

 Rules of the Varnish Log File

 The first number on each line is the thread id (not unique and gets reused
 frequently)
 Each ReqStart marks the start of a request and the last number on the line
 is the unique transaction id (e.g. 118591777)
 ReqEnd denote the end of the processing of the request by the thread
 Each line is atomically written, however many threads generate log lines
 that are interspersed with other requests (threads)
 These log files can be VERY large (10+ Gigabytes in the case of my
 application) so using a stable sort by thread id or anything that loads the
 entire file into memory is out of the question.


 Example Varnish Log file
40 ReqEnd   c 118591771 1350759605.775758028 1350759611.249602079
 5.866879225 5.473801851 0.42200
15 ReqStart c 10.102.41.121 4187 118591777
15 RxRequestc GET
15 RxURLc /json/engagement
15 RxHeader c host: www.example.com
30 ReqStart c 10.102.41.121 3906 118591802
15 RxHeader c Accept: application/json
30 RxRequestc GET
30 RxURLc /ws/boxtops/user/
30 RxHeader c host: www.example.com
15 ReqEnd   c 118591777 1350759605.775758028 1350759611.249602079
 5.866879225 5.473801851 0.42200
30 RxHeader c Accept: application/xml
30 ReqEnd   c 118591802 1350759611.326084614 1350759611.329720259
 0.005002737 0.003598213 0.37432
15 ReqStart c 10.102.41.121 4187 118591808
15 RxRequestc GET
15 RxURLc /ws/boxtops/user/
30 ReqStart c 10.102.41.121 3906 118591810
15 RxHeader c host: www.example.com
15 RxHeader c Accept: application/xml
30 RxRequestc GET
30 RxURLc /registration/success
30 RxHeader c host: www.example.com
46 TxRequest- GET
30 RxHeader c Accept: text/html
46 TxURL- /registration/success
15 ReqEnd   c 118591808 1350759611.442447424 1350759611.444925785
 0.016906023 0.002441406 0.36955
30 ReqEnd   c 118591810 1350759611.521781683 1350759611.525400877
 0.098322868 0.003532171 0.87023

 Desired Output
 {
   118591802
   { :ReqStart [10.102.41.121 3906 118591802]
 :RxRequest [GET]
 :RxURL [/ws/boxtops/user/]
 :RxHeader [host: www.example.com Accept: application/xml]
   or better yet
 :RxHeader {:host www.example.com :Accept application/xml}
 :ReqEnd [118591802 1350759611.326084614 1350759611.329720259
 0.005002737 0.003598213 0.37432] }
   118591777
   { :ReqStart [10.102.41.121 4187 118591777]
 :RxRequest [GET]
 :RxURL [/json/engagement]
 :RxHeader [host: www.example.com Accept: application/json]
 :ReqEnd [118591777 1350759605.775758028 1350759611.249602079
 5.866879225 5.473801851 0.42200 ]}
   118591808
   { :ReqStart [10.102.41.121 4187 118591808]
 :RxRequest [GET]
 :RxURL [/ws/boxtops/user/]
 :RxHeader [host: www.example.com 

Re: Macro to ease multiple-key sorting

2011-12-08 Thread Ray Miller
On 8 December 2011 01:51, Andy Fingerhut andy.finger...@gmail.com wrote:
 I've been going through the PLEAC web site, writing Clojure examples
 corresponding to the Perl code examples from the Perl Cookbook:

 http://pleac.sourceforge.net

 Michael Bacarella started a github repo to collect these together, and I'm
 helping flesh some of them out.

 https://github.com/mbacarella/pleac-clojure

 One thing that is very convenient in Perl is doing sorts on multiple
 comparison keys -- since 0 is treated as logically false in Perl, they can
 simply do what in Clojure would look like:

 (sort #(or (compare (key1 %1) (key2 %2))
     (compare (key2 %1) (key2 %2))
     ...)
  collection)

You can take advantage of the fact that Clojure already knows how to
compare vectors. If key1, key2, ... are functions (or keywords, which
act as functions on a map), you have:

(sort-by (juxt key1 key2) collection)

To sort a collection of maps whose keys aren't keywords, you have to
work a little harder:

(sort-by (fn [m] (vec (map #(get m %) [key1 key2]))) collection)

These examples are easily extended to handle an arbitrary number of keys.

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


Re: clojure.contrib.base64

2011-10-09 Thread Ray Miller
On 6 October 2011 19:38, Ray Miller r...@1729.org.uk wrote:

 Incidentally, I used the Apache Commons Base64 encoder, as the one in
 contrib was producing different results from the Apache Commons and
 Perl implementations. Perhaps a bug?


Here's the problem I alluded to above. I'm trying to compute the
base64 MD5 digest of the string foobar. With Perl, I'd do it like
this:

   perl -MDigest::MD5=md5_base64 -le 'print md5_base64(foobar)'

Which gives me the string: OFj2IjCsPJFfMAxmQxLGPw

Now in Clojure, I can use java.security.MessageDigest to give me the
MD5 digest as a byte array. When I transform this to base64 using the
Apache Commons library, I get the same result as above. But when I try
to do it with clojure.contrib.base64, I get a slightly different
string. It's quite possible I've misunderstood the
clojure.contrib.base64 API (in which case enlightenment is welcome!),
but I wondered if I'd tickled a bug in the contrib library?

Here's the code:

(use '[clojure.contrib.io :only (to-byte-array input-stream)])

(import '[java.security MessageDigest]
'[java.io StringWriter]
'[org.apache.commons.codec.binary Base64])

(require '[clojure.contrib.base64 :as base64])

(def md5sum (.. (java.security.MessageDigest/getInstance MD5)
(digest (to-byte-array foobar
;;= #byte[] [B@6fd33eef

(org.apache.commons.codec.binary.Base64/encodeBase64String md5sum)
;;= OFj2IjCsPJFfMAxmQxLGPw==

(let [output (StringWriter.)]
  (base64/encode (input-stream md5sum)
 output
 base64/*base64-alphabet*
 nil)
  (.toString output))
;;= OF/2Ij+sP5FfMAxmQx/GPw==

This string differs in several positions (first at character 3). Any
idea what's going wrong?

Ray.

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


Re: clojure.contrib.base64

2011-10-09 Thread Ray Miller
On 9 October 2011 20:13, Teemu Antti-Poika antti...@gmail.com wrote:
 On Oct 9, 12:56 pm, Ray Miller r...@1729.org.uk wrote:
 On 6 October 2011 19:38, Ray Miller r...@1729.org.uk wrote:
  Incidentally, I used the Apache Commons Base64 encoder, as the one in
  contrib was producing different results from the Apache Commons and
  Perl implementations. Perhaps a bug?

 ...
 This string differs in several positions (first at character 3). Any
 idea what's going wrong?

 That does look like a bug. On closer look base64/encode does not
 handle negative bytes properly (java has only unsigned bytes and bitwise
 operations on byte arrays always cause grief).

Thanks for investigating and tracking down the bug - I didn't know
were to start!

 As discussed elsewhere, the base64 module is not very efficient and
 is not currently planned to be migrated to a new style contrib module.
 Maybe using commons-codec is the best alternative for you?

I already switched my code to use commons-codec, just posted here in
case it was a bug in the contrib library that might catch out someone
else.

Thanks again for your investigation and explanation.

Ray.

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


Re: clojure.contrib.base64

2011-10-06 Thread Ray Miller
On 6 October 2011 18:27, Aaron Bedra aaron.be...@gmail.com wrote:
 This actually introduces an opportunity for a much larger set of utilities.

 clojure.data.crypto

 base64 is part of this idea anyways, and putting it in place along with
 nice wrappers around the messy java crypto bits I think could provide a
 significant win.

I wrote a little wrapper around java.security.MessageDigest a few weeks ago:

  https://github.com/ray1729/clj-message-digest

(also available on Clojars). This was inspired by Perl's Digest::MD5
module and  provides md5, md5-hex, md5-base64 etc. functions.

Incidentally, I used the Apache Commons Base64 encoder, as the one in
contrib was producing different results from the Apache Commons and
Perl implementations. Perhaps a bug?

Ray.

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


Re: ClojureQL and Oracle

2011-04-19 Thread Ray Miller
On 19 April 2011 22:34, Michael michael-a...@db.com wrote:

 As far as I can tell, ClojureQL does not directly support Oracle. Has
 anybody been able to get Clojure QL to work with Oracle?  Are there
 plans to directly support it? Would be great to use this with Clojure
 inside the corporate ship.

I've used it with Oracle for basic select/join/union queries. I didn't
try any update operations. The only read operation I had a problem
with was 'take', as Oracle doesn't support LIMIT, but then I was just
playing around, not trying to test exhaustively.

Ray.

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


Re: clj-ldap - Clojure LDAP client

2011-03-16 Thread Ray Miller
On 15 March 2011 08:46, Saul Hazledine shaz...@gmail.com wrote:
 On Mar 15, 1:30 am, Paul Dorman paul.dor...@gmail.com wrote:
 One thought though is that it may be quicker simply do a lookup on the
 directory server, obtain the password and then do a compare. In
 OpenLDAP, posixUser uids are indexed by default. Java libraries are
 available for most password encryption algorithms. This is the
 approach I use - do you know of any problems with my method?

Certainly when I was running LDAP servers we did not allow passwords
to be retrieved from the server, as they are then susceptible to an
offline dictionary attack. To authenticate users, you had to send a
bind request to the server.

Ray.

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