Hi Endre,

Concurrency alone isn't a reason to give up type safety. Future-based APIs
are typed even though futures may never complete.

(I'm not sure what you refer to with message loss; I didn't talk about
that.)

It's true that in the actor model each state change can change the set of
valid message types. But with regular objects, some method calls are also
invalid depending on the current state, they may even be invalid based on
parameter values and not types, and yet we don't give up on static typing.

I understand that with the current actor model, static typing probably
isn't possible. But I don't understand why a different model couldn't in
principle capture most or all of the benefits of actors, certainly
including concurrency and indeterminacy, and still preserve typing.

I'm sorry if I'm being obtuse here and missing something fundamental.


On Sun, Mar 9, 2014 at 10:30 PM, Endre Varga <endre.va...@typesafe.com>wrote:

> Hi Daniel,
>
> Please read carefully, in my second example there is no message loss.
> Concurrency is enough to have the same result since arbitrary delay is
> indistinguishable from message loss in any finite window of time.
>
> -Endre
>
>
> On Sun, Mar 9, 2014 at 8:31 PM, Daniel Armak <danar...@gmail.com> wrote:
>
>> Part of the difficulty I'm experiencing is that most of the time I want
>> to write code that is definitely local - a set of actors that are
>> guaranteed to run on the same JVM - but communication between them has to
>> deal with complications that only really arise from distributed
>> computation, like loss of type safety.
>>
>> Maybe the concepts of an actor as concurrency unit with private mutable
>> state and failure management, and actor as a possibly-remote entity with no
>> guaranteed delivery, would be better partially separated. In my admittedly
>> limited experience, separating actors into deployment sets is part of the
>> system design, needs careful planning, and doesn't change often. Inside
>> each local set, the benefits of guaranteed locality would be large
>> (messages aren't lost, static typing, etc.)
>>
>>
>> On Sun, Mar 9, 2014 at 7:42 PM, Endre Varga <endre.va...@typesafe.com>wrote:
>>
>>> Hi Daniel,
>>>
>>> The issue is that type systems are designed for local and not
>>> distributed computations. Let's look at an example.
>>>
>>> Imagine an actor that has three states, A, B and C
>>>
>>> In state A it accepts messages of type X, and when received one, it
>>> transitions to B
>>> In state B it accepts messages of type X and Y. When X is received,
>>> transitions to C, if Y, then stays in B
>>> In state C it accepts messages of type Z
>>>
>>> Now you send to an actor starting from state A a message X. Two things
>>> can happen:
>>>  - X is delivered, so the possible accepted types are {X, Y}
>>>  - X is lost, so the accepted type is {X}
>>> The intersection of those is {X}.
>>>
>>> Now imagine that you send another message X. Three things can happen:
>>>  - both X's were delivered, so the accepted type is {Z}
>>>  - only one of the X's were delivered, the other is lost, so the
>>> accepted types are {X, Y}
>>>  - both X's were lost, the accepted type is {X}
>>> The intersection of the above cases is the empty set.
>>>
>>> So what should be the local type representation of an actor that you
>>> have sent two messages of type X?
>>>
>>> Let's modify the example, and assume that there was no message loss, but
>>> let's take the viewpoint of another sender. This sender knows that two X's
>>> were sent to our example actor by the other sender. What messages can we
>>> send? There are three scenarios:
>>>  - both X's sent by the other sender has arrived already, so the
>>> accepted type is {Z}
>>>  - only the first X sent by the other sender has arrived yet, so the
>>> accepted types are {X, Y}
>>>  - no X's has arrived yet, accepted type is {X}
>>> The intersection of the above cases is the empty set.
>>>
>>> As you see, without receiving a reply from an actor, the provable type
>>> of an actor is usually Nothing, or something useless. Only replies can
>>> convey the *possible* type of an actor, and even that cannot be guaranteed
>>> if there are concurrent senders.
>>>
>>> -Endre
>>>
>>>
>>> On Sat, Mar 8, 2014 at 8:08 PM, Daniel Armak <danar...@gmail.com> wrote:
>>>
>>>> My intent was definitely to throw away type safety. In my example you
>>>> can wrap any ActorRef using any trait, and you can extract and use the raw
>>>> ActorRef from a typed wrapper. The only thing I was trying to salvage was
>>>> for the sender to declare what kind of actor / behavior they thought they
>>>> were dealing with.
>>>>
>>>> But I'm taking your advice to heart. I'll try to use pure actors until
>>>> I have more of a sense of how problematic various issues are.
>>>>
>>>> Thanks!
>>>>
>>>> Daniel Armak
>>>>
>>>>
>>>> On Sat, Mar 8, 2014 at 8:59 PM, Derek Wyatt <de...@derekwyatt.org>wrote:
>>>>
>>>>> On 8 March 2014 13:31, Daniel Armak <danar...@gmail.com> wrote:
>>>>>
>>>>>> Hi Derek.
>>>>>>
>>>>>> Yes, I'm aware of the tradeoffs and the reasons for them. It just
>>>>>> seems to me there ought to be a middle road.
>>>>>>
>>>>>> Here's an idea off the top of my head. If remoting is going to be
>>>>>> transparent, there won't be compile time type assurance. So let's give up
>>>>>> on local type assurance too, and just use types for documentation and
>>>>>> refactoring; that still seems a lot better than nothing.
>>>>>>
>>>>>> Suppose for each actor I wanted to implement, I declare a trait with
>>>>>> a method for each message it might receive. Each method must receive
>>>>>> exactly one parameter, which is the message, and return Unit:
>>>>>>
>>>>>> trait Printer {
>>>>>>   def print(msg: String): Unit
>>>>>> }
>>>>>>
>>>>>> The method name 'print' is just for documentation; only the parameter
>>>>>> is sent as the message. This preserves transparency with the actor model;
>>>>>> you don't rely on the trait implementation to build the actual message.
>>>>>>
>>>>>> The user of an ActorRef would use a wrapper (value type around the
>>>>>> ActorRef) generated by a macro to implement this trait. The macro would
>>>>>> also validate the trait: each method has one argument, returns Unit, and
>>>>>> all argument types are distinct. Each method call would be implemented 
>>>>>> as a
>>>>>> send().
>>>>>>
>>>>>> val actor : ActorRef = ???
>>>>>> val typedActor: Printer = mymacro.wrap[Printer](actor) // Or is there
>>>>>> a way to declare types with macros? I forget.
>>>>>> typedActor.print("my message")
>>>>>>
>>>>>> The macro would add an (implicit sender: ActorRef) argument to each
>>>>>> method.
>>>>>>
>>>>>> The actor itself would extend the Printer trait and implement its
>>>>>> methods. Another macro would concatenate them to implement receive:
>>>>>>
>>>>>> class PrinterActor extends Actor with Printer with
>>>>>> TypedActorMacro[Printer] {
>>>>>>   def print(msg: String):
>>>>>> }
>>>>>>
>>>>>> To use become/unbecome, we could introduce something more
>>>>>> complicated. Or, even, use the Printer trait only on the sender side - it
>>>>>> would still be useful. This is just a rough outline. Do you think it 
>>>>>> might
>>>>>> be useful, or do you think I shouldn't go down this road and trying to
>>>>>> marry akka actors and (actor) types is a futile endeavour?
>>>>>>
>>>>>
>>>>> Not futile, but highly suspect.  You've barely scratched the surface
>>>>> with the above and much research is way ahead of you here.
>>>>>
>>>>> The ??? you have above isn't exactly trivial to implement, for
>>>>> example. What's more is that you've probably thrown away a ton more
>>>>> features in the process.  e.g.:
>>>>>
>>>>> class MyActor(printActor: PrinterActor) { ... }
>>>>>
>>>>> // later...
>>>>>
>>>>> val myActor =
>>>>>   MyActor.props(loadBalancer(printerActor.props()))
>>>>> // oops. Does the "loadBalancer" now have to
>>>>> // implement Printer?  What if it's a load
>>>>> // balancer in front of scatter gather routers
>>>>> // that talk to forwarders that talk to various
>>>>> // different versions of Printers?  Does everyone
>>>>> // have to implement the same API?  If not, how
>>>>> // are you not throwing away type safety?  And, if so
>>>>> // how am I doing anything but writing annoying code
>>>>> // that keeps me a slave to the API?  And how do I
>>>>> // easily manage API changes, and so on, and so forth?
>>>>>
>>>>> Maybe not theoretically futile, but practically?  Probably :)
>>>>>
>>>>> To be perfectly honest, it seems as though you're trying to "fix" a
>>>>> problem without having travelled a mile in its shoes yet.  There are
>>>>> subsets of the problem that are much more important and more possible to
>>>>> cage, and you will see them as you progress.  When you do, focusing on
>>>>> those (should you still believe them to be worth it) might be the far
>>>>> better option.
>>>>>
>>>>>
>>>>>>
>>>>>> Thanks!
>>>>>>
>>>>>> On Sat, Mar 8, 2014 at 7:51 PM, Derek Wyatt <de...@derekwyatt.org>wrote:
>>>>>>
>>>>>>> What you're experiencing is a trade-off.  Actors provide a trade-off
>>>>>>> that you don't seem to be taking into account; endpoints (Actors) are
>>>>>>> untyped and the messages that they handle are strongly typed.
>>>>>>>
>>>>>>> You can't have an Actor be able to process "anything" with a
>>>>>>> type-specific receive method.  With Actor programming, I should be able 
>>>>>>> to
>>>>>>> add as many intermediaries in the message flow as I like and not disturb
>>>>>>> the two endpoints. The intermediaries should equally be ignorant of 
>>>>>>> what's
>>>>>>> happening (load balancers, routers, loggers, cachers, mediators,
>>>>>>> scatter-gather, and so forth).  You should also be able to move them 
>>>>>>> around
>>>>>>> a cluster without disturbing the endpoints.  You can also set up dynamic
>>>>>>> delegation in an Actor without it having to really understand what's 
>>>>>>> going
>>>>>>> on - for example, an Actor that speaks the "main dialect" but delegates 
>>>>>>> to
>>>>>>> something else when it doesn't understand what's being said.
>>>>>>>
>>>>>>> If you want to eliminate all of those features, then you will be
>>>>>>> able to get the type-safe determinism you're looking for (so long as you
>>>>>>> stay in the same JVM - crossing JVMs will incur a "what the hell am I
>>>>>>> *really* talking to?" question that eliminates a compile time
>>>>>>> assurance). Roland also tried bringing the best of both worlds together
>>>>>>> using Typed Channels but I think it was lacking a high enough success 
>>>>>>> level
>>>>>>> to survive, but it might be a way to get closer to your ideal.
>>>>>>>
>>>>>>> In short, you're giving up type safety in order to open the door to
>>>>>>> a whole new set of facilities.  Don't want to lose the type-safety?  
>>>>>>> Close
>>>>>>> the door :)
>>>>>>>
>>>>>>> I had the exact same reservations as you have right now.  I tried to
>>>>>>> reconcile them myself, using typed actors and my world turned into a 
>>>>>>> pile
>>>>>>> of crap... I got no real flexibility out of that system.  There was a
>>>>>>> cognitive overhead to switching to actors and no benefit.
>>>>>>>
>>>>>>> In the end, I learned to embrace the patterns and philosophy and
>>>>>>> grew to love it so much that I wrote a book about it (the first one, I
>>>>>>> think) and now code in Scala and Akka every single day.  Your mileage 
>>>>>>> may
>>>>>>> vary :)
>>>>>>>
>>>>>>>
>>>>>>> On Friday, March 7, 2014 5:10:23 PM UTC-5, Daniel Armak wrote:
>>>>>>>>
>>>>>>>> Hello,
>>>>>>>>
>>>>>>>> I hope someone will take the time to read this message (sorry about
>>>>>>>> its length) and help me.
>>>>>>>>
>>>>>>>> I'm writing a fairly large system from scratch in Scala. I love the
>>>>>>>> rich typing and functional programming style, and I have experience 
>>>>>>>> with
>>>>>>>> future-based programming, but not actors.
>>>>>>>>
>>>>>>>> When I try to use actors, I feel like I'm giving up static typing,
>>>>>>>> even the basic feature of a type declaring its methods (=received
>>>>>>>> messages). Using partial functions feels like casting, because I
>>>>>>>> really want to assert that the 'partial' function will always match.
>>>>>>>>
>>>>>>>> This can't be right. How do you reconcile the two worlds?
>>>>>>>>
>>>>>>>> Specific issues I'm struggling with:
>>>>>>>>
>>>>>>>> 1. Typed code is discoverable via methods and fields. An actor
>>>>>>>> relies on documentation.
>>>>>>>>
>>>>>>>> One option is to define all messages an actor can receive in its
>>>>>>>> companion object, and document each message; but many libraries (e.g.
>>>>>>>> spray) define many different actors that all send and receive the same
>>>>>>>> types (eg HttpRequest), which is convenient for forwarding messages 
>>>>>>>> between
>>>>>>>> actors. But then the *only* way to figure out which messages are legal 
>>>>>>>> and
>>>>>>>> the semantics of what they do is to read the docs.
>>>>>>>>
>>>>>>>> When an actor manages complex state and might receive ten or twenty
>>>>>>>> different message types, this is hard to manage.
>>>>>>>>
>>>>>>>> Even if I document the actor, this documentation is still not
>>>>>>>> discoverable because the client has an ActorRef, not an
>>>>>>>> ActorRef[MyActorTrait]. So I have to figure out manually what behavior 
>>>>>>>> this
>>>>>>>> actor is expected to implement and read the docs for that.
>>>>>>>>
>>>>>>>> 2. Refactoring actors is hard. To make a non-backward-compatible
>>>>>>>> API change to an actor, I have to go over all references to the message
>>>>>>>> types involved. No more 'find all usages of method' or 'rename method'.
>>>>>>>>
>>>>>>>> 3. Typed Actors lack important Actor features (become/unbecome,
>>>>>>>> etc), have to declare exceptions, suffer a proxy performance penalty, 
>>>>>>>> and
>>>>>>>> aren't recommended as a replacement for actors in general.
>>>>>>>>
>>>>>>>>
>>>>>>>> I understand that features like become() and remoting make it
>>>>>>>> difficult to type actors, and maybe this is just an unsolved difficult
>>>>>>>> problem. So how do mature actor-based projects handle these issues? 
>>>>>>>> How can
>>>>>>>> I have the benefits of both actors and static typing?
>>>>>>>>
>>>>>>>> TIA for any insight.
>>>>>>>>
>>>>>>>> Daniel Armak
>>>>>>>>
>>>>>>>  --
>>>>>>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>> >>>>>>>>>> Check the FAQ:
>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>> >>>>>>>>>> Search the archives:
>>>>>>> https://groups.google.com/group/akka-user
>>>>>>> ---
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "Akka User List" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>>> send an email to akka-user+unsubscr...@googlegroups.com.
>>>>>>> To post to this group, send email to akka-user@googlegroups.com.
>>>>>>> Visit this group at http://groups.google.com/group/akka-user.
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>>  --
>>>>>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>> >>>>>>>>>> Check the FAQ:
>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>> >>>>>>>>>> Search the archives:
>>>>>> https://groups.google.com/group/akka-user
>>>>>> ---
>>>>>> You received this message because you are subscribed to a topic in
>>>>>> the Google Groups "Akka User List" group.
>>>>>> To unsubscribe from this topic, visit
>>>>>> https://groups.google.com/d/topic/akka-user/rLKk7-D_jHQ/unsubscribe.
>>>>>> To unsubscribe from this group and all its topics, send an email to
>>>>>> akka-user+unsubscr...@googlegroups.com.
>>>>>>
>>>>>> To post to this group, send email to akka-user@googlegroups.com.
>>>>>> Visit this group at http://groups.google.com/group/akka-user.
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>>  --
>>>>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>> >>>>>>>>>> Check the FAQ:
>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>> >>>>>>>>>> Search the archives:
>>>>> https://groups.google.com/group/akka-user
>>>>> ---
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups "Akka User List" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>>> an email to akka-user+unsubscr...@googlegroups.com.
>>>>> To post to this group, send email to akka-user@googlegroups.com.
>>>>> Visit this group at http://groups.google.com/group/akka-user.
>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>
>>>>
>>>>  --
>>>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>>>> >>>>>>>>>> Check the FAQ:
>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>> >>>>>>>>>> Search the archives:
>>>> https://groups.google.com/group/akka-user
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Akka User List" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to akka-user+unsubscr...@googlegroups.com.
>>>> To post to this group, send email to akka-user@googlegroups.com.
>>>> Visit this group at http://groups.google.com/group/akka-user.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>  --
>>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>>> >>>>>>>>>> Check the FAQ:
>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>> >>>>>>>>>> Search the archives:
>>> https://groups.google.com/group/akka-user
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Akka User List" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to akka-user+unsubscr...@googlegroups.com.
>>> To post to this group, send email to akka-user@googlegroups.com.
>>> Visit this group at http://groups.google.com/group/akka-user.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
>> >>>>>>>>>> Read the docs: http://akka.io/docs/
>> >>>>>>>>>> Check the FAQ:
>> http://doc.akka.io/docs/akka/current/additional/faq.html
>> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Akka User List" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to akka-user+unsubscr...@googlegroups.com.
>> To post to this group, send email to akka-user@googlegroups.com.
>> Visit this group at http://groups.google.com/group/akka-user.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> >>>>>>>>>> Read the docs: http://akka.io/docs/
> >>>>>>>>>> Check the FAQ:
> http://doc.akka.io/docs/akka/current/additional/faq.html
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> ---
> You received this message because you are subscribed to the Google Groups
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to akka-user+unsubscr...@googlegroups.com.
> To post to this group, send email to akka-user@googlegroups.com.
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to akka-user+unsubscr...@googlegroups.com.
To post to this group, send email to akka-user@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to