right the docs say:

Within a transaction,
returns the in-transaction-value of ref, else returns the
most-recently-committed value of ref.

so outside the transaction is probably what I want...

Jim


On 20/11/13 14:11, Jim - FooBar(); wrote:
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.

Reply via email to