<div dir="ltr">Hi all,<div><br></div><div>First of all, my apologies for the long email. The subject is somewhat esoteric and therefore not easily expressed in a short email.<br><div><br></div><div>I'm following up on this email thread [1] from a slightly different perspective. This time I'd like to focus on the abstractions supported by Erlang vs. Akka rather than questions regarding availability of skilled developers or the technical superiority of one VM vs. the other.</div><div><br></div><div>Akka, on the surface, has first-class concepts that aren't supported by Erlang (e.g., Try, Future, Observable). By "first-class" I mean concepts/capabilities that are directly supported in the language and/or framework. For example, Erlang/OTP includes capabilities and concepts such as gen_server. Libraries (e.g., poolboy) address those that aren't available in Erlang/OTP.  [2] almost addresses some of those questions, specifically Fred Hebert's and Garrett Smith's responses.</div><div><br></div><div>Fred's response in [2] is interesting and informative, but it misses the mark in that it's up to the developer to know/understand how and when to implement the appropriate pattern. That's what capabilities such as gen_server are intended to eliminate. It gets even more interesting when discussing composable operations a la Akka. Here are 2 concepts in Akka that as far as I know aren't directly supported in Erlang. These only illustrate what's possible with the "Try" concept, but are also applicable to Future and Observable.</div><div><br></div><div>1. The concept that an operation might fail (i.e., the "Try" type in Akka).</div><div>2. Being able to easily compose operations that might fail in a way where the logic to detect and react to the failure can be expressed separately from the main logic path, aka the "happy path". </div><div><br></div><div>Here's an example of the first (in Scala, taken from the Coursera course on Principles of Reactive Programming). It's simplistic, but I think it's applicable in more complicated use cases. Hopefully the Scala is pretty self-explanatory:</div><div><br></div><div>1 val coins: Try[List[Coin]] = adventure.collectCoins()</div><div>2 </div><div>3 val treasure: Try[Treasure] = coins match {</div><div>4    case Success(cs) => adventure.buyTreasure(cs)</div><div>5    case failure @ Failure(t) => failure</div><div>6 }</div><div><br></div><div>Basically what this is explicitly saying is that adventure.collectCoins() may fail and the success or failure of that operation can be used in the next operation which is to buy treasure using those coins. At this point this is just expressing the semantics of the operation directly in the code, namely that the operation may fail (as is also the case in buyTreasure). This isn't a programming error, it's just expressing that perhaps the adventure character couldn't collect coins and/or wasn't able to buy treasure (maybe they didn't have enough coins). So Erlang's "Let It Crash" philosophy isn't applicable.  It can be argued that the block at lines 3-5 just a case expression, but this misses the point that the language directly expresses, through Try[], that both collectCoins() and buyTreasure can fail.</div><div><br></div><div>The example above is interesting from a semantic perspective, but it's mixing the happy path with failure handling. This is where the next concept/capability of Akka is interesting, namely the ability to compose operations while separating the failure handling path from the "happy path".  Here's the follow-on example from the same course:</div><div><br></div><div>1  val treasure: Try[Treasure] = </div><div>2    adventure.collectCoins().flatMap(coins => {</div><div>3       adventure.buyTreasure(coins)</div><div>4    })</div><div>5  </div><div>6  treasure match {</div><div>7     case Success(successValue) => </div><div>9        do something like continue to the next challenge...</div><div>10   case Failure(errorValue) => </div><div>11     do something like make the character repeat the previous challenge...</div><div><br></div><div>So the "happy path" of collectCoins() and buyTreasure() isn't intermingled with what to do if one or both of these operations fail. Specifically, buyTreasure() won't throw an exception if collectCoins() fails. I don't know of any way to express this in Erlang. </div><div><br></div><div>As far as I know Erlang doesn't support "Try" and the associated use of it in "match". In Akka this support is provided by monads. erlando is an Erlang library intended to provide monad support, but monads aren't baked into the language. And "Try" just applies to synchronous operations. "Future" implements the same semantics to async operations. "Observable" implements the same semantics to asynchronous stream operations.<br></div></div><div><br></div><div>I don't have enough real-world experience in whether or not these concepts are encountered in day-to-day "reactive" programming in Erlang or Scala/Akka, but they do seem useful. This leads me to my questions:</div><div><br></div><div>1. Are these concepts generally useful or just interesting from an academic perspective?</div><div>2. Would it be useful to support these capabilities as first-class concepts in Erlang (similar to gen_servers)? Or is this so trivial in Erlang that it's not worth making these first class capabilities?  </div><div>3. Is there any way to express these capabilities in Erlang (in addition to the rpc:async_call as described by Fred in [2], which only covers Futures, and doesn't support composition)? If there is I think a description of the pattern would be generally useful (Here's a plug for Garrett's new <a href="http://erlangpatterns.org">erlangpatterns.org</a>).</div><div>4. Is there anything else significant to discuss about this?</div><div><br></div><div>Thanks,<br>Rich</div><div><br></div><div>[1] <a href="http://erlang.org/pipermail/erlang-questions/2014-August/080699.html" target="_blank">http://erlang.org/pipermail/erlang-questions/2014-August/080699.html</a></div><div>[2] <a href="http://erlang.org/pipermail/erlang-questions/2012-November/070679.html" target="_blank">http://erlang.org/pipermail/erlang-questions/2012-November/070679.html</a></div></div>