at:tutorial:actors
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
at:tutorial:actors [2008/08/01 14:43] – * tvcutsem | at:tutorial:actors [2008/11/03 10:08] – * tvcutsem | ||
---|---|---|---|
Line 26: | Line 26: | ||
}; | }; | ||
}; | }; | ||
- | >>< | + | >>< |
</ | </ | ||
Line 70: | Line 70: | ||
}; | }; | ||
}; | }; | ||
- | >>< | + | >>< |
</ | </ | ||
Line 319: | Line 319: | ||
< | < | ||
+ | // to create an explicit future: | ||
def [future, resolver] := makeFuture(); | def [future, resolver] := makeFuture(); | ||
- | consumer< | + | |
- | def val := /* calculate useful value */ | + | // to explicitly resolve a future |
resolver.resolve(val); | resolver.resolve(val); | ||
</ | </ | ||
Line 328: | Line 329: | ||
The resolver also defines a '' | The resolver also defines a '' | ||
+ | |||
+ | As an example of such conditional synchronization, | ||
+ | |||
+ | < | ||
+ | def makeDatingService() { | ||
+ | def people := []; // a list of Questionnaire objects | ||
+ | object: { | ||
+ | def match(lonelyHeart) { | ||
+ | // if an ideal mate is found in the list, | ||
+ | // | ||
+ | // otherwise | ||
+ | // | ||
+ | // the lonelyHeart later, when an ideal made | ||
+ | // has registered with the dating service | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Let us assume that a person is simply identified by a name and its sex: | ||
+ | < | ||
+ | def makePerson(nam, | ||
+ | object: { | ||
+ | def name := nam; | ||
+ | def sex := sx; | ||
+ | } | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | The dating service has a little database stored as a simple list. This list does not contain person objects but rather Questionnaire objects. The questionnaire contains the logic necessary to match people. We will assume for the sake of the example that 2 people match if they are of the opposite sex. In addition, a questionnaire object can keep track of an " | ||
+ | |||
+ | < | ||
+ | def makeQuestionnaire(p) { | ||
+ | def idealPersonResolver; | ||
+ | object: { | ||
+ | def person := p; | ||
+ | def matches(otherQ) { otherQ.person.sex != p.sex }; | ||
+ | def wait() { | ||
+ | def [future, resolver] := makeFuture(); | ||
+ | idealPersonResolver := resolver; | ||
+ | future | ||
+ | }; | ||
+ | def notify(name) { idealPersonResolver.resolve(name) }; | ||
+ | }; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | When a questionnaire is asked to '' | ||
+ | |||
+ | Armed with these abstractions, | ||
+ | |||
+ | < | ||
+ | def makeDatingService() { | ||
+ | def people := []; // a list of Questionnaire objects | ||
+ | object: { | ||
+ | def match(lonelyHeart) { | ||
+ | def lonelyHeartQ := makeQuestionnaire(lonelyHeart); | ||
+ | { |return| | ||
+ | people.each: | ||
+ | // an ideal mate was found | ||
+ | if: (idealMateQ.matches(lonelyHeartQ).and: | ||
+ | idealMateQ.notify(lonelyHeart.name); | ||
+ | // remove the person from the database | ||
+ | people := people.filter: | ||
+ | return(idealMateQ.person.name) // notify lonelyHeart | ||
+ | } | ||
+ | }; | ||
+ | // no ideal mate was found, store its questionnaire in the database | ||
+ | people := people + [lonelyHeartQ]; | ||
+ | lonelyHeartQ.wait(); | ||
+ | }.escape(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Below, we define an auxiliary method that illustrates how a lonely heart has to interact with the dating service. | ||
+ | |||
+ | < | ||
+ | def d := makeDatingService(); | ||
+ | def register(p) { | ||
+ | when: d< | ||
+ | system.println(p.name + " matched with " + name); | ||
+ | }; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | The key to our conditional synchronization is that the '' | ||
+ | |||
+ | The complete source code of the above example can be found in the file '' | ||
===== Actor Mirrors ===== | ===== Actor Mirrors ===== |
at/tutorial/actors.txt · Last modified: 2020/02/05 21:26 by elisag