Hi all,
I've been wondering about this lately and I'm not sure which approach to
pick as both give the correct results (in my rudimentary tress-test).
So as I understand it is generally suggested to have pure, testable
functions that oter side-effecting functions rely on. like so for example:
(defn credit "A low-level crediting function. Nothing to do with refs."
[bank acc-id amount]
(update-in bank [acc-id :curr-balance] +' amount)) ;;safe math at the
lowest level
(defn debit "A low-level debiting function. Nothing to do with refs."
[bank acc-id amount]
(update-in bank [acc-id :curr-balance] -' amount)) ;;safe math at the
lowest level
(defn deposit!
"Modifies the bank such that an amount is credited to this account-id.
Returns the modified bank."
[bank acc-id amount]
(dosync
(alter bank credit acc-id amount)))
(defn withdraw!
"Modifies the bank such that an amount is debited from this account-id.
Returns the modified bank."
[bank acc-id amount]
(dosync
(alter bank debit acc-id amount)))
Ok everything is fine so far. Even our side-effecting fns return
something (per alter) which is good. Later on however one might want to
add another layer. for example this:
(defn- transfer1
"Modifies bank such that an amount is safely tranfered from an
account-id 'from' to an account-id 'to'.
Returns the modified bank."
[bank amount from to]
(dosync
(alter bank
(fn [b]
(-> b
(credit to amount)
(debit from amount))))))
(defn transfer!
"Entry point for transactions. Accepts a bank to transact on and an
arbitrary number of [amount from to] triplets.
Uses 'transfer1' per each triplet. Returns the modified bank."
[bank & amount-from-to]
(assert (zero? (rem (count amount-from-to) 3)) "Need mulitples of 3
[amount from to]")
(dosync
(doseq [[amount from to] (partition 3 amount-from-to)]
(transfer1 bank amount from to))
*@bank *))
In this last case 'doseq' would return nil from the transaction. My
question is this: Is what I'm doing (deref from within the transaction)
the right way or perhaps deref after the transaction has commited and
exited (outside the 'dosync')? Is there actually a difference?
This code is educational and I'd like it to be clean and that I've
covered all my basis for potential questions. If anyone can comment that
would be great...:)
Jim
--
--
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.