There's been a lot of discussion here of transactions. I agree that programming transactions using locks is just "too Martian". [Maybe that's why the ToonTalk help character is Marty the Martian ;-)] Here's how I would program them in ToonTalk. I'd program a bank account robot to respond to a message to give exclusive attention. The message contains a nest where subsequent messages will arrive. (And probably a bird that is given an acknowledgement that the message was processed.) The robot takes the nest where messages normally arrive and stores it somewhere in its box and puts the incoming nest where that nest was. In case you want to back out of an aborted transaction the robot should have copied its box and stored it as well. Now when the sender of the message has exclusive control over this bank account. All of its messages go to the nest it sent and messages from anyone else go to the stored nest. To end exclusive control a message is sent releasing it and a robot handles it by throwing away the copy of the old state and the nest and puts the original nest back where it was. (And any messages that were sent in the meanwhile are still on top and are now processed). This isn't very complicated - I bet a typical 10-year old familar with ToonTalk can master this. As with any code, bugs are possible. The most serious one being to forget to end exclusive control when you are done.
Nice example! This is exactly how Kats works. Each object maintains separate state for each transaction in which it is involved. When the transaction is complete, all objects involved in the transaction are told to commit their new state. This is useful in concurrent processing because different processes can work simultaneously, but in different transactions and not step on each other (note: multiple processes can also work in the same transaction concurrently). However, transactions is just one way of dealing with concurrent processing.
Transactions are all about being able to move a system from one state to another, while being able to easily get out of a bad situation that could leave the system in an inconsistent state. Concurrency is handled by creating a sort of "parallel universe" where work can be discarded if it goes bad, or if it conflicts with something that was done in another universe.
But, this is not appropriate for all situations. For example, you could use transactions to allow concurrent processes to maniupulate the positions of a couple of morphs on screen. A conflict would be defined as the two morphs occupying the same position on screen. Both processes do their work, commit their changes, then the screen gets updated. If ever the two morphs move into the same space, one of the transactions would fail to commit. However, another solution is to simply check the space in which the morph is about to move for the presence of another morph and avoid the conflict. The complexity cannot be eliminated, it can only be shifted from one place to another.
If we had infinite computing power, we wouldn't need either solution...we could just establish the constraints and have them enforced at all times. It would be physically impossible for the two morphs to occupy the same space at the same time, just as it is physically impossible for two people to occupy the same space at the same time.
- Stephen