Ok so there are two use cases:
1) testing constraint
2) referencing a snapshot

And two operations
A) @
B) ensure

1A is incorrect
1B is correct
2A is correct and concurrent
2B is correct but not concurrent

"More concurrency" is the default. This increases the chance of
incorrectness due to programmer error, as the tradeoff for lack of
concurrency due to programmer error. Can that be changed? If there
were no default the programmer would explicitly make a choice, so how
could we achieve that:

(let [s @sales]
  (dosync (ref-set bonus (/ (year-to-date s) 10))))
; overly tedious syntax, not really an option for more complex cases

; snap or ensure, deref not allowed
(dosync (ref-set bonus (/ (year-to-date (snap sales)))))
; breaks for functions (foo) returns @sales, should not care if in a
transaction or not.
; its up to the transaction level to decide (oh no this bodes poorly
for my quest)

; compiler checks for deref tests
LEGAL: (dosync (ref-set bonus (/ (year-to-date @sales))))
ILLEGAL: (dosync (ref-set bonus (if @constraint x y)))
; still breaks for function calls (if (foo) x y)  where foo returns
@constraint

; What if we made @ mean ensure and used snap instead of @?
; Same issues - doesn't work for function calls

So I can't see there being a more explicit way to choose between (1)
and (2) than what already exists [relying on the programmer to realise
when ensure is required]. I only just found out about write skew and
it worried me that I could be so wrong with my assumptions of what a
transaction means. That was a gap in understanding on my part. I do
think its an easy trap to fall into - but I can't see any way to
signpost it better.





On Sep 24, 1:45 am, Rich Hickey <richhic...@gmail.com> wrote:
> On Wed, Sep 23, 2009 at 10:17 AM, Christophe Grand
>
>
>
> <christo...@cgrand.net> wrote:
>
> > On Wed, Sep 23, 2009 at 7:14 AM, Timothy Pratley <timothyprat...@gmail.com>
> > wrote:
>
> >> When it useful to be able to deref inside a dosync without ensuring?
>
> > In a read-only transaction.
>
> >> Ensure seems like a more safe default of what I'd expect from a
> >> transaction. So why not make deref automatically ensure within a
> >> dosync? It takes a bit of care to remember to use ensure instead of
> >> deref in a dosync.
>
> > You only need to ensure if you don't use alter or ref-set later.
>
> > The typical use case for ensure is:
> > (when (a-predicate? (ensure foo)) (alter bar f arg1 arg2))
>
> And even then, ensure is often not needed and overkill. Make sure you
> have a real business requirement that the predicate remain true (or
> value fixed) on transaction completion. We need to move to a world in
> which we accept fewer guarantees of lockdown rather than more if we
> want to get more concurrency. ensure pulls things into your
> transaction footprint that plain reads would not. For instance, giving
> a salesperson a bonus equal to 10% of their year-to-date sales need
> not lock down their sales - it's merely a calculation done at a point
> in time, while allowing sales to proceed.
>
> Rich
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to