- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
An altogether different actor model
Sat, 2009-08-08, 05:00
Dear Scala Enthusiasts,
i finally got hold of a copy of an open source-able version of the system Christine Tomlinson, Greg Lavender, Mark Scheevel, ..., and i built. It's an actor-based language, called Rosette, together with a VM and compiler. i mention this to you guys because it's really an actor system with appropriate execution semantics guarantees that make it an implementation of the actor model put forward by Carl Hewitt and Gul Agha. It differs in this way from the Scala "actor" system which does not formally declare what sort of fairness constraints it imposes on message delivery -- which is tantamount to constraints on scheduling.
Of the many things that make this model of note is the commitment to reflection. The model is structurally, procedurally and even lexically reflective. What do i mean by that?
i hope to be able with this to begin to influence the Scala team concurrency abstraction offerings. After working for over 20 years on systems at the boundary between research and industry, i have become convinced that there isn't a one-size-fits-all concurrency abstraction. However, there are some that get better mileage than others, under certain driving conditions. Actors represent an interesting sweet spot because they
We always wanted this sort of machinery because good tool support is really really necessary when venturing into the perilous land of parallel and concurrent programming, and static analysis is some of the best kind of tool support one can hope for in this context. The work Christine and Mark did on Enabled-Sets (essentially filters on the actor's mailbox) was a step in this direction. Likewise, the work Christine and i did on the multimethod support and it's attendent Regular Expression Types (developed and deployed on industrial applications almost a decade before Ben Peirce's work on these in the context of XDuce) was a preparation for another assault on this (a naive intuition of state machines governing the enabled-sets machinery was guiding us).
Since Rosette was designed many people have put a lot of excellent work into types for concurrency and one family of proposals has emerged as the most pragmatic, namely Caires' spatial-behavioral types. Actors -- with their principal-port abstraction -- line up very well with Caires original term language in the first paper on spatial-behavioral types.
If the Scala team can make some guarantees about the actor scheduler semantics -- for any scheduler that can be plugged in -- then we can build a behavioral type system for Scala actors. Then Scala can have all the goodness mentioned in the bullet points above. If not, well, there's always Rosette, i guess.
So, if you would like to be able to see the repo, drop me a line and i'll add you as a committer.
Best wishes,
--greg
Rosette System, Version 3.0 (Jan 20, 1993 02:00:32 PM) - Copyright 1989, 1990, 1991, 1992 MCC
loading: ./configuration.rbl silent
loading: ./sbo-init.rbl silent
loading: ./system.rbl silent
loading: ./expander.rbl silent
loading: ./multimethod.rbl silent
loading: ./document.rbl silent
loading: ./config.rbl silent
loading: ./meth-proc-oprns.rbl silent
loading: ./que-stk-oprns.rbl silent
loading: ./string-oprns.rbl silent
loading: ./tuple-oprns.rbl silent
loading: ./table-oprns.rbl silent
loading: ./io-system.rbl silent
loading: ./exceptions.rbl silent
loading: ./time.rbl silent
loading: ./trace.rbl silent
loading: ./classes-types.rbl silent
loading: ./c-structures.rbl silent
loading: ./foreign-funs.rbl silent
loading: ./async-repl.rbl silent
loading: ./dyn-load.rbl silent
loading: ./apropos.rbl silent
rosette>
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
i finally got hold of a copy of an open source-able version of the system Christine Tomlinson, Greg Lavender, Mark Scheevel, ..., and i built. It's an actor-based language, called Rosette, together with a VM and compiler. i mention this to you guys because it's really an actor system with appropriate execution semantics guarantees that make it an implementation of the actor model put forward by Carl Hewitt and Gul Agha. It differs in this way from the Scala "actor" system which does not formally declare what sort of fairness constraints it imposes on message delivery -- which is tantamount to constraints on scheduling.
Of the many things that make this model of note is the commitment to reflection. The model is structurally, procedurally and even lexically reflective. What do i mean by that?
- Structural reflection means that actors are made out of actors. Specifically, every actor is made up of four actors:
- mailbox -- where messages are collected for processing
- shared behavior object -- think of this as a kind of vtable
- meta -- the map from symbols to locations in the ...
- extension -- where the actor's state is held
- Procedural reflection means that execution has an actor representation. Rosette has 1-shot continuations (very closely related to the delimited continuations coming in Scala 2.8). These are made accessible in reflective methods. A reflective method is analogous to a shift point in the delimited continuations model. Yanking on the actor that represents that continuation is like calling reset.
- Lexical reflection -- even the abstract syntax of the language has actors to represent it. This gives all kinds of good properties to meta-level computation.
i hope to be able with this to begin to influence the Scala team concurrency abstraction offerings. After working for over 20 years on systems at the boundary between research and industry, i have become convinced that there isn't a one-size-fits-all concurrency abstraction. However, there are some that get better mileage than others, under certain driving conditions. Actors represent an interesting sweet spot because they
- are pretty easy to grasp
- have a semantics that fits well with well understood ideas about transactions
- have a semantics that fits well with distribution
- and turn out to fit into a static typing discipline
- Port implementation to JVM
- compile the Rosette VM byte code to JVM byte code
- port the parser to JVM (this ties in with project stockholm work)
- port the built in data structures and the libs to JVM
- Extend the language with a behavioral type system
- Use Rosette expressions as the term language for Caires' spatial-behavioral types
- Compiler support for code refactoring that preserves concurrency properties -- that way if you know your code was deadlock-free and then you refactor you can be guaranteed it's still deadlock-free.
- Code navigation. You can use behavioral types to navigate code just like you use ordinary functional types right now.
- Service discovery. Behavioral types make really excellent descriptions of services. Even better, then you can check if a given component type checks against your service description -- making it a candidate provider for the service you seek.
- BTW, this also fits in with the project stockholm work because this is part of the semantic search machinery.
We always wanted this sort of machinery because good tool support is really really necessary when venturing into the perilous land of parallel and concurrent programming, and static analysis is some of the best kind of tool support one can hope for in this context. The work Christine and Mark did on Enabled-Sets (essentially filters on the actor's mailbox) was a step in this direction. Likewise, the work Christine and i did on the multimethod support and it's attendent Regular Expression Types (developed and deployed on industrial applications almost a decade before Ben Peirce's work on these in the context of XDuce) was a preparation for another assault on this (a naive intuition of state machines governing the enabled-sets machinery was guiding us).
Since Rosette was designed many people have put a lot of excellent work into types for concurrency and one family of proposals has emerged as the most pragmatic, namely Caires' spatial-behavioral types. Actors -- with their principal-port abstraction -- line up very well with Caires original term language in the first paper on spatial-behavioral types.
If the Scala team can make some guarantees about the actor scheduler semantics -- for any scheduler that can be plugged in -- then we can build a behavioral type system for Scala actors. Then Scala can have all the goodness mentioned in the bullet points above. If not, well, there's always Rosette, i guess.
So, if you would like to be able to see the repo, drop me a line and i'll add you as a committer.
Best wishes,
--greg
Rosette System, Version 3.0 (Jan 20, 1993 02:00:32 PM) - Copyright 1989, 1990, 1991, 1992 MCC
loading: ./configuration.rbl silent
loading: ./sbo-init.rbl silent
loading: ./system.rbl silent
loading: ./expander.rbl silent
loading: ./multimethod.rbl silent
loading: ./document.rbl silent
loading: ./config.rbl silent
loading: ./meth-proc-oprns.rbl silent
loading: ./que-stk-oprns.rbl silent
loading: ./string-oprns.rbl silent
loading: ./tuple-oprns.rbl silent
loading: ./table-oprns.rbl silent
loading: ./io-system.rbl silent
loading: ./exceptions.rbl silent
loading: ./time.rbl silent
loading: ./trace.rbl silent
loading: ./classes-types.rbl silent
loading: ./c-structures.rbl silent
loading: ./foreign-funs.rbl silent
loading: ./async-repl.rbl silent
loading: ./dyn-load.rbl silent
loading: ./apropos.rbl silent
rosette>
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Tue, 2009-08-18, 02:57
#2
RE: An altogether different actor model
Hi,
Since you mentioned a 'classic' API for Scala actors, I thought I'd mention that I also did a bit of work about two and a half years ago on making actors more object oriented and typed. I tried to keep the same facilities as actors had with in Scala at that time, but from glancing at the link you posted it seems my work isn't as complete as the work by Jonas Boner, and I only ended up using it in a simple context. Anyway, in case people are interested:
http://www.ne-fat-s.org/objactor/index.html
Stefan
----------------------------------------
> Date: Tue, 18 Aug 2009 11:32:06 +1000
> From: benh [at] ibsglobalweb [dot] com
> To: lgreg [dot] meredith [at] gmail [dot] com
> CC: scala [at] listes [dot] epfl [dot] ch
> Subject: Re: [scala] An altogether different actor model
>
> Hi Greg,
>
> I'm intrigued by the contrast between your two statements about Actors
> and Static Typing copied below. The second one reflects my evaluation of
> Scala actors, so Im quite interested to see how you might better fit
> them into static typing - that's surely in the future of Actors.
>
> I suspect you might have tried to explain that in the latter part of
> your letter, but I didn't understand it sufficiently. If you could give
> a more concrete example in Scala-like syntax, that would be interesting.
>
> My present feeling is that Scala actors would best evolve towards a
> classic API, ie a set of named functions with typed parameters and
> return values. Invoking on an Actor shouldn't look so different from
> invoking on an Object, IMO. Jonas Boner blogged about some work in this
> area in Scala OTP
> [http://jonasboner.com/2008/12/11/real-world-scala-fault-tolerant-concurrent-asynchronous-components.html].
> One difficulty is the way the a/synchronous divide gets papered over,
> but I'm not convinced that's unsurmountable.What's your opinion on this
> type of approach?
>
> -Ben
>
> Meredith Gregory wrote:
>> Actors represent an interesting sweet spot because they
>>
>> ... - and turn out to fit into a static typing discipline
>>
> Meredith Gregory also wrote:
>> Those familiar with Scala's
>> "actors" have certainly experienced a similar step over the edge, in the
>> sense that programming with Scala "actors" is not genuinely integrated with
>> or supported by all the very sophisticated typing machinery of the
>> functional kernel of the language
>
>
> --
>
>
>
> *Ben Hutchison
> Senior Developer
> * Level 2 476 St Kilda Road Melbourne VIC 3004
> T 613 8807 5252 | F 613 8807 5203 | M 0423 879 534 |
> www.ibsglobalweb.com
>
>
Tue, 2009-08-18, 03:07
#3
Re: An altogether different actor model
Ben,
Thanks for your query. To clarify the relationship between the two statements
Recently, i've been looking into Julia Lawall's Bossa as a possible mechanism for specifying a scheduling policy. One approach for a types-for-concurrency based approach to providing static checking for actors would be to state the guarantees up to a scheduling policy in Bossa. Then the type-checker would be off the hook if the code was deployed into a scheduler that violated the policy.
Best wishes,
--greg
On Mon, Aug 17, 2009 at 6:32 PM, Ben Hutchison <benh [at] ibsglobalweb [dot] com> wrote:
Thanks for your query. To clarify the relationship between the two statements
- Actors may, in principle, enjoy a static typing discipline that derives from a types-for-concurrency approach.
- Scala "actors" do not, in practice, enjoy such a discipline. Scala "actors" do not really enjoy much connection with Hewitt-Agha style actors because of a lack of fair message delivery scheduling -- or even a statement of any discipline on the message delivery scheduling.
Recently, i've been looking into Julia Lawall's Bossa as a possible mechanism for specifying a scheduling policy. One approach for a types-for-concurrency based approach to providing static checking for actors would be to state the guarantees up to a scheduling policy in Bossa. Then the type-checker would be off the hook if the code was deployed into a scheduler that violated the policy.
Best wishes,
--greg
On Mon, Aug 17, 2009 at 6:32 PM, Ben Hutchison <benh [at] ibsglobalweb [dot] com> wrote:
Hi Greg,
I'm intrigued by the contrast between your two statements about Actors and Static Typing copied below. The second one reflects my evaluation of Scala actors, so Im quite interested to see how you might better fit them into static typing - that's surely in the future of Actors.
I suspect you might have tried to explain that in the latter part of your letter, but I didn't understand it sufficiently. If you could give a more concrete example in Scala-like syntax, that would be interesting.
My present feeling is that Scala actors would best evolve towards a classic API, ie a set of named functions with typed parameters and return values. Invoking on an Actor shouldn't look so different from invoking on an Object, IMO. Jonas Boner blogged about some work in this area in Scala OTP [http://jonasboner.com/2008/12/11/real-world-scala-fault-tolerant-concurrent-asynchronous-components.html]. One difficulty is the way the a/synchronous divide gets papered over, but I'm not convinced that's unsurmountable.What's your opinion on this type of approach?
-Ben
Meredith Gregory wrote:
Actors represent an interesting sweet spot because theyMeredith Gregory also wrote:
... - and turn out to fit into a static typing discipline
Those familiar with Scala's
"actors" have certainly experienced a similar step over the edge, in the
sense that programming with Scala "actors" is not genuinely integrated with
or supported by all the very sophisticated typing machinery of the
functional kernel of the language
Tue, 2009-08-18, 03:27
#4
Re: An altogether different actor model
Ben,
In response to your second question regarding sending a message to an actor and how that looks in comparison to invoking a method or function on an object, in Rosette we adopted the following:
James Iry pointed out to me that JVM thread semantics is a little on the light side, in terms of any guarantees. Thus, guarantees about message delivery scheduling can be correspondingly difficult to enforce. i wonder if this might be a place where Scala could be giving feedback to the JVM community. JRuby and the dynamic languages have certainly had their influence on the JVM development, recently. If there was a serious value-prop -- like all the things one could do with a types-for-concurrency framework -- that depended on semantic guarantees for JVM thread execution, we might see a corresponding response from the JVM development communities.
Best wishes,
--greg
On Mon, Aug 17, 2009 at 6:59 PM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
In response to your second question regarding sending a message to an actor and how that looks in comparison to invoking a method or function on an object, in Rosette we adopted the following:
- (m arg0 arg1 ... argN) was syntax that resulted in the following evaluation
- send the message (m arg1 ... argN) to actor arg0;
- wait for a result and let that be the value of the expression
- (send m arg0 arg1 ... argN) was syntax that resulted in
- send the message (m arg1 ... argN) to actor arg0, but do not wait for results
- let #niv be the value of the expression (#niv is the constant representing no intrinsic value; it's like an untyped version of None in an Option, or maybe it might best be said to correspond to None for Option[Object])
- arg0.m(arg1 ,..., argN)
- arg0 ! m(arg1, ..., argN)
James Iry pointed out to me that JVM thread semantics is a little on the light side, in terms of any guarantees. Thus, guarantees about message delivery scheduling can be correspondingly difficult to enforce. i wonder if this might be a place where Scala could be giving feedback to the JVM community. JRuby and the dynamic languages have certainly had their influence on the JVM development, recently. If there was a serious value-prop -- like all the things one could do with a types-for-concurrency framework -- that depended on semantic guarantees for JVM thread execution, we might see a corresponding response from the JVM development communities.
Best wishes,
--greg
On Mon, Aug 17, 2009 at 6:59 PM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
Ben,
Thanks for your query. To clarify the relationship between the two statements
Given the plugin in scheduler architecture, if one plugs in the null scheduler that drops all work on the floor, is that a reasonable message delivery schedule? How does one specify what is reasonable? Without at least some specification of what is reasonable, there can be no static guarantees of any type. You could deploy code an enhanced types-for-concurrency type-checker guaranteed into a situation in which the null scheduler got plugged in -- by virtue of satisfying a long chain of dependencies for a large build for a Scala-based system -- and all bets would be off regarding what the code did. Of course, the null scheduler is really an extreme representative of a much more subtle problem. Getting scheduling policies correct can be a very tricky business.
- Actors may, in principle, enjoy a static typing discipline that derives from a types-for-concurrency approach.
- Scala "actors" do not, in practice, enjoy such a discipline. Scala "actors" do not really enjoy much connection with Hewitt-Agha style actors because of a lack of fair message delivery scheduling -- or even a statement of any discipline on the message delivery scheduling.
Recently, i've been looking into Julia Lawall's Bossa as a possible mechanism for specifying a scheduling policy. One approach for a types-for-concurrency based approach to providing static checking for actors would be to state the guarantees up to a scheduling policy in Bossa. Then the type-checker would be off the hook if the code was deployed into a scheduler that violated the policy.
Best wishes,
--greg
On Mon, Aug 17, 2009 at 6:32 PM, Ben Hutchison <benh [at] ibsglobalweb [dot] com> wrote:
Hi Greg,
I'm intrigued by the contrast between your two statements about Actors and Static Typing copied below. The second one reflects my evaluation of Scala actors, so Im quite interested to see how you might better fit them into static typing - that's surely in the future of Actors.
I suspect you might have tried to explain that in the latter part of your letter, but I didn't understand it sufficiently. If you could give a more concrete example in Scala-like syntax, that would be interesting.
My present feeling is that Scala actors would best evolve towards a classic API, ie a set of named functions with typed parameters and return values. Invoking on an Actor shouldn't look so different from invoking on an Object, IMO. Jonas Boner blogged about some work in this area in Scala OTP [http://jonasboner.com/2008/12/11/real-world-scala-fault-tolerant-concurrent-asynchronous-components.html]. One difficulty is the way the a/synchronous divide gets papered over, but I'm not convinced that's unsurmountable.What's your opinion on this type of approach?
-Ben
Meredith Gregory wrote:
Actors represent an interesting sweet spot because theyMeredith Gregory also wrote:
... - and turn out to fit into a static typing discipline
Those familiar with Scala's
"actors" have certainly experienced a similar step over the edge, in the
sense that programming with Scala "actors" is not genuinely integrated with
or supported by all the very sophisticated typing machinery of the
functional kernel of the language
Tue, 2009-08-18, 15:37
#5
Re: An altogether different actor model
It's clear from the comments on scheduling that I'm out of my depth, here. But I only expect two simple things from "typed actors"
sealed abstract class FooMsg
...
class FooActor {
private val a = actor {
loop {
react {
case m: FooMsg => m match {
// exhausive match FooMsg (2)
case ...
}
case _ => throw new RuntimeException("Not a valid message")
}
}
}
// FooActors only take FooMsgs (1)
def ! (m: FooMsg) {a ! m}
}
and probably many other ways, which is great. It was just a bit odd that scala is so strongly typed, while actors use "Any" messages. Is this just because Scala actors are modeled on Erlang actors? Or is it because the untyped messages are desirable? For example, I imagine if you want to do some of Eralng's OTP tricks, like hot-swapping a running server, it might be important that you not limit the types of messages the server can receive.
I'm also aware that a language like spec# has "contracts" that allow static specification of state machines that govern use of a channel. That would be significantly more complicated than my expectations, though also clearly useful.
thanks,
Dave
- Make sure that the message I'm sending is understood by the recipient.
- Make sure that each recipient processes all of the messages that might be sent to it.
sealed abstract class FooMsg
...
class FooActor {
private val a = actor {
loop {
react {
case m: FooMsg => m match {
// exhausive match FooMsg (2)
case ...
}
case _ => throw new RuntimeException("Not a valid message")
}
}
}
// FooActors only take FooMsgs (1)
def ! (m: FooMsg) {a ! m}
}
and probably many other ways, which is great. It was just a bit odd that scala is so strongly typed, while actors use "Any" messages. Is this just because Scala actors are modeled on Erlang actors? Or is it because the untyped messages are desirable? For example, I imagine if you want to do some of Eralng's OTP tricks, like hot-swapping a running server, it might be important that you not limit the types of messages the server can receive.
I'm also aware that a language like spec# has "contracts" that allow static specification of state machines that govern use of a channel. That would be significantly more complicated than my expectations, though also clearly useful.
thanks,
Dave
Tue, 2009-08-18, 15:47
#6
Re: An altogether different actor model
I asked a similar question some time ago. Good answers were given:
http://www.nabble.com/-scala--Why-are-Scala's-actors-untyped--td18811476.html#a18811476
2009/8/18 David Melski :
> It's clear from the comments on scheduling that I'm out of my depth, here.
> But I only expect two simple things from "typed actors"
>
> Make sure that the message I'm sending is understood by the recipient.
> Make sure that each recipient processes all of the messages that might be
> sent to it.
>
> It is simple enough to wrap the existing actors so that one gets those two
> things, something like:
>
> sealed abstract class FooMsg
> ...
>
> class FooActor {
> private val a = actor {
> loop {
> react {
> case m: FooMsg => m match {
> // exhausive match FooMsg (2)
> case ...
> }
> case _ => throw new RuntimeException("Not a valid message")
> }
> }
> }
>
> // FooActors only take FooMsgs (1)
> def ! (m: FooMsg) {a ! m}
> }
>
> and probably many other ways, which is great. It was just a bit odd that
> scala is so strongly typed, while actors use "Any" messages. Is this just
> because Scala actors are modeled on Erlang actors? Or is it because the
> untyped messages are desirable? For example, I imagine if you want to do
> some of Eralng's OTP tricks, like hot-swapping a running server, it might be
> important that you not limit the types of messages the server can receive.
>
> I'm also aware that a language like spec# has "contracts" that allow static
> specification of state machines that govern use of a channel. That would be
> significantly more complicated than my expectations, though also clearly
> useful.
>
> thanks,
> Dave
>
>
Wed, 2009-08-19, 01:17
#7
Re: An altogether different actor model
David Melski wrote:
> But I only expect two simple things from "typed actors"
>
> 1. Make sure that the message I'm sending is understood by the recipient.
> 2. Make sure that each recipient processes all of the messages that might
> be sent to it.
>
One more thing:
3. I dont want to have to rewrite code because I decide to change
component X's threading/execution model between "passive" and "active",
ie convert between an Object and an Actor.
OO programming is about objects sending messages to each other. Actor
programming is about Actors sending messages to each other. The
difference is that each Actor autonomously manages its own execution,
while Objects share a thread.
The fact that this aspect has leaked into invocation syntax is unfortunate.
I personally would never build a large software system over actors
without wrapping invocations in a typed, method-based API. I know that I
will want to change my mind about who the actors in the system are as I
go, and I dont wish to rewrite masses of code between eg:
emailService.sendEmail(...)
...and...
emailService ! SendEmail(...)
..just because email dispatch became asynchronous.
-Ben
> It is simple enough to wrap the existing actors so that one gets those two
> things, something like:
>
> sealed abstract class FooMsg
> ...
>
> class FooActor {
> private val a = actor {
> loop {
> react {
> case m: FooMsg => m match {
> // exhausive match FooMsg (2)
> case ...
> }
> case _ => throw new RuntimeException("Not a valid message")
> }
> }
> }
>
> // FooActors only take FooMsgs (1)
> def ! (m: FooMsg) {a ! m}
> }
>
> and probably many other ways, which is great. It was just a bit odd that
> scala is so strongly typed, while actors use "Any" messages. Is this just
> because Scala actors are modeled on Erlang actors? Or is it because the
> untyped messages are desirable? For example, I imagine if you want to do
> some of Eralng's OTP tricks, like hot-swapping a running server, it might be
> important that you not limit the types of messages the server can receive.
>
> I'm also aware that a language like spec# has "contracts" that allow static
> specification of state machines that govern use of a channel. That would be
> significantly more complicated than my expectations, though also clearly
> useful.
>
> thanks,
> Dave
>
>
Wed, 2009-08-19, 02:27
#8
Re: An altogether different actor model
Dave,
How will wrapping an actor in an object ensure that a recipient processes all of the messages that might be sent to it. Specifically, are you claiming that wrapping an actor in an object will in all cases prevent the actor from deadlocking? If the actor is deadlocked, then even though the type of wrapping object says that the object can handle a message doesn't mean the actor is in a state that it can process the message. Perhaps your wrapper includes a timer on all message processing the actor does so that it's always in a race with a timeout that prevents potential deadlock?
case class Deadly( a : Actor ) {
var gotSignal : Boolean = true
}
Best wishes,
--greg
On Tue, Aug 18, 2009 at 7:29 AM, David Melski <dgmelski [at] gmail [dot] com> wrote:
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
How will wrapping an actor in an object ensure that a recipient processes all of the messages that might be sent to it. Specifically, are you claiming that wrapping an actor in an object will in all cases prevent the actor from deadlocking? If the actor is deadlocked, then even though the type of wrapping object says that the object can handle a message doesn't mean the actor is in a state that it can process the message. Perhaps your wrapper includes a timer on all message processing the actor does so that it's always in a race with a timeout that prevents potential deadlock?
case class Deadly( a : Actor ) {
var gotSignal : Boolean = true
}
Best wishes,
--greg
On Tue, Aug 18, 2009 at 7:29 AM, David Melski <dgmelski [at] gmail [dot] com> wrote:
It's clear from the comments on scheduling that I'm out of my depth, here. But I only expect two simple things from "typed actors"
It is simple enough to wrap the existing actors so that one gets those two things, something like:
- Make sure that the message I'm sending is understood by the recipient.
- Make sure that each recipient processes all of the messages that might be sent to it.
sealed abstract class FooMsg
...
class FooActor {
private val a = actor {
loop {
react {
case m: FooMsg => m match {
// exhausive match FooMsg (2)
case ...
}
case _ => throw new RuntimeException("Not a valid message")
}
}
}
// FooActors only take FooMsgs (1)
def ! (m: FooMsg) {a ! m}
}
and probably many other ways, which is great. It was just a bit odd that scala is so strongly typed, while actors use "Any" messages. Is this just because Scala actors are modeled on Erlang actors? Or is it because the untyped messages are desirable? For example, I imagine if you want to do some of Eralng's OTP tricks, like hot-swapping a running server, it might be important that you not limit the types of messages the server can receive.
I'm also aware that a language like spec# has "contracts" that allow static specification of state machines that govern use of a channel. That would be significantly more complicated than my expectations, though also clearly useful.
thanks,
Dave
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Wed, 2009-08-19, 05:07
#9
Re: An altogether different actor model
Dave,
Sorry... for some reason the mail client received a send event before i finished typing the code example. Sample included below. The block that handles the actual work will never get called. Moreover a pair of these objects will be stuck in livelock.
Welcome to Scala version 2.7.3.final (Java HotSpot(TM) Client VM, Java 1.5.0_19).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val de1 : DeadlyEmbrace = new DeadlyEmbrace
val de1 : DeadlyEmbrace = new DeadlyEmbrace
de1: DeadlyEmbrace = DeadlyEmbrace@eeb4a3
scala> val de2 : DeadlyEmbrace = new DeadlyEmbrace
val de2 : DeadlyEmbrace = new DeadlyEmbrace
de2: DeadlyEmbrace = DeadlyEmbrace@5679f0
scala> de1.acquaint( de2 )
de1.acquaint( de2 )
scala> de2.acquaint( de1 )
de2.acquaint( de1 )
scala> de1.show
de1.show
partner... DeadlyEmbrace@5679f0
signaled... false
scala> de2.show
de2.show
partner... DeadlyEmbrace@eeb4a3
signaled... false
scala> de1.doWork
de1.doWork
scala> signaling partner...
de2.doWork
de2.doWork
scala> signaling partner...
signaling partner...
signaling partner...
de1.show
de1.show
scala> partner... DeadlyEmbrace@5679f0
signaled... false
signaling partner...
signaling partner...
signaling partner...
signaling partner...
de2.show
de2.show
scala> partner... DeadlyEmbrace@eeb4a3
signaled... false
signaling partner...
signaling partner...
signaling partner...
signaling partner...
C-c C-cbash-3.2$
bash-3.2$
Best wishes,
--greg
import scala.actors._
import scala.actors.Actor._
trait DEMessage {
}
case class Signal() extends DEMessage
case class DoWork() extends DEMessage
case class Show() extends DEMessage
case class Acquaint( d : DeadlyEmbrace ) extends DEMessage
class DeadlyEmbrace {
def signal : Unit = {
a ! Signal()
}
def doWork : Unit = {
a ! DoWork()
}
def show : Unit = {
a ! Show()
}
def acquaint( d : DeadlyEmbrace ) : Unit = {
a ! Acquaint( d )
}
private val a = actor {
var signaled : Boolean = false
var acquaintance : Option[DeadlyEmbrace] = None
loop {
react {
case m : DEMessage => {
m match {
case msig : Signal =>
acquaintance match {
case Some( d ) => {
println( "signaling partner..." )
Thread.sleep( 10000 )
d.signal
}
case None =>
println( "waiting for a partner..." )
}
case mwork : DoWork =>
acquaintance match {
case Some( d ) => {
if ( signaled ) {
// This is where the message should be handled
println( "working..." )
}
else {
d.signal
}
}
case None => {
println( "waiting for a partner..." )
}
}
case mshow : Show => {
acquaintance match {
case Some( d ) => {
println( "partner... " + d )
println( "signaled... " + signaled )
}
case None =>
println( "waiting for a partner..." )
}
}
case macq : Acquaint => {
macq match {
case Acquaint( d ) =>
acquaintance = Some( d )
}
}
}
}
case _ => throw new RuntimeException("Not a valid message")
}
}
}
}
On Tue, Aug 18, 2009 at 6:24 PM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Sorry... for some reason the mail client received a send event before i finished typing the code example. Sample included below. The block that handles the actual work will never get called. Moreover a pair of these objects will be stuck in livelock.
Welcome to Scala version 2.7.3.final (Java HotSpot(TM) Client VM, Java 1.5.0_19).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val de1 : DeadlyEmbrace = new DeadlyEmbrace
val de1 : DeadlyEmbrace = new DeadlyEmbrace
de1: DeadlyEmbrace = DeadlyEmbrace@eeb4a3
scala> val de2 : DeadlyEmbrace = new DeadlyEmbrace
val de2 : DeadlyEmbrace = new DeadlyEmbrace
de2: DeadlyEmbrace = DeadlyEmbrace@5679f0
scala> de1.acquaint( de2 )
de1.acquaint( de2 )
scala> de2.acquaint( de1 )
de2.acquaint( de1 )
scala> de1.show
de1.show
partner... DeadlyEmbrace@5679f0
signaled... false
scala> de2.show
de2.show
partner... DeadlyEmbrace@eeb4a3
signaled... false
scala> de1.doWork
de1.doWork
scala> signaling partner...
de2.doWork
de2.doWork
scala> signaling partner...
signaling partner...
signaling partner...
de1.show
de1.show
scala> partner... DeadlyEmbrace@5679f0
signaled... false
signaling partner...
signaling partner...
signaling partner...
signaling partner...
de2.show
de2.show
scala> partner... DeadlyEmbrace@eeb4a3
signaled... false
signaling partner...
signaling partner...
signaling partner...
signaling partner...
C-c C-cbash-3.2$
bash-3.2$
Best wishes,
--greg
import scala.actors._
import scala.actors.Actor._
trait DEMessage {
}
case class Signal() extends DEMessage
case class DoWork() extends DEMessage
case class Show() extends DEMessage
case class Acquaint( d : DeadlyEmbrace ) extends DEMessage
class DeadlyEmbrace {
def signal : Unit = {
a ! Signal()
}
def doWork : Unit = {
a ! DoWork()
}
def show : Unit = {
a ! Show()
}
def acquaint( d : DeadlyEmbrace ) : Unit = {
a ! Acquaint( d )
}
private val a = actor {
var signaled : Boolean = false
var acquaintance : Option[DeadlyEmbrace] = None
loop {
react {
case m : DEMessage => {
m match {
case msig : Signal =>
acquaintance match {
case Some( d ) => {
println( "signaling partner..." )
Thread.sleep( 10000 )
d.signal
}
case None =>
println( "waiting for a partner..." )
}
case mwork : DoWork =>
acquaintance match {
case Some( d ) => {
if ( signaled ) {
// This is where the message should be handled
println( "working..." )
}
else {
d.signal
}
}
case None => {
println( "waiting for a partner..." )
}
}
case mshow : Show => {
acquaintance match {
case Some( d ) => {
println( "partner... " + d )
println( "signaled... " + signaled )
}
case None =>
println( "waiting for a partner..." )
}
}
case macq : Acquaint => {
macq match {
case Acquaint( d ) =>
acquaintance = Some( d )
}
}
}
}
case _ => throw new RuntimeException("Not a valid message")
}
}
}
}
On Tue, Aug 18, 2009 at 6:24 PM, Meredith Gregory <lgreg [dot] meredith [at] gmail [dot] com> wrote:
Dave,
How will wrapping an actor in an object ensure that a recipient processes all of the messages that might be sent to it. Specifically, are you claiming that wrapping an actor in an object will in all cases prevent the actor from deadlocking? If the actor is deadlocked, then even though the type of wrapping object says that the object can handle a message doesn't mean the actor is in a state that it can process the message. Perhaps your wrapper includes a timer on all message processing the actor does so that it's always in a race with a timeout that prevents potential deadlock?
case class Deadly( a : Actor ) {
var gotSignal : Boolean = true
}
Best wishes,
--greg
On Tue, Aug 18, 2009 at 7:29 AM, David Melski <dgmelski [at] gmail [dot] com> wrote:
It's clear from the comments on scheduling that I'm out of my depth, here. But I only expect two simple things from "typed actors"
It is simple enough to wrap the existing actors so that one gets those two things, something like:
- Make sure that the message I'm sending is understood by the recipient.
- Make sure that each recipient processes all of the messages that might be sent to it.
sealed abstract class FooMsg
...
class FooActor {
private val a = actor {
loop {
react {
case m: FooMsg => m match {
// exhausive match FooMsg (2)
case ...
}
case _ => throw new RuntimeException("Not a valid message")
}
}
}
// FooActors only take FooMsgs (1)
def ! (m: FooMsg) {a ! m}
}
and probably many other ways, which is great. It was just a bit odd that scala is so strongly typed, while actors use "Any" messages. Is this just because Scala actors are modeled on Erlang actors? Or is it because the untyped messages are desirable? For example, I imagine if you want to do some of Eralng's OTP tricks, like hot-swapping a running server, it might be important that you not limit the types of messages the server can receive.
I'm also aware that a language like spec# has "contracts" that allow static specification of state machines that govern use of a channel. That would be significantly more complicated than my expectations, though also clearly useful.
thanks,
Dave
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117
+1 206.650.3740
http://biosimilarity.blogspot.com
Wed, 2009-08-19, 08:37
#10
Re: An altogether different actor model
Meredith Gregory wrote:
> How will wrapping an actor in an object ensure that a recipient processes
> all of the messages that might be sent to it.
Hi Greg,
I think David was alluding to the issue that if a message is sent to an
actor that its doesnt understand, the message will remain unmatched in
its mailbox indefinitely. A possible memory leak. Strongly typing actors
ensures they will be able to match on and thus consume any message that
can be sent to them via the typed client interface.
That's not to say that the issues you've mentioned re: lack of
scheduling semantics are resolved; I agree that they're not, and that
presently you just have to accept that pragmatically messages do happen
to get delivered "sometime" in the present implementation.
-Ben
> On Tue, Aug 18, 2009 at 7:29 AM, David Melski wrote:
>
>> But I only expect two simple things from "typed actors"
>>
>> 1. Make sure that the message I'm sending is understood by the
>> recipient.
>> 2. Make sure that each recipient processes all of the messages that
>> might be sent to it.
>>
>> It is simple enough to wrap the existing actors so that one gets those two
>> things, something like:
>>
>> sealed abstract class FooMsg
>> ...
>>
>> class FooActor {
>> private val a = actor {
>> loop {
>> react {
>> case m: FooMsg => m match {
>> // exhausive match FooMsg (2)
>> case ...
>> }
>> case _ => throw new RuntimeException("Not a valid message")
>> }
>> }
>> }
>>
>> // FooActors only take FooMsgs (1)
>> def ! (m: FooMsg) {a ! m}
>> }
>>
>> and probably many other ways, which is great. It was just a bit odd that
>> scala is so strongly typed, while actors use "Any" messages. Is this just
>> because Scala actors are modeled on Erlang actors? Or is it because the
>> untyped messages are desirable? For example, I imagine if you want to do
>> some of Eralng's OTP tricks, like hot-swapping a running server, it might be
>> important that you not limit the types of messages the server can receive.
>>
>> I'm also aware that a language like spec# has "contracts" that allow static
>> specification of state machines that govern use of a channel. That would be
>> significantly more complicated than my expectations, though also clearly
>> useful.
>>
>> thanks,
>> Dave
>>
>>
>>
>
>
>
Wed, 2009-08-19, 14:47
#11
Re: An altogether different actor model
2009/8/18 Ben Hutchison :
> Hi Greg,
>
> I'm intrigued by the contrast between your two statements about Actors and
> Static Typing copied below. The second one reflects my evaluation of Scala
> actors, so Im quite interested to see how you might better fit them into
> static typing - that's surely in the future of Actors.
>
> I suspect you might have tried to explain that in the latter part of your
> letter, but I didn't understand it sufficiently. If you could give a more
> concrete example in Scala-like syntax, that would be interesting.
>
> My present feeling is that Scala actors would best evolve towards a classic
> API, ie a set of named functions with typed parameters and return values.
> Invoking on an Actor shouldn't look so different from invoking on an Object,
> IMO. Jonas Boner blogged about some work in this area in Scala OTP
> [http://jonasboner.com/2008/12/11/real-world-scala-fault-tolerant-concurrent-asynchronous-components.html].
> One difficulty is the way the a/synchronous divide gets papered over, but
> I'm not convinced that's unsurmountable.What's your opinion on this type of
> approach?
FWIW, I've taken these ideas further in the Akka Project. Which is now
a production impl of both Actors and Active Objects addressing some of
the shortcomings in the Scala Actors library.
Read more here:
http://wiki.github.com/jboner/akka/reference-active-objects-java-api
>
> -Ben
>
> Meredith Gregory wrote:
>>
>> Actors represent an interesting sweet spot because they
>>
>> ... - and turn out to fit into a static typing discipline
>>
>
> Meredith Gregory also wrote:
>>
>> Those familiar with Scala's
>> "actors" have certainly experienced a similar step over the edge, in the
>> sense that programming with Scala "actors" is not genuinely integrated
>> with
>> or supported by all the very sophisticated typing machinery of the
>> functional kernel of the language
>
>
> --
>
>
>
> *Ben Hutchison
> Senior Developer
> * Level 2 476 St Kilda Road Melbourne VIC 3004
> T 613 8807 5252 | F 613 8807 5203 | M 0423 879 534 | www.ibsglobalweb.com
>
>
>
>
Wed, 2009-08-19, 15:37
#12
Re: An altogether different actor model
Ben is correct. In addition to the memory leak, I'll get unexpected behavior if I forget to add code to handle a particular message. This is exactly why the compiler warns about "match is not exhaustive" for matches against a sealed class. In your example, if you change DEMessage to an sealed class, the compiler will use precisely this mechanism to ensure the actor does something for all messages it might receive (at "m match").
This is admittedly very limited. It doesn't handle nested reacts very well, where you want the actor to process different types of messages depending on what "state" it is in. It says nothing about deadlock. It's just what I would have expected.
BTW, I was not complaining, just curious. I have very little experience with concurrent programming, and the actors library seems great to my untrained eyes.
Thanks to Ricky for pointing to the earlier thread.
Dave
On Wed, Aug 19, 2009 at 3:33 AM, Ben Hutchison <benh [at] ibsglobalweb [dot] com> wrote:
This is admittedly very limited. It doesn't handle nested reacts very well, where you want the actor to process different types of messages depending on what "state" it is in. It says nothing about deadlock. It's just what I would have expected.
BTW, I was not complaining, just curious. I have very little experience with concurrent programming, and the actors library seems great to my untrained eyes.
Thanks to Ricky for pointing to the earlier thread.
Dave
On Wed, Aug 19, 2009 at 3:33 AM, Ben Hutchison <benh [at] ibsglobalweb [dot] com> wrote:
Meredith Gregory wrote:
How will wrapping an actor in an object ensure that a recipient processesHi Greg,
all of the messages that might be sent to it.
I think David was alluding to the issue that if a message is sent to an actor that its doesnt understand, the message will remain unmatched in its mailbox indefinitely. A possible memory leak. Strongly typing actors ensures they will be able to match on and thus consume any message that can be sent to them via the typed client interface.
That's not to say that the issues you've mentioned re: lack of scheduling semantics are resolved; I agree that they're not, and that presently you just have to accept that pragmatically messages do happen to get delivered "sometime" in the present implementation.
-Ben
On Tue, Aug 18, 2009 at 7:29 AM, David Melski <dgmelski [at] gmail [dot] com> wrote:
But I only expect two simple things from "typed actors"
1. Make sure that the message I'm sending is understood by the
recipient.
2. Make sure that each recipient processes all of the messages that
might be sent to it.
It is simple enough to wrap the existing actors so that one gets those two
things, something like:
sealed abstract class FooMsg
...
class FooActor {
private val a = actor {
loop {
react {
case m: FooMsg => m match {
// exhausive match FooMsg (2)
case ...
}
case _ => throw new RuntimeException("Not a valid message")
}
}
}
// FooActors only take FooMsgs (1)
def ! (m: FooMsg) {a ! m}
}
and probably many other ways, which is great. It was just a bit odd that
scala is so strongly typed, while actors use "Any" messages. Is this just
because Scala actors are modeled on Erlang actors? Or is it because the
untyped messages are desirable? For example, I imagine if you want to do
some of Eralng's OTP tricks, like hot-swapping a running server, it might be
important that you not limit the types of messages the server can receive.
I'm also aware that a language like spec# has "contracts" that allow static
specification of state machines that govern use of a channel. That would be
significantly more complicated than my expectations, though also clearly
useful.
thanks,
Dave
Hi Greg,
I'm intrigued by the contrast between your two statements about Actors
and Static Typing copied below. The second one reflects my evaluation of
Scala actors, so Im quite interested to see how you might better fit
them into static typing - that's surely in the future of Actors.
I suspect you might have tried to explain that in the latter part of
your letter, but I didn't understand it sufficiently. If you could give
a more concrete example in Scala-like syntax, that would be interesting.
My present feeling is that Scala actors would best evolve towards a
classic API, ie a set of named functions with typed parameters and
return values. Invoking on an Actor shouldn't look so different from
invoking on an Object, IMO. Jonas Boner blogged about some work in this
area in Scala OTP
[http://jonasboner.com/2008/12/11/real-world-scala-fault-tolerant-concurrent-asynchronous-components.html].
One difficulty is the way the a/synchronous divide gets papered over,
but I'm not convinced that's unsurmountable.What's your opinion on this
type of approach?
-Ben
Meredith Gregory wrote:
> Actors represent an interesting sweet spot because they
>
> ... - and turn out to fit into a static typing discipline
>
Meredith Gregory also wrote:
> Those familiar with Scala's
> "actors" have certainly experienced a similar step over the edge, in the
> sense that programming with Scala "actors" is not genuinely integrated with
> or supported by all the very sophisticated typing machinery of the
> functional kernel of the language