Re: vec to map with consolidated vals

2013-08-17 Thread Sean Corfield
Ah, I misunderstood your requirements, but I'm glad it led you in the
right direction!

On Fri, Aug 16, 2013 at 10:40 PM, David Chelimsky  wrote:
> Thanks for the suggestions Sean and Ben. I learned new functions from both
> of you!
>
> Sean, your suggestion yields the following:
>
> (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
> ; {:a (1 3) :b (2)}
>
> So it still needs to reduce the vals using +. That led me to this:
>
> (defn to-consolidated-map [parts]
>   (apply merge-with + (map (fn [[k v]] {k v}) parts)))
>
> Which led me to this:
>
> (defn to-consolidated-map [parts]
>   (apply merge-with + (map (partial apply hash-map) parts)))
>
> I like this one because it describes the solution the way I thought about it
> - I just didn't know about merge-with. It also has the benefit of using core
> fns rather than anonymous fns. WDYT?
>
> On Sat, Aug 17, 2013 at 7:23 AM, Sean Corfield 
> wrote:
>>
>> How about this:
>>
>> (defn to-consolidated-map [parts]
>>   (apply merge-with concat
>> (map (fn [[k v]] {k (list v)}) parts)))
>>
>> On Fri, Aug 16, 2013 at 9:57 PM, David Chelimsky 
>> wrote:
>> > I've got a vector of 2-element vectors e.g. [[:a 1] [:b 2]] where the
>> > first
>> > val of any vec might appear in another vec e.g. [[:a 1] [:b 2] [:a 3]].
>> > I
>> > need a fn that will consolidate this into a hash-map with the vals
>> > consolidated e.g.
>> >
>> > (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
>> > ; {:a 4 :b 2}
>> >
>> > I've got two candidate implementations and I'm curious which you like
>> > better
>> > and why, or if I'm missing a better way:
>> >
>> > (defn to-consolidated-map [parts]
>> >   (reduce (fn [h [k v]]
>> > (if (contains? h k)
>> >   (assoc h k (+ (k h) v))
>> >   (assoc h k v)))
>> >   {} parts))
>> >
>> > (defn to-consolidated-map [parts]
>> > (->> parts
>> >(group-by first)
>> >(map (fn [[k v]] [k (->> v (map last) (reduce +))]
>> >
>> > TIA,
>> > David
>> >
>> > --
>> > --
>> > 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.
>>
>>
>>
>> --
>> Sean A Corfield -- (904) 302-SEAN
>> An Architect's View -- http://corfield.org/
>> World Singles, LLC. -- http://worldsingles.com/
>>
>> "Perfection is the enemy of the good."
>> -- Gustave Flaubert, French realist novelist (1821-1880)
>>
>> --
>> --
>> 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.



-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

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

Re: vec to map with consolidated vals

2013-08-17 Thread Steven Degutis
At first I came up with the same solution as your second one. But I
couldn't help but feel that it wasn't descriptive enough. It felt too
incidental-complexity-ish.

To me, (into {} the-map) seems mostly right. But obviously it would just
squash the values you need. So I figured it should just be modified a bit.
Seeing as how it's really short for reduce conj, I figured conj was the
place to swap out.

Here's what I came up with:

(def the-map [[:a 1] [:b 2] [:a 3]])



(defn add-maybe [& nums]

  (->> nums

   (remove nil?)

   (reduce +)))



(reduce (fn [m [k v]]

  (update-in m [k] add-maybe v))

{}

the-map)



;; => {:b 2, :a 4}


But I don't really like the add-maybe function. It seems like I'm probably
missing an opportunity for a core-lib function that I'm forgetting about. I
really just wanted to have access to the original value, so I could do (or
orig-value 0) and then just use + instead of add-maybe.

-Steven


On Fri, Aug 16, 2013 at 11:57 PM, David Chelimsky wrote:

> I've got a vector of 2-element vectors e.g. [[:a 1] [:b 2]] where the
> first val of any vec might appear in another vec e.g. [[:a 1] [:b 2] [:a
> 3]]. I need a fn that will consolidate this into a hash-map with the vals
> consolidated e.g.
>
> (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
> ; {:a 4 :b 2}
>
> I've got two candidate implementations and I'm curious which you like
> better and why, or if I'm missing a better way:
>
> (defn to-consolidated-map [parts]
>   (reduce (fn [h [k v]]
> (if (contains? h k)
>   (assoc h k (+ (k h) v))
>   (assoc h k v)))
>   {} parts))
>
> (defn to-consolidated-map [parts]
> (->> parts
>(group-by first)
>(map (fn [[k v]] [k (->> v (map last) (reduce +))]
>
> TIA,
> David
>
> --
> --
> 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: vec to map with consolidated vals

2013-08-17 Thread Steven Degutis
Wow. Sorry for the awful formatting. Re-pasting it from Google Groups 
(instead of email) to fix it:

(def a [[:a 1] [:b 2] [:a 3]])

 

(defn add-maybe [& nums]

  (->> nums

   (remove nil?)

   (reduce +)))

 

(reduce (fn [m [k v]]

  (update-in m [k] add-maybe v))

{}

a)

 

;; => {:b 2, :a 4}


-Steven

On Saturday, August 17, 2013 3:40:23 AM UTC-5, Steven Degutis wrote:
>
> At first I came up with the same solution as your second one. But I 
> couldn't help but feel that it wasn't descriptive enough. It felt too 
> incidental-complexity-ish.
>
> To me, (into {} the-map) seems mostly right. But obviously it would just 
> squash the values you need. So I figured it should just be modified a bit. 
> Seeing as how it's really short for reduce conj, I figured conj was the 
> place to swap out.
>
> Here's what I came up with:
>
> (def the-map [[:a 1] [:b 2] [:a 3]])
>
>
>  
>
> (defn add-maybe [& nums]
>
>
>   (->> nums
>
>(remove nil?)
>
>
>(reduce +)))
>
>  
>
> (reduce (fn [m [k v]]
>
>
>   (update-in m [k] add-maybe v))
>
>
> {}
>
> the-map)
>
>  
>
> ;; => {:b 2, :a 4}
>
>
> But I don't really like the add-maybe function. It seems like I'm probably 
> missing an opportunity for a core-lib function that I'm forgetting about. I 
> really just wanted to have access to the original value, so I could do (or 
> orig-value 0) and then just use + instead of add-maybe.
>
> -Steven
>
>
> On Fri, Aug 16, 2013 at 11:57 PM, David Chelimsky wrote:
>
>> I've got a vector of 2-element vectors e.g. [[:a 1] [:b 2]] where the 
>> first val of any vec might appear in another vec e.g. [[:a 1] [:b 2] [:a 
>> 3]]. I need a fn that will consolidate this into a hash-map with the vals 
>> consolidated e.g.
>>
>> (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
>> ; {:a 4 :b 2}
>>
>> I've got two candidate implementations and I'm curious which you like 
>> better and why, or if I'm missing a better way:
>>
>> (defn to-consolidated-map [parts]
>>   (reduce (fn [h [k v]]
>> (if (contains? h k)
>>   (assoc h k (+ (k h) v))
>>   (assoc h k v)))
>>   {} parts))
>>
>> (defn to-consolidated-map [parts]
>> (->> parts
>>(group-by first)
>>(map (fn [[k v]] [k (->> v (map last) (reduce +))]
>>
>> TIA,
>> David
>>
>

-- 
-- 
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-17 Thread Steven Degutis
Oh. Wow, I should read the whole thread before posting. Seems like
merge-with is what I was looking for. Although, lately both partial and
apply make me a little uneasy in terms of efficiency. But that's easily
enough solved with an anonymous function, which I don't think is any less
readable (maybe even more readable):

(apply merge-with + (map (fn [[k v]] {k v}) the-map))

-Steven


On Sat, Aug 17, 2013 at 3:42 AM, Steven Degutis  wrote:

> Wow. Sorry for the awful formatting. Re-pasting it from Google Groups
> (instead of email) to fix it:
>
> (def a [[:a 1] [:b 2] [:a 3]])
>
>
>
> (defn add-maybe [& nums]
>
>   (->> nums
>
>(remove nil?)
>
>(reduce +)))
>
>
>
> (reduce (fn [m [k v]]
>
>   (update-in m [k] add-maybe v))
>
> {}
>
> a)
>
>
>
> ;; => {:b 2, :a 4}
>
>
> -Steven
>
> On Saturday, August 17, 2013 3:40:23 AM UTC-5, Steven Degutis wrote:
>
>> At first I came up with the same solution as your second one. But I
>> couldn't help but feel that it wasn't descriptive enough. It felt too
>> incidental-complexity-ish.
>>
>> To me, (into {} the-map) seems mostly right. But obviously it would just
>> squash the values you need. So I figured it should just be modified a bit.
>> Seeing as how it's really short for reduce conj, I figured conj was the
>> place to swap out.
>>
>> Here's what I came up with:
>>
>> (def the-map [[:a 1] [:b 2] [:a 3]])
>>
>>
>>
>>
>> (defn add-maybe [& nums]
>>
>>
>>   (->> nums
>>
>>(remove nil?)
>>
>>
>>(reduce +)))
>>
>>
>>
>> (reduce (fn [m [k v]]
>>
>>
>>   (update-in m [k] add-maybe v))
>>
>>
>> {}
>>
>> the-map)
>>
>>
>>
>> ;; => {:b 2, :a 4}
>>
>>
>> But I don't really like the add-maybe function. It seems like I'm
>> probably missing an opportunity for a core-lib function that I'm forgetting
>> about. I really just wanted to have access to the original value, so I
>> could do (or orig-value 0) and then just use + instead of add-maybe.
>>
>> -Steven
>>
>>
>> On Fri, Aug 16, 2013 at 11:57 PM, David Chelimsky wrote:
>>
>>> I've got a vector of 2-element vectors e.g. [[:a 1] [:b 2]] where the
>>> first val of any vec might appear in another vec e.g. [[:a 1] [:b 2] [:a
>>> 3]]. I need a fn that will consolidate this into a hash-map with the vals
>>> consolidated e.g.
>>>
>>> (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
>>> ; {:a 4 :b 2}
>>>
>>> I've got two candidate implementations and I'm curious which you like
>>> better and why, or if I'm missing a better way:
>>>
>>> (defn to-consolidated-map [parts]
>>>   (reduce (fn [h [k v]]
>>> (if (contains? h k)
>>>   (assoc h k (+ (k h) v))
>>>   (assoc h k v)))
>>>   {} parts))
>>>
>>> (defn to-consolidated-map [parts]
>>> (->> parts
>>>(group-by first)
>>>(map (fn [[k v]] [k (->> v (map last) (reduce +))]
>>>
>>> TIA,
>>> David
>>>
>>  --
> --
> 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: vec to map with consolidated vals

2013-08-17 Thread David Chelimsky
Hey Steven, here's a variation of my first example that, I think, gets
closer to what you're proposing (with maybe-add handled in-line):

(defn to-consolidated-map [parts]
  (reduce (fn [h [k v]]
(assoc h k (+ (get h k 0) v)))
  {}
  parts))

Using assoc instead of update-in allows it to handle nils with a default
value to get. All core lib fns. WDYT?

Also, this:

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

or this variant:

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

each use only core lib fns, which you say you're looking for. I find this
less accidental-complexity-ish than the implementations that use reduce
with a custom (anonymous) fn, which each require handling nil in some
fashion. WDYT?




On Sat, Aug 17, 2013 at 10:42 AM, Steven Degutis wrote:

> Wow. Sorry for the awful formatting. Re-pasting it from Google Groups
> (instead of email) to fix it:
>
> (def a [[:a 1] [:b 2] [:a 3]])
>
>
>
> (defn add-maybe [& nums]
>
>   (->> nums
>
>(remove nil?)
>
>(reduce +)))
>
>
>
> (reduce (fn [m [k v]]
>
>   (update-in m [k] add-maybe v))
>
> {}
>
> a)
>
>
>
> ;; => {:b 2, :a 4}
>
>
> -Steven
>
> On Saturday, August 17, 2013 3:40:23 AM UTC-5, Steven Degutis wrote:
>
>> At first I came up with the same solution as your second one. But I
>> couldn't help but feel that it wasn't descriptive enough. It felt too
>> incidental-complexity-ish.
>>
>> To me, (into {} the-map) seems mostly right. But obviously it would just
>> squash the values you need. So I figured it should just be modified a bit.
>> Seeing as how it's really short for reduce conj, I figured conj was the
>> place to swap out.
>>
>> Here's what I came up with:
>>
>> (def the-map [[:a 1] [:b 2] [:a 3]])
>>
>>
>>
>>
>> (defn add-maybe [& nums]
>>
>>
>>   (->> nums
>>
>>(remove nil?)
>>
>>
>>(reduce +)))
>>
>>
>>
>> (reduce (fn [m [k v]]
>>
>>
>>   (update-in m [k] add-maybe v))
>>
>>
>> {}
>>
>> the-map)
>>
>>
>>
>> ;; => {:b 2, :a 4}
>>
>>
>> But I don't really like the add-maybe function. It seems like I'm
>> probably missing an opportunity for a core-lib function that I'm forgetting
>> about. I really just wanted to have access to the original value, so I
>> could do (or orig-value 0) and then just use + instead of add-maybe.
>>
>> -Steven
>>
>>
>> On Fri, Aug 16, 2013 at 11:57 PM, David Chelimsky wrote:
>>
>>> I've got a vector of 2-element vectors e.g. [[:a 1] [:b 2]] where the
>>> first val of any vec might appear in another vec e.g. [[:a 1] [:b 2] [:a
>>> 3]]. I need a fn that will consolidate this into a hash-map with the vals
>>> consolidated e.g.
>>>
>>> (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
>>> ; {:a 4 :b 2}
>>>
>>> I've got two candidate implementations and I'm curious which you like
>>> better and why, or if I'm missing a better way:
>>>
>>> (defn to-consolidated-map [parts]
>>>   (reduce (fn [h [k v]]
>>> (if (contains? h k)
>>>   (assoc h k (+ (k h) v))
>>>   (assoc h k v)))
>>>   {} parts))
>>>
>>> (defn to-consolidated-map [parts]
>>> (->> parts
>>>(group-by first)
>>>(map (fn [[k v]] [k (->> v (map last) (reduce +))]
>>>
>>> TIA,
>>> David
>>>
>>  --
> --
> 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: vec to map with consolidated vals

2013-08-17 Thread David Chelimsky
Sorry - pressed send before refreshing and didn't see your response.

Readability is a very subjective topic. I have an (possibly irrational)
aversion to anonymous fns when core fns solve the same problem, so I'm very
accustomed to reading things like (partial apply xxx). The perf issue would
definitely push me over, however.




On Sat, Aug 17, 2013 at 11:19 AM, David Chelimsky wrote:

> Hey Steven, here's a variation of my first example that, I think, gets
> closer to what you're proposing (with maybe-add handled in-line):
>
> (defn to-consolidated-map [parts]
>   (reduce (fn [h [k v]]
> (assoc h k (+ (get h k 0) v)))
>   {}
>   parts))
>
> Using assoc instead of update-in allows it to handle nils with a default
> value to get. All core lib fns. WDYT?
>
> Also, this:
>
>   (defn to-consolidated-map [parts]
> (apply merge-with + (map (partial apply hash-map) parts)))
>
> or this variant:
>
>   (defn to-consolidated-map [parts]
> (->> parts (map (partial apply hash-map)) (apply merge-with +))
>
> each use only core lib fns, which you say you're looking for. I find this
> less accidental-complexity-ish than the implementations that use reduce
> with a custom (anonymous) fn, which each require handling nil in some
> fashion. WDYT?
>
>
>
>
> On Sat, Aug 17, 2013 at 10:42 AM, Steven Degutis wrote:
>
>> Wow. Sorry for the awful formatting. Re-pasting it from Google Groups
>> (instead of email) to fix it:
>>
>> (def a [[:a 1] [:b 2] [:a 3]])
>>
>>
>>
>> (defn add-maybe [& nums]
>>
>>   (->> nums
>>
>>(remove nil?)
>>
>>(reduce +)))
>>
>>
>>
>> (reduce (fn [m [k v]]
>>
>>   (update-in m [k] add-maybe v))
>>
>> {}
>>
>> a)
>>
>>
>>
>> ;; => {:b 2, :a 4}
>>
>>
>> -Steven
>>
>> On Saturday, August 17, 2013 3:40:23 AM UTC-5, Steven Degutis wrote:
>>
>>> At first I came up with the same solution as your second one. But I
>>> couldn't help but feel that it wasn't descriptive enough. It felt too
>>> incidental-complexity-ish.
>>>
>>> To me, (into {} the-map) seems mostly right. But obviously it would just
>>> squash the values you need. So I figured it should just be modified a bit.
>>> Seeing as how it's really short for reduce conj, I figured conj was the
>>> place to swap out.
>>>
>>> Here's what I came up with:
>>>
>>> (def the-map [[:a 1] [:b 2] [:a 3]])
>>>
>>>
>>>
>>>
>>> (defn add-maybe [& nums]
>>>
>>>
>>>   (->> nums
>>>
>>>(remove nil?)
>>>
>>>
>>>(reduce +)))
>>>
>>>
>>>
>>> (reduce (fn [m [k v]]
>>>
>>>
>>>   (update-in m [k] add-maybe v))
>>>
>>>
>>> {}
>>>
>>> the-map)
>>>
>>>
>>>
>>> ;; => {:b 2, :a 4}
>>>
>>>
>>> But I don't really like the add-maybe function. It seems like I'm
>>> probably missing an opportunity for a core-lib function that I'm forgetting
>>> about. I really just wanted to have access to the original value, so I
>>> could do (or orig-value 0) and then just use + instead of add-maybe.
>>>
>>> -Steven
>>>
>>>
>>> On Fri, Aug 16, 2013 at 11:57 PM, David Chelimsky wrote:
>>>
 I've got a vector of 2-element vectors e.g. [[:a 1] [:b 2]] where the
 first val of any vec might appear in another vec e.g. [[:a 1] [:b 2] [:a
 3]]. I need a fn that will consolidate this into a hash-map with the vals
 consolidated e.g.

 (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
 ; {:a 4 :b 2}

 I've got two candidate implementations and I'm curious which you like
 better and why, or if I'm missing a better way:

 (defn to-consolidated-map [parts]
   (reduce (fn [h [k v]]
 (if (contains? h k)
   (assoc h k (+ (k h) v))
   (assoc h k v)))
   {} parts))

 (defn to-consolidated-map [parts]
 (->> parts
(group-by first)
(map (fn [[k v]] [k (->> v (map last) (reduce +))]

 TIA,
 David

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

Re: vec to map with consolidated vals

2013-08-17 Thread Jay Fields
Of your proposed solutions, this one

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

Is the one I thought of first and also find very readable.

On Saturday, August 17, 2013, David Chelimsky wrote:

> Sorry - pressed send before refreshing and didn't see your response.
>
> Readability is a very subjective topic. I have an (possibly irrational)
> aversion to anonymous fns when core fns solve the same problem, so I'm very
> accustomed to reading things like (partial apply xxx). The perf issue would
> definitely push me over, however.
>
>
>
>
> On Sat, Aug 17, 2013 at 11:19 AM, David Chelimsky wrote:
>
> Hey Steven, here's a variation of my first example that, I think, gets
> closer to what you're proposing (with maybe-add handled in-line):
>
> (defn to-consolidated-map [parts]
>   (reduce (fn [h [k v]]
> (assoc h k (+ (get h k 0) v)))
>   {}
>   parts))
>
> Using assoc instead of update-in allows it to handle nils with a default
> value to get. All core lib fns. WDYT?
>
> Also, this:
>
>   (defn to-consolidated-map [parts]
> (apply merge-with + (map (partial apply hash-map) parts)))
>
> or this variant:
>
>   (defn to-consolidated-map [parts]
> (->> parts (map (partial apply hash-map)) (apply merge-with +))
>
> each use only core lib fns, which you say you're looking for. I find this
> less accidental-complexity-ish than the implementations that use reduce
> with a custom (anonymous) fn, which each require handling nil in some
> fashion. WDYT?
>
>
>
>
> On Sat, Aug 17, 2013 at 10:42 AM, Steven Degutis wrote:
>
> Wow. Sorry for the awful formatting. Re-pasting it from Google Groups
> (instead of email) to fix it:
>
> (def a [[:a 1] [:b 2] [:a 3]])
>
>
>
> (defn add-maybe [& nums]
>
>   (->> nums
>
>(remove nil?)
>
>(reduce +)))
>
>
>
> (reduce (fn [m [k
>
>

-- 
-- 
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: function creation, partial or #()

2013-08-17 Thread Jay Fields
Thanks everyone. Seems like there's pretty solid agreement on which
solution is preferred.

Cheers, Jay

On Saturday, August 17, 2013, David Chelimsky wrote:

> On Fri, Aug 16, 2013 at 9:49 PM, Gregg Reynolds 
> 
> > wrote:
>
>> On Tue, Aug 13, 2013 at 1:50 PM, John D. Hume 
>> > 'duelin.mark...@gmail.com');>>
>> wrote:
>> > Though in some cases the performance impact could be significant, my
>> concern
>> > is readability. My understanding of the concept of partial function
>> > application is that it's about supplying some but not all of the
>> arguments.
>> > So when I see `partial` in code, I expect more arguments to be supplied
>> > later, which is confusing when that's not the case. (Obviously context
>> can
>> > make it easy to see that there will be no more arguments, but often that
>> > context is not present.)
>> >
>>
>> +1.  Using partial to convert a unary func into a nullary func when
>> #() is available strikes me as malpractice.  Suppose you were to come
>> across something like this in legacy code:
>>
>> >> (do-work (partial say-hello "bob"))
>>
>> For me, the natural inference would be that say-hello must want at
>> least one more arg (otherwise why partial?), so do-work must be
>> feeding some arg to the result of (partial say-hello "bob"), like
>> adding "Don't worry, we're not watching you", in case the NSA owns
>> do-work.  Execution efficiency aside, downstream programmer confusion
>> due to implied semantics also has a cost.
>>
>> -Gregg
>>
>
> I agree w/ John and Gregg, though I don't think I'd sue you for
> malpractice ;) partial means something and using it this way gives it a
> different meaning, even if it happens to solve the problem at hand.
>
> --
> --
> 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 '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  'clojure%2bunsubscr...@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  'clojure%2bunsubscr...@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: function creation, partial or #()

2013-08-17 Thread Jay Fields
Sean, it sounds like you want

(swap! some-a update-in [:k1 :k2] (fnil conj []) id)

But that's based on some pretty limited context.

On Friday, August 16, 2013, Sean Corfield wrote:

> On Fri, Aug 16, 2013 at 4:32 PM, Timothy Baldridge 
> >
> wrote:
> > I'm just going to throw this out there, but I almost always consider
> using
> > #() instead of (fn []) to be bad practice.
>
> I still use #() for anonymous single argument functions that are
> small, single forms, but I've started switching to (fn [..] ..) for
> anything even slightly more complex because, like you, I find having a
> named argument to be worth the extra typing, even if it is just a
> single letter, suggestive of the argument type.
>
> Today I found myself writing (fnil #(conj % id) []) a couple of times
> because (fnil (fn [v] (conj v id)) []) doesn't seem any clearer - but
> suggestions for nicer code are always welcome. It's part of (swap!
> some-atom update-in [:path :to :item] ...) if that helps :)
>
> Sean
>
> --
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com 
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com .
> For more options, visit https://groups.google.com/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.


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

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: 

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


Help to start creating this DSL in Clojure

2013-08-17 Thread Hussein B.
Hi, 

I'm trying to create this Domain Specific Language:

(query "clojure"
  (directory "/usr/texts")
  (group-by :creation-date))

What it should do is to search for all files in a specific directory using 
a regexp and then group the result by some of files attributes.

The idea is the (query) created a RegExp object. (directory) to specify 
which directory to scan. (group-by) is to group the files names by 
creation-date of the files.

(query) will use Java RegExp library. (directory) will use java.io package. 

** I know that I can use Clojure functions for RegExp and IO but I want to 
try to create it using Java libraries **

Any starting points are really appreciated.

Thanks for help and 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/groups/opt_out.


Re: Help to start creating this DSL in Clojure

2013-08-17 Thread Michael Klishin
Hussein B.:

> Hi, 
>
> I'm trying to create this Domain Specific Language:
>
> (query "clojure"
>   (directory "/usr/texts")
>   (group-by :creation-date))
>
>
>  

> Any starting points are really appreciated.
>
>
Take a look at 
http://clojure-doc.org/articles/tutorials/growing_a_dsl_with_clojure.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/groups/opt_out.


Re: Generating a "Java bean" via Clojure?

2013-08-17 Thread Ryan Brush
Some Java frameworks will accept public final fields as Java bean fields. 
In that case, a Clojure record can be used directly (although I'm not sure 
if we're making an assumption about Clojure records that might change). 
This has actually worked for my limited needs in this space.

The only other cases I've run into this are instances where I wanted to 
create a first-class Java (and javadoc'd) API for consumers, so I wrote a 
Java interface that followed JavaBean conventions, and simply reified it in 
Clojure. 

That all said, if I had to do this often (I haven't), I probably would have 
written some form of defbean macro that created a record and the 
corresponding getters for Java land. Unfortunately I'm not aware of such a 
thing, but it seems like it would be straightforward to implement.

On Friday, August 16, 2013 12:29:40 PM UTC-5, Sean Corfield wrote:
>
> I was working with a Java library recently and needed to create a 
> "Java bean" to pass into it. It can be done via `gen-class` but it 
> seems kind of verbose having to explicitly write out all of the 
> getters and setters, and it seems you could also do it via `deftype` 
> but that's also rather painful (I started looking at that in the hope 
> of automating it via a macro but it seemed difficult to have 
> overloaded constructors and I needed both a no-arg constructor and one 
> that took all the bean attributes). 
>
> What do people do when they need a "Java bean" for interop when using 
> Clojure with a Java library? This seems like it should be common 
> enough that I would have expected it to be part of clojure.java.data 
> but it isn't... 
>
> Just a class name and a list of property names and (perhaps optional) 
> types should be all the ceremony we need to write... and I don't want 
> to reinvent the wheel if that is already out there somewhere? 
> -- 
> Sean A Corfield -- (904) 302-SEAN 
> An Architect's View -- http://corfield.org/ 
> World Singles, LLC. -- http://worldsingles.com/ 
>
> "Perfection is the enemy of the good." 
> -- Gustave Flaubert, French realist novelist (1821-1880) 
>

-- 
-- 
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] Leiningen 2.3.1 released

2013-08-17 Thread James Qiu
After upgrade to 2.3.1, I can't find "repl-port" file in target directory,
so "lein repl" will use a random port, I have to use "LEIN_REPL_PORT=33021
lein repl" to assign the port.


2013/8/14 Sean Corfield 

> Thank you!
>
> I've upgraded our team to 2.3.1, as well as our QA system. So far, no
> problems.
>
> Sean
>
> On Tue, Aug 13, 2013 at 10:37 AM, Phil Hagelberg  wrote:
> >
> > Hello folks.
> >
> > With some help from Nelson Morris I've pushed out the 2.3.1 release of
> > Leiningen. This fixes the self-install issues as well as the issue
> > around AOT classes not being included in jar files. It also adds a new
> > flag (:monkeypatch-clojure-test false) you can use to disable
> > Leiningen's monkeypatch of the `clojure.test` library.
> >
> > As usual, if you installed manually you can upgrade with `lein
> > upgrade`. If you need to back out for some reason, you can downgrade with
> > `lein upgrade 2.2.0`.
> >
> > -Phil
>
>
>
> --
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
> World Singles, LLC. -- http://worldsingles.com/
>
> "Perfection is the enemy of the good."
> -- Gustave Flaubert, French realist novelist (1821-1880)
>
> --
> --
> 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: Gensym collisions can be engineered.

2013-08-17 Thread J.-F. Rompre
Interesting discussion - I was pretty surprised to see this can happen

I don't understand all the details about the solutions discussed in this 
thread, but it seems that the only way to ensure no local can be clobbered, 
gensym'ed or not, is to introduce into the RT a "local resolution phase"  
table which maps all user (as found in code) symbols in the current scope 
to a unique symbol - sort of a "gensym for regular vars", to that in the 
following example, the local G__2244 defined by the user would get remapped 
internally.
The table could be wiped out at the end of its scope...admittedly this is 
probably a challenge to provide for nested scopes.

(defmacro clobber [ & forms ] 
 (let [ club (gensym) ] 
   `(let [ ~club "squirrel" ] 
   ~@forms
 ;;the following to help find a clobbered var 
in the scope 
 ;; enclosing the macro call 
 (println "clobbering symbol: " '~club)
)))

 give it a few REPL (gensym) tries, and:

user=> (let [ G__2244 "mountain lion" ] (clobber (println "I am a " 
G__2244)))
I am a  squirrel
clobbering symbol:  G__2244



On Saturday, November 7, 2009 11:59:08 PM UTC-5, John Harrop wrote:
>
> user=> (def q 'G__723)
> #'user/q
> user=> (def r (gensym))
> #'user/r
> user=> q
> G__723
> user=> r
> G__723
> user=> (= q r)
> true
>
> It's possible to anticipate the next gensym name that will be generated 
> and then engineer a collision, and therefore possibly variable capture 
> unintended by the author of a macro.
>
> It looks like "manually" generating a name does not remove it from the 
> pool of allowable future gensym names.
>
> This shouldn't tend to cause accidental problems in practice, since gensym 
> names tend not to collide with the kinds of identifiers programmers 
> ordinarily use. Nonetheless it can be partially fixed comparatively easily 
> by adding to the runtime a WeakHashMap into which a reference to any 
> symbol, however created, is placed and modifying the gensym-generator to, 
> at the point where it currently returns a value, first check if the 
> WeakHashMap contains it already and if so, generate the next one, and the 
> next, as needed until it gets a not-in-use name. This requires gensym 
> creation and normal symbol creation to occur in a global lock but symbol 
> creation rarely occurs at runtime and even more rarely in any kind of 
> hot-spot at runtime. The use of WeakHashMap would prevent the runtime 
> clogging up with ungarbagecollectable symbols, so the memory overhead of 
> adding this would be smallish, one machine pointer per in-use symbol or so, 
> equivalent to if every symbol had a few more characters in its name.
>
> This would stop gensym from producing a name already in use. It wouldn't 
> prevent a gensym being generated somewhere and *then* the identical name 
> being put together someplace else and passed to the symbol function, 
> though; a small loophole. Collisions between gensyms in preexisting code 
> and an enclosing lexical scope in new code would become impossible, but 
> collisions between gensyms in preexisting code and an enclosed lexical 
> scope (e.g. a macro-invocation body, such as a loop body) would remain 
> theoretically possible.
>
> That last loophole can't really be plugged without giving Clojure "true" 
> gensyms (uninterned anywhere), which would bring with it its own 
> architectural problems. If that change were made, the above REPL 
> interaction would be possible up to the (= q r) evaluation, but that would 
> return false despite the names looking the same, so the symbols wouldn't 
> really collide even though a collision of their printed representations 
> could still be engineered. One bothersome consequence though would be that 
> the textual output of macroexpand-1 could no longer always be substituted 
> for a macro call in source code without altering the run-time semantics of 
> that code, even when the macro's expansion-generation does not have side 
> effects.
>
> (To reproduce that REPL interaction for yourself, evaluate (gensym) at the 
> REPL and note the number. Add seven and then evaluate (def q 'G__#) with # 
> replaced with the sum. Then evaluate (def r (gensym)) and, if you like, 
> skip straight to (= q r). If that doesn't work, the number it goes up by 
> must have changed between Clojure 1.0 and whatever version you're using; 
> evaluate (gensym), then (def q 'xyzzy), then (gensym) again and note the 
> increment and use that instead of seven. Oh, and don't have any background 
> threads running in that JVM instance that might do something autonomously 
> that causes a gensym to be generated.)
>
>

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

Re: vec to map with consolidated vals

2013-08-17 Thread Steven Degutis
Yeah, I totally agree that using core fns instead of anonymous fns makes
code way more readable and easier to mentally scan. The main reason I
suggested the anonymous function was for performance, which is probably
premature-optimization at this point. But I think I agree with you and Jay,
that short one is probably best.

Also I agree that your solution with (get) is better than the (update-in)
version I had for the reasons you mentioned.

-Steven


On Sat, Aug 17, 2013 at 4:28 AM, David Chelimsky wrote:

> Sorry - pressed send before refreshing and didn't see your response.
>
> Readability is a very subjective topic. I have an (possibly irrational)
> aversion to anonymous fns when core fns solve the same problem, so I'm very
> accustomed to reading things like (partial apply xxx). The perf issue would
> definitely push me over, however.
>
>
>
>
> On Sat, Aug 17, 2013 at 11:19 AM, David Chelimsky wrote:
>
>> Hey Steven, here's a variation of my first example that, I think, gets
>> closer to what you're proposing (with maybe-add handled in-line):
>>
>> (defn to-consolidated-map [parts]
>>   (reduce (fn [h [k v]]
>> (assoc h k (+ (get h k 0) v)))
>>   {}
>>   parts))
>>
>> Using assoc instead of update-in allows it to handle nils with a default
>> value to get. All core lib fns. WDYT?
>>
>> Also, this:
>>
>>   (defn to-consolidated-map [parts]
>> (apply merge-with + (map (partial apply hash-map) parts)))
>>
>> or this variant:
>>
>>   (defn to-consolidated-map [parts]
>> (->> parts (map (partial apply hash-map)) (apply merge-with +))
>>
>> each use only core lib fns, which you say you're looking for. I find this
>> less accidental-complexity-ish than the implementations that use reduce
>> with a custom (anonymous) fn, which each require handling nil in some
>> fashion. WDYT?
>>
>>
>>
>>
>> On Sat, Aug 17, 2013 at 10:42 AM, Steven Degutis wrote:
>>
>>> Wow. Sorry for the awful formatting. Re-pasting it from Google Groups
>>> (instead of email) to fix it:
>>>
>>> (def a [[:a 1] [:b 2] [:a 3]])
>>>
>>>
>>>
>>> (defn add-maybe [& nums]
>>>
>>>   (->> nums
>>>
>>>(remove nil?)
>>>
>>>(reduce +)))
>>>
>>>
>>>
>>> (reduce (fn [m [k v]]
>>>
>>>   (update-in m [k] add-maybe v))
>>>
>>> {}
>>>
>>> a)
>>>
>>>
>>>
>>> ;; => {:b 2, :a 4}
>>>
>>>
>>> -Steven
>>>
>>> On Saturday, August 17, 2013 3:40:23 AM UTC-5, Steven Degutis wrote:
>>>
 At first I came up with the same solution as your second one. But I
 couldn't help but feel that it wasn't descriptive enough. It felt too
 incidental-complexity-ish.

 To me, (into {} the-map) seems mostly right. But obviously it would
 just squash the values you need. So I figured it should just be modified a
 bit. Seeing as how it's really short for reduce conj, I figured conj was
 the place to swap out.

 Here's what I came up with:

 (def the-map [[:a 1] [:b 2] [:a 3]])





 (defn add-maybe [& nums]


   (->> nums

(remove nil?)


(reduce +)))



 (reduce (fn [m [k v]]



   (update-in m [k] add-maybe v))



 {}

 the-map)



 ;; => {:b 2, :a 4}


 But I don't really like the add-maybe function. It seems like I'm
 probably missing an opportunity for a core-lib function that I'm forgetting
 about. I really just wanted to have access to the original value, so I
 could do (or orig-value 0) and then just use + instead of add-maybe.

 -Steven


 On Fri, Aug 16, 2013 at 11:57 PM, David Chelimsky wrote:

> I've got a vector of 2-element vectors e.g. [[:a 1] [:b 2]] where the
> first val of any vec might appear in another vec e.g. [[:a 1] [:b 2] [:a
> 3]]. I need a fn that will consolidate this into a hash-map with the vals
> consolidated e.g.
>
> (to-consolidated-map [[:a 1] [:b 2] [:a 3]])
> ; {:a 4 :b 2}
>
> I've got two candidate implementations and I'm curious which you like
> better and why, or if I'm missing a better way:
>
> (defn to-consolidated-map [parts]
>   (reduce (fn [h [k v]]
> (if (contains? h k)
>   (assoc h k (+ (k h) v))
>   (assoc h k v)))
>   {} parts))
>
> (defn to-consolidated-map [parts]
> (->> parts
>(group-by first)
>(map (fn [[k v]] [k (->> v (map last) (reduce +))]
>
> TIA,
> David
>
  --
>>> --
>>> 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

Re: logback.xml being picked up twice in project (how do I surpess the inheritted projects logback.xml)?

2013-08-17 Thread Stephen Cagle
Thanks Laurent, I did as you suggest and things seem to be fine now. I 
ended up using :profiles => :dev  => :source-paths in my project.clj to 
include the 'dev-resources' directory. Seems to be in use when I lein repl, 
but is not included when I build a jar. Probably there are other problems 
with that, but it seems to work well enough for me.
  

On Thursday, August 15, 2013 11:39:19 PM UTC-7, Laurent PETIT wrote:
>
> 2013/8/16 Stephen Cagle >: 
> > Sorry if I am being dense, just want to make sure I understand what you 
> are 
> > saying... 
> > 
> > So, I was including logback.xml in my git source control. I take it you 
> > would say that is a bad idea? I thought it made sense as I then have it 
> as 
> > part of the project, but I suppose it could get in the way in situations 
> > like this. Do you gitignore your logback.xml and just have a custom 
> > logback.xml specified with "logback.configurationFile" for different 
> aspects 
> > (development, testing, production)? 
>
> A simple configuration idea (supposing you are using leiningen for 
> projects base and derive, and that you own both projects so you can 
> make changes to both). 
>
> base plays the role of a "library". A library should not impose 
> logging settings on the final products that will use it. But you still 
> need a logging file to test the library ! Just put a logback-test.xml 
> file in your dev-resources directory. It's fine to have it in git, 
> then, since it won't be part of the final jar now, it's all that 
> matters. 
>
> You do this for each "library" in your application. 
>
> For the final product, the one you deliver, you can just have 2 
> configurations, one for test, one while developing: 
>
> - place a file logback-test.xml in dev-resources. When it is present, 
> it will be picked first, meaning it will be picked first in your local 
> machine. 
> - place the production file logback.xml in resources. 
>
> This is a simple settings. It doesn't handle the case where you want 
> different logback.xml files for test, staging and prod servers, for 
> instance. YMMV. 
>
> > 
> > 
> > On Thursday, August 15, 2013 5:16:24 PM UTC-7, Jason Bennett wrote: 
> >> 
> >> The trick is, don't build the original jar with the logback config 
> file. 
> >> No dependent of that jar wants to be told how to do logging. You should 
> keep 
> >> your logback.xml in the /config directory, not in /resources. 
> >> 
> >> As far as -D, that's to pass environment parameters to the JVM. See 
> >> http://logback.qos.ch/manual/configuration.html#configFileProperty for 
> how 
> >> to configure the logback.xml location that way. 
> >> 
> >> To recap: don't include logback.xml in any jars, anywhere (except for 
> test 
> >> versions, which logback supports). Have it living in production on the 
> file 
> >> system, and point to that file on startup. That way, you can have 
> >> environment-specific logging configured in that environment. 
> >> 
> >> jason 
> >> 
> >> 
> >> 
> >> On Thu, Aug 15, 2013 at 5:06 PM, Stephen Cagle  
> wrote: 
> >>> 
> >>> I don't know what -D is, other than a one eyed laughing face. :D 
> >>> 
> >>> Is there some sort of standard for this? Do people simply write a 
> script 
> >>> that checks out the code and remove files that they don't want in the 
> >>> generated jar? Is there something I can put in my project.clj that 
> specifies 
> >>> what I don't want included in a generated jar? How do people generally 
> go 
> >>> about it. 
> >>> 
> >>> Not that it is a big deal, mind you. It just seems a bit busy to have 
> to 
> >>> write a special script that 1) checks out my code from github 
> 2)removes the 
> >>> files I don't want in the jar 3) builds the jar 4) does whatever else 
> I am 
> >>> forgetting. Seems like there might be something simpler that I don't 
> know 
> >>> about. 
> >>> 
> >>> 
> >>> On Thursday, August 15, 2013 4:38:01 PM UTC-7, Jason Bennett wrote: 
>  
>  You shouldn't include the logback.xml in the generated jar file. 
>  
>  Only the ultimately generated artifact should have a logback.xml 
> file, 
>  best loaded from the file system (possibly through -D). It doesn't 
> matter 
>  what settings base has for logging, derive should set all logging 
>  parameters. 
>  
>  jason 
>  
>  On Thursday, August 15, 2013 3:51:04 PM UTC-7, Stephen Cagle wrote: 
> > 
> > I have project 'base' that has a logback.xml file and project 
> 'derive' 
> > that also has a logback.xml file. Project 'derive' has a dependency 
> on 
> > 'base'. When I "lein trampoline repl" on project 'derive', I get the 
> > following warning. 
> > 
> >  
> > 15:34:30,066 |-INFO in ch.qos.logback.classic.LoggerContext[default] 
> - 
> > Could NOT find resource [logback.groovy] 
> > 15:34:30,066 |-INFO in ch.qos.logback.classic.LoggerContext[default] 
> - 
> > Could NOT find resource [logback-test.xml] 
> > 15:34:30,066 |-INFO in ch.qos

Re: function creation, partial or #()

2013-08-17 Thread Sean Corfield
Gosh darn... yes, that is what I want. That must be the only
combination of things I didn't try! Thank you.

On Sat, Aug 17, 2013 at 4:18 AM, Jay Fields  wrote:
> Sean, it sounds like you want
>
> (swap! some-a update-in [:k1 :k2] (fnil conj []) id)
>
> But that's based on some pretty limited context.
>
>
> On Friday, August 16, 2013, Sean Corfield wrote:
>>
>> On Fri, Aug 16, 2013 at 4:32 PM, Timothy Baldridge 
>> wrote:
>> > I'm just going to throw this out there, but I almost always consider
>> > using
>> > #() instead of (fn []) to be bad practice.
>>
>> I still use #() for anonymous single argument functions that are
>> small, single forms, but I've started switching to (fn [..] ..) for
>> anything even slightly more complex because, like you, I find having a
>> named argument to be worth the extra typing, even if it is just a
>> single letter, suggestive of the argument type.
>>
>> Today I found myself writing (fnil #(conj % id) []) a couple of times
>> because (fnil (fn [v] (conj v id)) []) doesn't seem any clearer - but
>> suggestions for nicer code are always welcome. It's part of (swap!
>> some-atom update-in [:path :to :item] ...) if that helps :)
>>
>> Sean
>>
>> --
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/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.



-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

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


Current state of the art in Web deployment?

2013-08-17 Thread John Jacobsen
Hi folks,

I'm starting work on a Clojure Web app and would like to get a sense for 
the current "standard" (if any) for deploying to production.  In my case, I 
have an AWS Ubuntu instance, set up via Vagrant and Puppet, which mirrors 
some developer VMs.  Datomic, leiningen etc. are running everywhere happily.

After some prototyping and development, we are now getting to the stage 
where "lein run" and a Jetty server running from -main aren't going to cut 
it.  I would like to get a sense for what people do now -- the story 
painted by Google / StackOverflow seems all over the place.  Let's assume 
Heroku and Google App Engine are out of the picture, and that we are 
non-expert in terms of traditional Java approaches for Web apps (I'm coming 
mostly from a Python/Django background).

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

Not too active on this list so if my question can be improved, I'm happy to 
hear that as well.

Thanks, awesome Clojure community!!

John

-- 
-- 
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: Do you like the Clojure syntax?

2013-08-17 Thread Tj Gabbour
Hi,

Random thought from a very tired person. :)

Programmers manipulate tiny pieces of reality, so tiny that quantum effects 
come into play. [1]

Many of us (unknowingly) train our visual senses to help us calculate these 
strange manipulations with less strain. Maybe if we train it on too narrow 
a range of notations, it's harder to extend this training to slightly 
perturbed ones. [2]

Lisp + Paredit helps me train kinesthetic parts too. The effects are maybe 
too submerged for me to introspect [3], but Lisp is oddly close to things 
my hands manipulate in normal life. I commonly hold groups of things. Those 
things may be delimited by enclosing objects; between them may lie 
empty-looking space.

(Of course, in daily life I'm not causing things to suddenly blink out of 
existence or be enclosed. But my body seems to adjust to the concept fine.)

Lisp representation may just be symbolic, but manipulating it isn't only 
like text editing. It lends itself to structure editing. [4]

BTW, this post isn't about Lisp is better than language X. If someone like 
likes X better than Lisp, then cheers.


All the best,
  Tj


[1] 
http://physics.stackexchange.com/questions/11567/is-quantum-physics-used-in-manufacturing-cpus

[2] Given that Lisp syntax isn't merely aesthetic, but radically simplifies 
some things, it should often be worth the retraining.

BTW, programming languages are artificial sorts of languages. Humans have 
enormous difficulty with them compared to natural language; if anyone 
claims that C-like languages are easier for humans to compute than Lisp, 
ask for scientific studies. Or simply email Chomsky and ask him.

[3] It's likely good that we have limits to introspection, because 
otherwise we probably couldn't function as well. I suppose this is when 
people start using mystical terms like "intuition".

[4] I vaguely hear manipulating Java under Eclipse may be more advanced 
than Paredit, due to greater engineering effort. But this shouldn't affect 
the analysis.


On Saturday, August 17, 2013 12:47:09 AM UTC+2, frye wrote:
>
> Oh thanks Steven. I've lately been thinking about human cognition, 
> intelligence, etc. So boning up on my Chomsky, Kurzweil, and so on. 
>
> Remember that the original lisp syntax only had a few core features: 
> homoiconicity, first-class functions, recursion, garbage collection, etc. 
> But from this core, the most advance language features have been easily 
> added. Indeed, we're seeing this in real time, in Clojure: immutable data, 
> lazy sequences, concurrent programming with STM, etc. Now, while 
> theoretically possible, I don't think it's really feasible to implement 
> many of these features in Cobol or Pascal - languages from the same era. 
> Even Java has made a very clumsy attempt at closures, etc. But these other 
> languages can't compete with the LISP approach, I think because of their 
> syntax design. 
>
> The human species still has an extremely limited understanding of how 
> consciousness (ie cognition) works. My suspicion though, is that aspect's 
> like the simplicity of lisp's syntax is what keeps it at the bleeding edge 
> of computer science and our notions of computation. As limited as that is. 
>
>
> Tim Washington 
> Interruptsoftware.ca / Bkeeping.com 
>
>
>
> On Fri, Aug 16, 2013 at 5:00 PM, Steven Degutis 
> 
> > wrote:
>
>> Great point Tim. When I first realized that most problems and solutions 
>> are language-agnostic, I started downplaying the importance of syntax. But 
>> now I think they're like apples and oranges. Sure, semantics and syntax 
>> live together, but one's not more important than the other. They're both 
>> important to get right, for different reasons.
>>
>> For instance, while function calls in Ruby are (typically) semantically 
>> similar to in Clojure, destructuring arguments in Ruby is much more limited 
>> than in Clojure, and in Clojure it's much more easily readable as well as 
>> more powerful. This is only a syntax thing though, but it's a powerful 
>> player in the feature-set.
>>
>>
>> On Fri, Aug 16, 2013 at 12:27 PM, Timothy Washington 
>> 
>> > wrote:
>>
>>> I think it's a mistake to discount the importance of syntax to a 
>>> language. Human beings, as a species is heavily symbolic. Think of ancient 
>>> cave paintings, to pictograms, to scripts. We use these symbols to 
>>> communicate with each other, our outside world, and our abstract thoughts. 
>>> Whether it's written / spoken language, or math or music notation, we need 
>>> these symbols - it's a human thing. Dolphins or monkeys, while very 
>>> intelligent, do not, by themselves, use these written symbols to 
>>> communicate with each other. 
>>>
>>> And I think it follows then, that the design of the syntax itself is 
>>> important. It's certainly true that abstract concepts (of computation in 
>>> this case) are the motive for using any given syntax. But the syntax 
>>> impacts and facilitates the kinds of ideas we can have, the ease with

Re: Current state of the art in Web deployment?

2013-08-17 Thread Ray Miller
On 17 August 2013 21:52, John Jacobsen  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: ANN swag a DSL for documenting Compojure routes using Swagger

2013-08-17 Thread ronen
Cool, let me know how it works out for you

On Saturday, August 17, 2013 5:01:46 AM UTC+3, Casper Clausen wrote:
>
> Nice work. Looking forward to giving it a spin.
>
> On Thursday, August 15, 2013 12:13:11 PM UTC+2, ronen wrote:
>>
>> Swagger  is a cool project 
>> for documenting Restful API's, 
>>
>> Swag is a DSL that wraps Compojure routes enabling them to be listed and 
>> described automagically without the need of maintaining json
>>
>> https://github.com/narkisr/swag
>>
>> Feedback is welcome
>> Ronen
>>
>

-- 
-- 
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: What's your preference, partial or closures?

2013-08-17 Thread yair
What do you mean by currying in this context?  Is there a way to do this in 
clojure apart from using partial?

On Saturday, August 17, 2013 10:04:23 AM UTC+10, Sean Corfield wrote:
>
> I went down the partial path for a long time but have moved more and 
> more toward currying and closures lately as it seems to produce 
> cleaner code - and this also seems to be the way Clojure/core have 
> moved with the reducers library and other places...? 
>
> Sean 
>
> On Fri, Aug 16, 2013 at 3:00 PM, Alan Shaw > 
> wrote: 
> > (defn newgrid 
> > 
> >   [m initialize qi qj]... 
> > 
> > 
> > and then (let [init (partial newgrid m initialize)]... 
> > 
> > 
> > Or else: 
> > 
> > 
> > (defn newgrid 
> > 
> >   [m initialize] 
> > 
> >   (fn [qi qj]... 
> > 
> > 
> > and then (let [init (newgrid m initialize)]... 
> > 
> > -- 
> > -- 
> > 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/groups/opt_out. 
>
>
>
> -- 
> Sean A Corfield -- (904) 302-SEAN 
> An Architect's View -- http://corfield.org/ 
> World Singles, LLC. -- http://worldsingles.com/ 
>
> "Perfection is the enemy of the good." 
> -- Gustave Flaubert, French realist novelist (1821-1880) 
>

-- 
-- 
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: core.async - handling nils

2013-08-17 Thread Mikera
My overall sense is that the convenience of using if-let directly in a few 
use cases doesn't justify making channels fall short of being able to send 
arbitrary values (nil specifically, and clearly boolean false can cause 
some problems too). 

I think it would be a much better design to have a sentinel value and a 
couple of specialised functions or macros that can detect  / interact with 
it appropriately. With a sentinel value the key part of your if-recv code 
could just be something like:

`(let [~name ( I ran into the other half of this problem: If you expect nils to signify 
> closed channels, then you can't leverage the logically false nature of nil 
> without excluding explicit boolean false values. Given the pleasant syntax 
> of if-let /  which is defined as follows:
>
> (defmacro if-recv
>   "Reads from port, binding to name. Evaluates the then block if the
>   read was successful. Evaluates the else block if the port was closed."
>   ([[name port :as binding] then]
>`(if-recv ~binding ~then nil))
>   ([[name port] then else]
>`(let [~name (   (if (nil? ~name)
> ~else
> ~then
>
>
> I've considered some alternative core.async designs, such as an additional 
> "done" sentinel value, or a pair of quote/unquote operators (see 
> "reduced"), but nothing seems as simple as just avoiding booleans and nils, 
> as annoying as that is. I'd be curious to here what Rich & team 
> considered and how they're thinking about it. However, my expectation is 
> that the nil approach won't change, since it's pretty much good enough.
>
> On Thursday, August 15, 2013 10:44:48 PM UTC-4, Mikera wrote:
>>
>> Hi all,
>>
>> I'm experimenting with core.async. Most of it is exceptionally good, but 
>> bit I'm finding it *very* inconvenient that nil can't be sent over 
>> channels. In particular, you can't pipe arbitrary Clojure sequences through 
>> channels (since sequences can contain nils). 
>>
>> I see this as a pretty big design flaw given the ubiquity of sequences in 
>> Clojure code - it appears to imply that you can't easily compose channels 
>> with generic sequence-handling code without some pretty ugly special-case 
>> handling.
>>
>> Am I missing something? Is this a real problem for others too? 
>>
>> If it is a design flaw, can it be fixed before the API gets locked down?
>>
>

-- 
-- 
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: What's your preference, partial or closures?

2013-08-17 Thread Sean Corfield
On Sat, Aug 17, 2013 at 5:43 PM, yair  wrote:
> What do you mean by currying in this context?  Is there a way to do this in
> clojure apart from using partial?

(defn some-func
  ([a b c] (process a b c))
  ([a b]   (fn [c] (some-func a b c)))
  ([a] (fn ([b] (fn [c] (some-func a b c)))
   ([b c] (some-func a b c)

(some-func 1 2 3)
((some-func 1 2) 3)
(((some-func 1) 2) 3)
((some-func 1) 2 3)
-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

-- 
-- 
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: core.async - handling nils

2013-08-17 Thread Brandon Bloom
That's precisely the design followed by Magpie, described here:
http://journal.stuffwithstuff.com/2013/04/17/well-done/

Parts 1 & 2 of that series are worth reading too.


On Sat, Aug 17, 2013 at 8:48 PM, Mikera wrote:

> My overall sense is that the convenience of using if-let directly in a few
> use cases doesn't justify making channels fall short of being able to send
> arbitrary values (nil specifically, and clearly boolean false can cause
> some problems too).
>
> I think it would be a much better design to have a sentinel value and a
> couple of specialised functions or macros that can detect  / interact with
> it appropriately. With a sentinel value the key part of your if-recv code
> could just be something like:
>
> `(let [~name (   (if (end-of-stream? ~name)
> ~else
> ~then
>
>
> I can see that wrappers for nil values could also work, but that seems to
> be a more complex solution (and also potentially with more overhead) than a
> sentinel value
>
>
> On Saturday, 17 August 2013 07:50:06 UTC+8, Brandon Bloom wrote:
>
>> I ran into the other half of this problem: If you expect nils to signify
>> closed channels, then you can't leverage the logically false nature of nil
>> without excluding explicit boolean false values. Given the pleasant syntax
>> of if-let / > which is defined as follows:
>>
>> (defmacro if-recv
>>   "Reads from port, binding to name. Evaluates the then block if the
>>   read was successful. Evaluates the else block if the port was closed."
>>   ([[name port :as binding] then]
>>`(if-recv ~binding ~then nil))
>>   ([[name port] then else]
>>`(let [~name (>   (if (nil? ~name)
>> ~else
>> ~then
>>
>>
>> I've considered some alternative core.async designs, such as an
>> additional "done" sentinel value, or a pair of quote/unquote operators (see
>> "reduced"), but nothing seems as simple as just avoiding booleans and nils,
>> as annoying as that is. I'd be curious to here what Rich & team
>> considered and how they're thinking about it. However, my expectation is
>> that the nil approach won't change, since it's pretty much good enough.
>>
>> On Thursday, August 15, 2013 10:44:48 PM UTC-4, Mikera wrote:
>>>
>>> Hi all,
>>>
>>> I'm experimenting with core.async. Most of it is exceptionally good, but
>>> bit I'm finding it *very* inconvenient that nil can't be sent over
>>> channels. In particular, you can't pipe arbitrary Clojure sequences through
>>> channels (since sequences can contain nils).
>>>
>>> I see this as a pretty big design flaw given the ubiquity of sequences
>>> in Clojure code - it appears to imply that you can't easily compose
>>> channels with generic sequence-handling code without some pretty ugly
>>> special-case handling.
>>>
>>> Am I missing something? Is this a real problem for others too?
>>>
>>> If it is a design flaw, can it be fixed before the API gets locked down?
>>>
>>  --
> --
> 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/pF9FEP7b77U/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/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: core.async - handling nils

2013-08-17 Thread Ben Wolfson
A sentinel value also prevents channels from being able to send/receive 
arbitrary values, without further wrapping.

Sent from my iPhone

On Aug 17, 2013, at 5:48 PM, Mikera  wrote:

> My overall sense is that the convenience of using if-let directly in a few 
> use cases doesn't justify making channels fall short of being able to send 
> arbitrary values (nil specifically, and clearly boolean false can cause some 
> problems too). 
> 
> I think it would be a much better design to have a sentinel value and a 
> couple of specialised functions or macros that can detect  / interact with it 
> appropriately. With a sentinel value the key part of your if-recv code could 
> just be something like:
> 
> `(let [~name (   (if (end-of-stream? ~name)
> ~else
> ~then
> 
> I can see that wrappers for nil values could also work, but that seems to be 
> a more complex solution (and also potentially with more overhead) than a 
> sentinel value
> 
> 
> On Saturday, 17 August 2013 07:50:06 UTC+8, Brandon Bloom wrote:
>> I ran into the other half of this problem: If you expect nils to signify 
>> closed channels, then you can't leverage the logically false nature of nil 
>> without excluding explicit boolean false values. Given the pleasant syntax 
>> of if-let / > is defined as follows:
>> 
>> (defmacro if-recv
>>   "Reads from port, binding to name. Evaluates the then block if the
>>   read was successful. Evaluates the else block if the port was closed."
>>   ([[name port :as binding] then]
>>`(if-recv ~binding ~then nil))
>>   ([[name port] then else]
>>`(let [~name (>   (if (nil? ~name)
>> ~else
>> ~then
>> 
>> I've considered some alternative core.async designs, such as an additional 
>> "done" sentinel value, or a pair of quote/unquote operators (see "reduced"), 
>> but nothing seems as simple as just avoiding booleans and nils, as annoying 
>> as that is. I'd be curious to here what Rich & team considered and how 
>> they're thinking about it. However, my expectation is that the nil approach 
>> won't change, since it's pretty much good enough.
>> 
>> On Thursday, August 15, 2013 10:44:48 PM UTC-4, Mikera wrote:
>>> 
>>> Hi all,
>>> 
>>> I'm experimenting with core.async. Most of it is exceptionally good, but 
>>> bit I'm finding it *very* inconvenient that nil can't be sent over 
>>> channels. In particular, you can't pipe arbitrary Clojure sequences through 
>>> channels (since sequences can contain nils). 
>>> 
>>> I see this as a pretty big design flaw given the ubiquity of sequences in 
>>> Clojure code - it appears to imply that you can't easily compose channels 
>>> with generic sequence-handling code without some pretty ugly special-case 
>>> handling.
>>> 
>>> Am I missing something? Is this a real problem for others too? 
>>> 
>>> If it is a design flaw, can it be fixed before the API gets locked down?
> 
> -- 
> -- 
> 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: Model validation - exceptions as side-effects?

2013-08-17 Thread Alexandr Kurilin
Leonardo, that's an interesting solution, thanks for writing it out and 
giving me some food for thought.

My thought process was that at this point I have a pure API that either 
gets the right inputs or it simply does nothing. As in, no helping messages 
about what went wrong, no attempt to do recovery. Some claim that for 
security purposes errors encountered by the API should be as opaque as 
possible to leak few internal details, so that's vaguely the direction I'm 
going in at this point, even though you lose on the development front.

I'd love to know your expert opinion on this, since you wrote Bouncer: say 
you're in the situation I listed above, where you don't care about nice 
error handling, you just want to give the caller a 400 if the input is 
incorrect. Would you still go the route where the validator function 
returns a list of errors? My concern is that now I have to have additional 
checks in place in my controller for whether the model save returned a list 
of errors, which will regardless ultimately result in a 400 status code.

Thanks!

(BTW, your blog is great, great content)

On Friday, August 16, 2013 7:28:51 PM UTC-7, Leonardo Borges wrote:
>
> I would prefer not throwing an exception in the case of a validation.
>
> Say your validation function returns a vector or the first argument 
> contains validation errors if any and the second contains the original map:
>
> (validate my-map) ;; returns [{:errors '("blah")} original-map]
>
>
> Then a neat way to write your function, taking advantage or core.match[1], 
> would be this:
>
> (defn my-fn [my-map]
>   (match (validate my-map)
>   [{:errors errors} original-map] (handle-errors)
>   [_ original-map] (save original-map)))
>
> This is my personal preference. It's concise, elegant and idiomatic in 
> languages that support pattern matching.
>
> If you'd rather not use core.match for whatever reason, I'd still opt out 
> of throwing an exception. The function would just need a little bit more 
> code to simulate the behaviour above.
>
> [1]: https://github.com/clojure/core.match
>
> Leonardo Borges
> www.leonardoborges.com
>
>
> On Sat, Aug 17, 2013 at 12:08 PM, Alexandr Kurilin 
> 
> > wrote:
>
>> Let's hypothetically say I have a Ring application and I'm performing 
>> some validation on the input map I receive as part of a POST request. The 
>> validate function throws an exception if anything's wrong with the input. 
>> The exception is caught in the middleware and turned into a 400 code 
>> response.
>>
>>  I could do either:
>>
>> (-> input
>>  validate
>>  save)
>>
>> or I could do:
>>
>> (do
>>   (validate input)
>>   (save input))
>>
>> The former doesn't really buy me anything, since a new version of input 
>> would never be returned by validate. It is however "side-effect free" in a 
>> way?
>> The latter is probably less idiomatic, but makes it obvious that input is 
>> not changing as part of the evaluation.
>>
>> What would be the more elegant way of handling this? Is the do block 
>> approach somehow inferior?
>>
>> Thanks!
>>
>> -- 
>> -- 
>> 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/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: Current state of the art in Web deployment?

2013-08-17 Thread Mark Mandel
On Sun, Aug 18, 2013 at 6:52 AM, John Jacobsen wrote:

> After some prototyping and development, we are now getting to the stage
> where "lein run" and a Jetty server running from -main aren't going to cut
> it.


At the risk of asking a dumb question, but being quite new to Clojure, I
don't mind - why do you say they won't cut it?

Mark


-- 
E: mark.man...@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast
http://www.2ddu.com/

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