I started to write an essay, aimed at those programmers who are experienced
with highly mutable languages such as Javascript, Ruby, PHP, etc, to
demonstrate how one's code style changes when one switches to a mostly
immutable language such as Clojure. However, my Clojure code is not nearly
as terse as I wanted. In particular, I have this nil check:
(if (nil? ((:winner c) nu))
(assoc nu (:winner c) {:history [{}]})
nu)
which I assume I am writing because I am ignorant. I'm guessing there might
be something clever I can do to avoid this?
For my code examples, I'm working with these 2 data structures:
(def users {
:henry {
:history
[
{:housing 25, :restaurants 40, :theater 930},
{:restaurants 30, :crisis 220}
]
},
:lisa {
:history
[
{:theater 80},
{:housing 445, :restaurants 15, :theater 35}
]
},
:pasha {
:history
[
{:restaurants 5},
{:restaurants 40, :theater 60}
]
},
:eli {
:history
[
{:crisis 135, :restaurants 440, :theater 65},
{:theater 95}
]
}
})
(def contests [{:category :housing, :prize-money 100, :winner :eli},
{:category :housing, :prize-money 30, :winner :henry},
{:category :housing, :prize-money 340, :winner :henry},
{:category :housing, :prize-money 45, :winner :susan},
{:category :housing, :prize-money 15, :winner :henry},
{:category :housing, :prize-money 10, :winner :pasha},
{:category :housing, :prize-money 25, :winner :pasha},
{:category :crisis, :prize-money 100, :winner :eli},
{:category :crisis, :prize-money 2330, :winner :henry},
{:category :crisis, :prize-money 90, :winner :henry},
{:category :restaurants, :prize-money 1130, :winner :eli},
{:category :restaurants, :prize-money 130, :winner :pasha},
{:category :theater, :prize-money 60, :winner :eli},
{:category :theater, :prize-money 90, :winner :pasha},
{:category :theater, :prize-money 130, :winner :pasha},
{:category :theater, :prize-money 830, :winner :susan},
{:category :theater, :prize-money 90, :winner :susan},
{:category :theater, :prize-money 270, :winner :eli}])
Presumably "users" shows past winnings from 2 rounds of some contest,
whereas "contests" shows the winnings from the 3rd round, which need to be
added to "users". So I wrote:
(defn add-placeholder-to-history [us]
(loop [u us nu {}]
(if (first u)
(recur
(rest u)
(assoc nu (get (first u) 0) {:history (into [] (cons {}
(:history (get (first u) 1))))}))
nu)))
(defn update-history [nu c]
(update-in
(if (nil? ((:winner c) nu))
(assoc nu (:winner c) {:history [{}]})
nu)
[(:winner c) :history 0 (:category c)] (fnil #(+ %1 (:prize-money c))
0)))
And so in the end we would simply call:
(reduce
update-history
(add-placeholder-to-history users)
contests)
Which correctly gives me:
{
:susan {
:history [{:theater 920, :housing 45}]
}
:lisa {
:history [{}
{:theater 80}
{:housing 445, :restaurants 15, :theater 35}]
}
:henry {
:history [{:crisis 2420, :housing 385}
{:housing 25, :restaurants 40, :theater 930}
{:crisis 220, :restaurants 30}]
}
:eli {
:history [{:theater 330, :restaurants 1130, :crisis 100, :housing 100}
{:crisis 135, :restaurants 440, :theater 65}
{:theater 95}]
}
:pasha {
:history [{:theater 220, :restaurants 130, :housing 35}
{:restaurants 5}
{:restaurants 40, :theater 60}]
}
}
And then I wrote:
-----------------------------------
By the way, you might be wondering what this is for:
(if (nil? ((:winner c) nu))
(assoc nu (:winner c) {:history [{}]})
nu)
We do this for Susan. She is a new contestant who won some money in the
newest round of contests, however, she does not yet exist in "users", so we
need to create a space for her. Without these 3 lines of code, we get this
for her:
{:susan {:history {0 {:theater 920, :housing 45}}},
But with these 3 lines of code, we get the correct results for her, and for
everyone else.
-----------------------------------
I am wondering if I can avoid those 3 lines of code?
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.