Re: Some basic guidance to designing functional vs. state parts of app

2010-03-06 Thread Jeff Rose
  If you make a design decision to use an atom, you are effectively committing
  to never, ever being able to update that atom within a transaction.

  refs can do everything atoms can do and more.  They are slightly slower, 
  perhaps, but much safer.  So
  unless you have an explicit performance reason to use atoms and have 
  thought through the
  implications, the simplest design choice is to prefer refs.

I agree.  At first I was always mixing and matching atoms and refs,
but it seems like a case of premature optimization.  If I understand
correctly atoms don't give you any benefit over refs besides
performance.  As you grow a program it's virtually impossible to
predict which variables will end up needing coordinated updates, so
why not just use refs and count on the STM for everything by default?
Once you get to the performance optimization phase you can start
converting refs to atoms, add type hints where appropriate, and make
use of transients in your inner loops.

The ref-atom refactoring would be very cool, and if you start by
using refs for everything it would be easy as a first pass to turn any
ref that is always modified alone into an atom.

-Jeff

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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-05 Thread Stuart Halloway
Someone could (and hopefully will) write a multi-hundred-page book  
exclusively on Clojure's approach to state. I simply didn't have  
enough space while overviewing the whole language.


If you want an identity that is isolated from whatever else is (or  
might in the future) happen in your app, prefer atoms. However, if it  
does (or will) coordinate with other identities, use refs.


I guess switching between these should be a feature of the Clojure  
Refactoring IDE. :-)


Stu


For a single value
there seems to be little reason to adopt refs, though I've often
wondered why Stuart Halloway's book gives an example updating a  
single

ref of messages for a chat application.


I seem to recall atoms being the last reference type to be  
introduced. They might not have existed when Stuart was writing.


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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-05 Thread David Nolen
On Fri, Mar 5, 2010 at 4:08 PM, eyeris drewpvo...@gmail.com wrote:

 I don't follow your logic. Modifications of refs within a transaction
 retry too.


He's saying that atoms don't participate in the STM. If an atom depends on
the value of some refs, your program might be put into an inconsistent state
if the transaction is retried and you're changing the value of the atom in
the transaction.

In general using an atom means you're sure that you'll never want to perform
an atomic change of both it and some other mutable reference in your
program.

That's my understanding of it anyway.

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

Re: Some basic guidance to designing functional vs. state parts of app

2010-03-05 Thread Mark Engelberg
When you increment the contents of an atom, for example, it happens
immediately.  If it is inside a transaction, and the transaction retries,
the contents will be incremented multiple times.  Refs, on the other hand,
retry from the initial state at the beginning of the transaction, so as long
as there are no external side effects, you get the illusion that it only
happened once.  Essentially, changing an atom is like other side effects
(e.g., display or file output), and therefore cannot be safely used inside a
transaction.

On Fri, Mar 5, 2010 at 1:08 PM, eyeris drewpvo...@gmail.com wrote:

 I don't follow your logic. Modifications of refs within a transaction
 retry too.



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

Re: Some basic guidance to designing functional vs. state parts of app

2010-03-05 Thread Rick Moynihan
On 5 March 2010 17:56, Mark Engelberg mark.engelb...@gmail.com wrote:

 On Wed, Mar 3, 2010 at 5:20 PM, Rick Moynihan rick.moyni...@gmail.com
 wrote:

 If you have a single value representing the whole world, then it seems
 that protecting it with an atom would be the simplest and most
 idiomatic solution.

 For a single value there seems to be little reason to adopt refs, ...

 I disagree.  The problem with atoms is that updating an atom is a
 side-effect that cannot (typically) participate safely in a transaction.  It
 might be retried, so if for example, you want to increment the contents of
 an atom, it might get incremented multiple times which is generally not okay
 (if you're storing something in a cache, then a retry might be okay).

 If you make a design decision to use an atom, you are effectively committing
 to never, ever being able to update that atom within a transaction.

This is a good point, one that I hadn't considered and arguably also
non-obvious!  Though all is not necessarily lost when state you don't
control is held in an atom, as you can wrap it inside an agent which
will be co-ordinated with the STM, ensuring safe modification in the
event of retries.

 refs can do everything atoms can do and more.  They are slightly slower, 
 perhaps, but much safer.  So
 unless you have an explicit performance reason to use atoms and have thought 
 through the
 implications, the simplest design choice is to prefer refs.

My simple (uncontended) tests seem to indicate that atoms are about 4x
faster than refs (though I'd love to see a more comprehensive
benchmark).  Regardless I'll certainly be more cautious about using
atoms in the future, as refs are without doubt more composable.

R.

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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-04 Thread Sophie
Thank you all, the replies so far and the questions have already
deepened my understanding considerably!

Looking forward to more. I think a bit more discussion like this (not
necessarily my quite skimpy example) would be quite valuable to many
like me.

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


Some basic guidance to designing functional vs. state parts of app

2010-03-03 Thread Sophie
As a bit of a newbie to the functional + identity/state design space,
I'm struggling a bit with where to use identity constructs (refs) and
where to stay with pure functions, and could use some guidance. Pardon
me if some of my terms are a bit off. Here is a simple hypothetical
app for matching Applicants to Jobs.

I have several Applicants, each with some set of Skills. There are
several Jobs, each with some Requirements. There is some Match
relation between Skills and the Jobs they can match. The set of
Applicants, each of their skills, and the set of Jobs can change with
time. There is a set of Jobs that each Applicant can fill,
functionally computed from applicant skills  job requirements 
Match.

Ok, so jobs_that_an_applicant_can_fill is a pure function, I get
that.

Do I design a single World ref whose state changes with time to
different worlds, so adding a new Applicant or even adding a new Skill
to an existing Applicant results in a new World value? Or is it better
to have an Applicants ref and a Jobs ref that refer to different
sets of those er.. things?

Can each Applicant have a skills ref, whose state changes to
different sets of Skills? Should I design it this way?

How do I choose? What are the trade-offs?

Any and all guidance, insights, advice etc. welcome!

Thanks!

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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-03 Thread eyeris
One aspect of your question that makes it difficult to answer is that
you don't explain what the repercussions should be (in terms of
synchronization) when a new applicant or job enters the pool or a new
skill is attributed to an applicant. Should the job-applicant
matching function be restarted? Are you simply trying to isolate the
matching algorithm from updates to the data structures?



On Mar 2, 10:34 pm, Sophie itsme...@hotmail.com wrote:
 As a bit of a newbie to the functional + identity/state design space,
 I'm struggling a bit with where to use identity constructs (refs) and
 where to stay with pure functions, and could use some guidance. Pardon
 me if some of my terms are a bit off. Here is a simple hypothetical
 app for matching Applicants to Jobs.

 I have several Applicants, each with some set of Skills. There are
 several Jobs, each with some Requirements. There is some Match
 relation between Skills and the Jobs they can match. The set of
 Applicants, each of their skills, and the set of Jobs can change with
 time. There is a set of Jobs that each Applicant can fill,
 functionally computed from applicant skills  job requirements 
 Match.

 Ok, so jobs_that_an_applicant_can_fill is a pure function, I get
 that.

 Do I design a single World ref whose state changes with time to
 different worlds, so adding a new Applicant or even adding a new Skill
 to an existing Applicant results in a new World value? Or is it better
 to have an Applicants ref and a Jobs ref that refer to different
 sets of those er.. things?

 Can each Applicant have a skills ref, whose state changes to
 different sets of Skills? Should I design it this way?

 How do I choose? What are the trade-offs?

 Any and all guidance, insights, advice etc. welcome!

 Thanks!

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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-03 Thread Armando Blancas


On Mar 2, 8:34 pm, Sophie itsme...@hotmail.com wrote:
 Do I design a single World ref whose state changes with time to
 different worlds, so adding a new Applicant or even adding a new Skill
 to an existing Applicant results in a new World value? Or is it better
 to have an Applicants ref and a Jobs ref that refer to different
 sets of those er.. things?


It's simpler to use refs close to the object that will change; that
makes
the code to mutate the value simpler; if the world is the only mutable
object,
then the code to change something in there will increase with the
depth
of the mutation.

 Can each Applicant have a skills ref, whose state changes to
 different sets of Skills? Should I design it this way?

Yes; and if the kills set in independent of other state it may be an
atom and you
avoid a dosync if the program is single-threaded.

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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-03 Thread Mike Meyer
On Wed, 3 Mar 2010 14:20:56 -0800 (PST)
Armando Blancas armando_blan...@yahoo.com wrote:

 
 
 On Mar 2, 8:34 pm, Sophie itsme...@hotmail.com wrote:
  Do I design a single World ref whose state changes with time to
  different worlds, so adding a new Applicant or even adding a new Skill
  to an existing Applicant results in a new World value? Or is it better
  to have an Applicants ref and a Jobs ref that refer to different
  sets of those er.. things?
 
 
 It's simpler to use refs close to the object that will change; that
 makes
 the code to mutate the value simpler; if the world is the only mutable
 object,
 then the code to change something in there will increase with the
 depth
 of the mutation.

I'm not sure it's simpler: update-in makes reaching deep into a
structure to create a new structure with that one change in it easy,
and is probably more efficient than trying to do the same thing by
hand.

More importantly, if you break your refs up into smaller objects, you
should get better concurrency, as you can change two such refs in two
different threads without a problem. If you put the two in a structure
in the same ref, then you can't update one while the other is being
worked on.

mike
-- 
Mike Meyer m...@mired.org http://www.mired.org/consulting.html
Independent Network/Unix/Perforce consultant, email for more information.

O ascii ribbon campaign - stop html mail - www.asciiribbon.org

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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-03 Thread Rick Moynihan
On 3 March 2010 04:34, Sophie itsme...@hotmail.com wrote:
 As a bit of a newbie to the functional + identity/state design space,
 I'm struggling a bit with where to use identity constructs (refs) and
 where to stay with pure functions, and could use some guidance. Pardon
 me if some of my terms are a bit off. Here is a simple hypothetical
 app for matching Applicants to Jobs.

 I have several Applicants, each with some set of Skills. There are
 several Jobs, each with some Requirements. There is some Match
 relation between Skills and the Jobs they can match. The set of
 Applicants, each of their skills, and the set of Jobs can change with
 time. There is a set of Jobs that each Applicant can fill,
 functionally computed from applicant skills  job requirements 
 Match.

 Ok, so jobs_that_an_applicant_can_fill is a pure function, I get
 that.

 Do I design a single World ref whose state changes with time to
 different worlds, so adding a new Applicant or even adding a new Skill
 to an existing Applicant results in a new World value? Or is it better
 to have an Applicants ref and a Jobs ref that refer to different
 sets of those er.. things?

 Can each Applicant have a skills ref, whose state changes to
 different sets of Skills? Should I design it this way?

 How do I choose? What are the trade-offs?

If you have a single value representing the whole world, then it seems
that protecting it with an atom would be the simplest and most
idiomatic solution.  Refs are for co-ordinated change, i.e. where you
want to update multiple values at the same time.  For a single value
there seems to be little reason to adopt refs, though I've often
wondered why Stuart Halloway's book gives an example updating a single
ref of messages for a chat application.

If you partition your data more, into several values, then you should
use refs to co-ordinate the change.  The more granular you make the
refs, the more you trade complexity of design for potential throughput
under concurrent load, as finer grained refs are likely to mean less
collisions during transactions (unless of course you update every ref
in every transaction - which sounds like it'd be the worst case
scenario).

R.

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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-03 Thread Richard Newman

For a single value
there seems to be little reason to adopt refs, though I've often
wondered why Stuart Halloway's book gives an example updating a single
ref of messages for a chat application.


I seem to recall atoms being the last reference type to be introduced.  
They might not have existed when Stuart was writing.


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


Re: Some basic guidance to designing functional vs. state parts of app

2010-03-03 Thread rzeze...@gmail.com


On Mar 2, 11:34 pm, Sophie itsme...@hotmail.com wrote:

 How do I choose? What are the trade-offs?

 Any and all guidance, insights, advice etc. welcome!

 Thanks!

To me, it seems like you have two orthogonal pieces of data, and a
function that builds a report from that data.  You have a set of job
listings, and a set of applicants.  I see no reason why these need to
be coordinated (ref).  The addition of a job listing is totally
independent of an applicant updating her resume.  So it's
uncoordinated (atom).  That is, the job listings are always in a
consistent state no matter what I do to the applicant data.  Said
another way, there's nothing I can do to the applicant data that can
put the job listings in an inconsistent state.

As for the match function.  Well it needs to get a snapshot of both
pieces of data, and then determine what applicants match up with each
job listing.  While this function is running a job could be added, an
applicant could update her resume, or maybe an applicant will remove
her resume but your function won't see any of that, but who cares?  It
will see a consistent snapshot of both pieces of data, and from those
it will build the result.  As of time T1, here is your latest and
greatest match report.

Now, say you want the match report built every time a job listing or
applicant data is changed.  This way the 'latest' report is always in
memory and ready to go.  Well, in this case, you now need to
coordinate the update of job listings or applicant data with the
generation of the report.  You never want your program to enter a
state where the job listings are in state L101 and applicants are in
state A54 and your report is based on the combination of (L101, A53).
That's an inconsistent state because your report is not based on the
latest data.  In this case, you'd probably want to use refs to make
sure the your job/applicant data is coordinated with your report
data.  However, if your data is constantly changing, and the match
function takes a while to run then this may be very slow.

Take what I say with a grain of salt as I'm also fairly new to this
stuff.  At the end of the day, experience is probably the best
teacher.

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