Akka typed-channels

Roland Kuhn
Roland KuhnCTO at Actyx AG
Typed Channels
                              and
                           Macros
                           Dr. Roland Kuhn
                              @rolandkuhn




söndag 10 februari 13
The Problem



                  someActor ! CommandOne




söndag 10 februari 13
The Problem


                  trait Command
                  case class CommandOne(param: String) extends Command

                  someActor ! CommandOne




söndag 10 februari 13
The Vision


                           someActor <-!- CommandOne(”msg”)




                        because the other does not compile

söndag 10 februari 13
But How?


                        • ActorRef must know about message types
                          – Actor type must be parameterized
                        • Message type is verified against that




söndag 10 februari 13
And the replies?


                            val f: Future[Response] =

                        someActor <-?- CommandOne(”hello”)




                         because the compiler knows

söndag 10 februari 13
And How This?


                        • ActorRef must know reply types
                          – Actor must be parameterized with them
                        • Reply types are extracted at call site




söndag 10 februari 13
No Type Pollution

                        • Generic Filter/Transform Actors
                          – accept management commands
                          – pass on generic other type
                        • Using just one type is not enough!
                        • Need to use type unions and allow multiple
                          possible reply types for one input



söndag 10 februari 13
Actors Do Compose


                         msg -?-> firstActor -?-> secondActor -!-> client

                        msg -?-> someService -*-> (_ map httpOk) -!-> client




                                Process wiring from the outside

söndag 10 februari 13
The Result:




söndag 10 februari 13
Type-Safe Composability

                             of

                        Actor Systems


söndag 10 februari 13
Relation to π-calculus


                        • Actors are composite processes
                        • Actor types are structural, not nominal
                        • wiring A͡B can be done situationally


                            http://doc.akka.io/ see Typed Channels

söndag 10 februari 13
That was the
                            Eloi world
                        Now we’re going to visit the Morlocks




söndag 10 februari 13
The Implementation

                        • Tagged type union with
                          :+:[(In, Out), ChannelList] <: ChannelList

                        • Value class ChannelRef[…](val a: ActorRef)
                        • Actor mixin Channels[…]
                        • WrappedMessage[…, LUB](val m: LUB)
                        • ops desugar to tell/ask after type check


söndag 10 februari 13
How to Declare it?
                  class OpinionatedEcho extends Actor
                      with Channels[TNil, (String, String) :+: TNil] {

                        channel[String] { (str, sender) ⇒ sender <-!- str }
                        // or
                        channel[String] {
                          case (”hello”, sender) ⇒ sender <-!- ”world”
                          case (x, sender)       ⇒ sender <-!- s”dunno: $x”
                        }

                  }




                           “sender” will accept only String messages

söndag 10 februari 13
First Problem: Lambdas

                        • Type-checker transforms lambda before the
                          macro call
                          – pattern matches or PartialFunction literals
                            generate checks depending on static type info
                        • Behavior is not an argument to “channels”
                        • macro only emits object with right “apply”



söndag 10 februari 13
First Problem: Lambdas
                        private class Behaviorist[-R, Ch: ru.TypeTag](
                            wrapped: Boolean) extends (R ⇒ Unit) {
                          // ...
                            def apply(recv: R): Unit = {
                              val tt = ru.typeTag[Ch]
                                behavior ++= (
                                  for (t ← inputChannels(ru)(tt.tpe))
                                  yield
                                   tt.mirror.runtimeClass(t.widen) -> ff(recv))
                            }
                        }



                                calling channels[_] registers the behavior

söndag 10 februari 13
The Gory Details
                        def impl[LUB, ReplyChannels <: ChannelList,
                            MsgTChan <: ChannelList,
                            MsgT: c.WeakTypeTag,
                            MyCh <: ChannelList: c.WeakTypeTag,
                            ParentCh <: ChannelList: c.WeakTypeTag](
                              c: Context {
                                type PrefixType = Channels[ParentCh, MyCh]
                              }): c.Expr[(Nothing ⇒ Unit)] = {
                         // some type calculations happen here
                         val prepTree = reify(...)
                         reify {
                           prepTree.splice
                           c.prefix.splice.behaviorist[
                             (MsgT, ChannelRef[ReplyChannels]) ⇒ Unit, MsgT](
                               bool(c, false).splice)(universe.typeTag[MsgT])
                         }
                    }



söndag 10 februari 13
The Gory Details
                        trait Channels[P <: ChannelList, C <: ChannelList] {
                          this: Actor ⇒


                         def channel[T]: (Nothing ⇒ Unit) =
                           macro macros.Channel.impl[Any, ChannelList,
                             ChannelList, T, C, P]


                         def behaviorist[R, Ch: ru.TypeTag](wrapped: Boolean)
                           : (R ⇒ Unit) = new Behaviorist[R, Ch](wrapped)


                         // ...
                    }




söndag 10 februari 13
Sample Type Calculation
                    final def missingChannels(u: Universe)(
                        channels: u.Type, required: List[u.Type]): List[u.Type] = {
                        import u._
                        // making the top-level method recursive blows up the compiler
                        def rec(ch: Type, req: List[Type]): List[Type] = {
                            ch match {
                                case TypeRef(_, _, TypeRef(_, _, in :: _) :: tail :: Nil) ⇒
                                  rec(tail, req filterNot (_ <:< in))
                                case last ⇒ req filterNot (_ <:< last)
                            }
                        }
                        rec(channels, required)
                   }




söndag 10 februari 13
How to Return a Type
                        def impl[..., ReplyChannels <: ChannelList, ...]
                            (c: Context): c.Expr[(Nothing ⇒ Unit)] = {
                         // calculate “channels: u.Type” and then:
                         implicit val ttReplyChannels =
                           c.TypeTag[ReplyChannels](channels)


                         reify {
                             ...[(..., ...[ReplyChannels]) ⇒ ..., ...]...
                         }
                    }



                             “reify” picks up TypeTags and uses their .tpe

söndag 10 februari 13
Sharing Code with Runtime

                        final def x(u: Universe)(list: u.Type, msg: u.Type)
                            : List[u.Type] = {
                          val imp = u.mkImporter(ru)
                         val tpeReplyChannels =
                           imp.importType(ru.typeOf[ReplyChannels[_]])
                         val tpeTNil = imp.importType(ru.typeOf[TNil])
                         // ...
                    }




                            otherwise there will be weird exceptions

söndag 10 februari 13
How to test it?
                        def mkToolbox(compileOptions: String = "")
                          : ToolBox[_ <: scala.reflect.api.Universe] = {
                             val m = scala.reflect.runtime.currentMirror
                             m.mkToolBox(options = compileOptions)
                         }


                    def eval(code: String, compileOptions: String =
                             "-cp akka-actor/target/classes:akka-channels/target/classes")
                         : Any = {
                             val tb = mkToolbox(compileOptions)
                             tb.eval(tb.parse(code))
                         }




söndag 10 februari 13
How to test it?
                    intercept[ToolBoxError] {
                        eval("""
                             import akka.channels._
                             import ChannelSpec._
                             implicit val c = new ChannelRef[TNil](null)
                             new ChannelRef[(A, C) :+: TNil](null) <-!- B
                           """)
                    }.message must include(
                      "target ChannelRef does not support messages of " +
                        "types akka.channels.ChannelSpec.B.type")




söndag 10 februari 13
get it and learn more
                           http://akka.io
                        http://letitcrash.com
                        http://typesafe.com

söndag 10 februari 13
E0F
söndag 10 februari 13
1 of 26

Recommended

F#3.0 by
F#3.0 F#3.0
F#3.0 Rodrigo Vidal
456 views31 slides
Java For Automation by
Java   For AutomationJava   For Automation
Java For AutomationAbhijeet Dubey
89 views44 slides
Clojure Interoperability by
Clojure InteroperabilityClojure Interoperability
Clojure Interoperabilityrik0
877 views70 slides
+2 CS class and objects by
+2 CS class and objects+2 CS class and objects
+2 CS class and objectskhaliledapal
982 views26 slides
Chapter 8 Inheritance by
Chapter 8 InheritanceChapter 8 Inheritance
Chapter 8 InheritanceOUM SAOKOSAL
2.3K views39 slides
Moose by
MooseMoose
Moosendronen
2.1K views15 slides

More Related Content

Similar to Akka typed-channels

Lecture38 by
Lecture38Lecture38
Lecture38David Evans
567 views39 slides
Unit Testing Presentation by
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentationnicobn
629 views29 slides
Clojure 1.1 And Beyond by
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And BeyondMike Fogus
1.1K views24 slides
From Java to Parellel Clojure - Clojure South 2019 by
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019Leonardo Borges
293 views53 slides
C# programming by
C# programming C# programming
C# programming umesh patil
434 views19 slides
Testing for share by
Testing for share Testing for share
Testing for share Rajeev Mehta
333 views20 slides

Similar to Akka typed-channels(20)

Unit Testing Presentation by nicobn
Unit Testing PresentationUnit Testing Presentation
Unit Testing Presentation
nicobn629 views
Clojure 1.1 And Beyond by Mike Fogus
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
Mike Fogus1.1K views
From Java to Parellel Clojure - Clojure South 2019 by Leonardo Borges
From Java to Parellel Clojure - Clojure South 2019From Java to Parellel Clojure - Clojure South 2019
From Java to Parellel Clojure - Clojure South 2019
Leonardo Borges293 views
C# programming by umesh patil
C# programming C# programming
C# programming
umesh patil434 views
Testing for share by Rajeev Mehta
Testing for share Testing for share
Testing for share
Rajeev Mehta333 views
Property based Testing - generative data & executable domain rules by Debasish Ghosh
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
Debasish Ghosh3.6K views
Clojure concurrency by Alex Navis
Clojure concurrencyClojure concurrency
Clojure concurrency
Alex Navis1.4K views
Asynchronous Orchestration DSL on squbs by Anil Gursel
Asynchronous Orchestration DSL on squbsAsynchronous Orchestration DSL on squbs
Asynchronous Orchestration DSL on squbs
Anil Gursel525 views
Fun with errors? - Clojure Finland Meetup 26.3.2019 Tampere by Metosin Oy
Fun with errors? - Clojure Finland Meetup 26.3.2019 TampereFun with errors? - Clojure Finland Meetup 26.3.2019 Tampere
Fun with errors? - Clojure Finland Meetup 26.3.2019 Tampere
Metosin Oy1.4K views
Clojure Intro by thnetos
Clojure IntroClojure Intro
Clojure Intro
thnetos10.5K views
Functional programming with Ruby - can make you look smart by Chen Fisher
Functional programming with Ruby - can make you look smartFunctional programming with Ruby - can make you look smart
Functional programming with Ruby - can make you look smart
Chen Fisher1K views
What can be done with Java, but should better be done with Erlang (@pavlobaron) by Pavlo Baron
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
Pavlo Baron2.2K views
Introduction to clojure by Abbas Raza
Introduction to clojureIntroduction to clojure
Introduction to clojure
Abbas Raza1.4K views
Torquebox OSCON Java 2011 by tobiascrawley
Torquebox OSCON Java 2011Torquebox OSCON Java 2011
Torquebox OSCON Java 2011
tobiascrawley562 views
ClojureScript loves React, DomCode May 26 2015 by Michiel Borkent
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
Michiel Borkent411 views

More from Roland Kuhn

Taming Distribution: Formal Protocols for Akka Typed by
Taming Distribution: Formal Protocols for Akka TypedTaming Distribution: Formal Protocols for Akka Typed
Taming Distribution: Formal Protocols for Akka TypedRoland Kuhn
1.2K views36 slides
Distributed systems vs compositionality by
Distributed systems vs compositionalityDistributed systems vs compositionality
Distributed systems vs compositionalityRoland Kuhn
2.9K views37 slides
Reactive Design Patterns — J on the Beach by
Reactive Design Patterns — J on the BeachReactive Design Patterns — J on the Beach
Reactive Design Patterns — J on the BeachRoland Kuhn
3.3K views36 slides
The Newest in Session Types by
The Newest in Session TypesThe Newest in Session Types
The Newest in Session TypesRoland Kuhn
3.9K views24 slides
Akka Typed — between Session Types and the Actor Model by
Akka Typed — between Session Types and the Actor ModelAkka Typed — between Session Types and the Actor Model
Akka Typed — between Session Types and the Actor ModelRoland Kuhn
6.7K views31 slides
Project Gålbma – Actors vs Types by
Project Gålbma – Actors vs TypesProject Gålbma – Actors vs Types
Project Gålbma – Actors vs TypesRoland Kuhn
2.7K views49 slides

More from Roland Kuhn(11)

Taming Distribution: Formal Protocols for Akka Typed by Roland Kuhn
Taming Distribution: Formal Protocols for Akka TypedTaming Distribution: Formal Protocols for Akka Typed
Taming Distribution: Formal Protocols for Akka Typed
Roland Kuhn1.2K views
Distributed systems vs compositionality by Roland Kuhn
Distributed systems vs compositionalityDistributed systems vs compositionality
Distributed systems vs compositionality
Roland Kuhn2.9K views
Reactive Design Patterns — J on the Beach by Roland Kuhn
Reactive Design Patterns — J on the BeachReactive Design Patterns — J on the Beach
Reactive Design Patterns — J on the Beach
Roland Kuhn3.3K views
The Newest in Session Types by Roland Kuhn
The Newest in Session TypesThe Newest in Session Types
The Newest in Session Types
Roland Kuhn3.9K views
Akka Typed — between Session Types and the Actor Model by Roland Kuhn
Akka Typed — between Session Types and the Actor ModelAkka Typed — between Session Types and the Actor Model
Akka Typed — between Session Types and the Actor Model
Roland Kuhn6.7K views
Project Gålbma – Actors vs Types by Roland Kuhn
Project Gålbma – Actors vs TypesProject Gålbma – Actors vs Types
Project Gålbma – Actors vs Types
Roland Kuhn2.7K views
Akka Streams and HTTP by Roland Kuhn
Akka Streams and HTTPAkka Streams and HTTP
Akka Streams and HTTP
Roland Kuhn41.6K views
Akka and AngularJS – Reactive Applications in Practice by Roland Kuhn
Akka and AngularJS – Reactive Applications in PracticeAkka and AngularJS – Reactive Applications in Practice
Akka and AngularJS – Reactive Applications in Practice
Roland Kuhn17.3K views
Go Reactive: Blueprint for Future Applications by Roland Kuhn
Go Reactive: Blueprint for Future ApplicationsGo Reactive: Blueprint for Future Applications
Go Reactive: Blueprint for Future Applications
Roland Kuhn3.1K views
Reactive Streams: Handling Data-Flow the Reactive Way by Roland Kuhn
Reactive Streams: Handling Data-Flow the Reactive WayReactive Streams: Handling Data-Flow the Reactive Way
Reactive Streams: Handling Data-Flow the Reactive Way
Roland Kuhn34.8K views
Akka cluster overview at 010dev by Roland Kuhn
Akka cluster overview at 010devAkka cluster overview at 010dev
Akka cluster overview at 010dev
Roland Kuhn6.8K views

Recently uploaded

AI Tools for Business and Startups by
AI Tools for Business and StartupsAI Tools for Business and Startups
AI Tools for Business and StartupsSvetlin Nakov
107 views39 slides
Class 10 English lesson plans by
Class 10 English  lesson plansClass 10 English  lesson plans
Class 10 English lesson plansTARIQ KHAN
288 views53 slides
Narration lesson plan.docx by
Narration lesson plan.docxNarration lesson plan.docx
Narration lesson plan.docxTARIQ KHAN
112 views11 slides
Google solution challenge..pptx by
Google solution challenge..pptxGoogle solution challenge..pptx
Google solution challenge..pptxChitreshGyanani1
131 views18 slides
Ch. 7 Political Participation and Elections.pptx by
Ch. 7 Political Participation and Elections.pptxCh. 7 Political Participation and Elections.pptx
Ch. 7 Political Participation and Elections.pptxRommel Regala
97 views11 slides
ICS3211_lecture 08_2023.pdf by
ICS3211_lecture 08_2023.pdfICS3211_lecture 08_2023.pdf
ICS3211_lecture 08_2023.pdfVanessa Camilleri
149 views30 slides

Recently uploaded(20)

AI Tools for Business and Startups by Svetlin Nakov
AI Tools for Business and StartupsAI Tools for Business and Startups
AI Tools for Business and Startups
Svetlin Nakov107 views
Class 10 English lesson plans by TARIQ KHAN
Class 10 English  lesson plansClass 10 English  lesson plans
Class 10 English lesson plans
TARIQ KHAN288 views
Narration lesson plan.docx by TARIQ KHAN
Narration lesson plan.docxNarration lesson plan.docx
Narration lesson plan.docx
TARIQ KHAN112 views
Ch. 7 Political Participation and Elections.pptx by Rommel Regala
Ch. 7 Political Participation and Elections.pptxCh. 7 Political Participation and Elections.pptx
Ch. 7 Political Participation and Elections.pptx
Rommel Regala97 views
ISO/IEC 27001 and ISO/IEC 27005: Managing AI Risks Effectively by PECB
ISO/IEC 27001 and ISO/IEC 27005: Managing AI Risks EffectivelyISO/IEC 27001 and ISO/IEC 27005: Managing AI Risks Effectively
ISO/IEC 27001 and ISO/IEC 27005: Managing AI Risks Effectively
PECB 585 views
Psychology KS4 by WestHatch
Psychology KS4Psychology KS4
Psychology KS4
WestHatch84 views
Are we onboard yet University of Sussex.pptx by Jisc
Are we onboard yet University of Sussex.pptxAre we onboard yet University of Sussex.pptx
Are we onboard yet University of Sussex.pptx
Jisc96 views
Drama KS5 Breakdown by WestHatch
Drama KS5 BreakdownDrama KS5 Breakdown
Drama KS5 Breakdown
WestHatch79 views
Create a Structure in VBNet.pptx by Breach_P
Create a Structure in VBNet.pptxCreate a Structure in VBNet.pptx
Create a Structure in VBNet.pptx
Breach_P75 views
UWP OA Week Presentation (1).pptx by Jisc
UWP OA Week Presentation (1).pptxUWP OA Week Presentation (1).pptx
UWP OA Week Presentation (1).pptx
Jisc88 views
Structure and Functions of Cell.pdf by Nithya Murugan
Structure and Functions of Cell.pdfStructure and Functions of Cell.pdf
Structure and Functions of Cell.pdf
Nithya Murugan545 views
PLASMA PROTEIN (2).pptx by MEGHANA C
PLASMA PROTEIN (2).pptxPLASMA PROTEIN (2).pptx
PLASMA PROTEIN (2).pptx
MEGHANA C68 views

Akka typed-channels

  • 1. Typed Channels and Macros Dr. Roland Kuhn @rolandkuhn söndag 10 februari 13
  • 2. The Problem someActor ! CommandOne söndag 10 februari 13
  • 3. The Problem trait Command case class CommandOne(param: String) extends Command someActor ! CommandOne söndag 10 februari 13
  • 4. The Vision someActor <-!- CommandOne(”msg”) because the other does not compile söndag 10 februari 13
  • 5. But How? • ActorRef must know about message types – Actor type must be parameterized • Message type is verified against that söndag 10 februari 13
  • 6. And the replies? val f: Future[Response] = someActor <-?- CommandOne(”hello”) because the compiler knows söndag 10 februari 13
  • 7. And How This? • ActorRef must know reply types – Actor must be parameterized with them • Reply types are extracted at call site söndag 10 februari 13
  • 8. No Type Pollution • Generic Filter/Transform Actors – accept management commands – pass on generic other type • Using just one type is not enough! • Need to use type unions and allow multiple possible reply types for one input söndag 10 februari 13
  • 9. Actors Do Compose msg -?-> firstActor -?-> secondActor -!-> client msg -?-> someService -*-> (_ map httpOk) -!-> client Process wiring from the outside söndag 10 februari 13
  • 10. The Result: söndag 10 februari 13
  • 11. Type-Safe Composability of Actor Systems söndag 10 februari 13
  • 12. Relation to π-calculus • Actors are composite processes • Actor types are structural, not nominal • wiring A͡B can be done situationally http://doc.akka.io/ see Typed Channels söndag 10 februari 13
  • 13. That was the Eloi world Now we’re going to visit the Morlocks söndag 10 februari 13
  • 14. The Implementation • Tagged type union with :+:[(In, Out), ChannelList] <: ChannelList • Value class ChannelRef[…](val a: ActorRef) • Actor mixin Channels[…] • WrappedMessage[…, LUB](val m: LUB) • ops desugar to tell/ask after type check söndag 10 februari 13
  • 15. How to Declare it? class OpinionatedEcho extends Actor with Channels[TNil, (String, String) :+: TNil] { channel[String] { (str, sender) ⇒ sender <-!- str } // or channel[String] { case (”hello”, sender) ⇒ sender <-!- ”world” case (x, sender) ⇒ sender <-!- s”dunno: $x” } } “sender” will accept only String messages söndag 10 februari 13
  • 16. First Problem: Lambdas • Type-checker transforms lambda before the macro call – pattern matches or PartialFunction literals generate checks depending on static type info • Behavior is not an argument to “channels” • macro only emits object with right “apply” söndag 10 februari 13
  • 17. First Problem: Lambdas private class Behaviorist[-R, Ch: ru.TypeTag]( wrapped: Boolean) extends (R ⇒ Unit) { // ... def apply(recv: R): Unit = { val tt = ru.typeTag[Ch] behavior ++= ( for (t ← inputChannels(ru)(tt.tpe)) yield tt.mirror.runtimeClass(t.widen) -> ff(recv)) } } calling channels[_] registers the behavior söndag 10 februari 13
  • 18. The Gory Details def impl[LUB, ReplyChannels <: ChannelList, MsgTChan <: ChannelList, MsgT: c.WeakTypeTag, MyCh <: ChannelList: c.WeakTypeTag, ParentCh <: ChannelList: c.WeakTypeTag]( c: Context { type PrefixType = Channels[ParentCh, MyCh] }): c.Expr[(Nothing ⇒ Unit)] = { // some type calculations happen here val prepTree = reify(...) reify { prepTree.splice c.prefix.splice.behaviorist[ (MsgT, ChannelRef[ReplyChannels]) ⇒ Unit, MsgT]( bool(c, false).splice)(universe.typeTag[MsgT]) } } söndag 10 februari 13
  • 19. The Gory Details trait Channels[P <: ChannelList, C <: ChannelList] { this: Actor ⇒ def channel[T]: (Nothing ⇒ Unit) = macro macros.Channel.impl[Any, ChannelList, ChannelList, T, C, P] def behaviorist[R, Ch: ru.TypeTag](wrapped: Boolean) : (R ⇒ Unit) = new Behaviorist[R, Ch](wrapped) // ... } söndag 10 februari 13
  • 20. Sample Type Calculation final def missingChannels(u: Universe)( channels: u.Type, required: List[u.Type]): List[u.Type] = { import u._ // making the top-level method recursive blows up the compiler def rec(ch: Type, req: List[Type]): List[Type] = { ch match { case TypeRef(_, _, TypeRef(_, _, in :: _) :: tail :: Nil) ⇒ rec(tail, req filterNot (_ <:< in)) case last ⇒ req filterNot (_ <:< last) } } rec(channels, required) } söndag 10 februari 13
  • 21. How to Return a Type def impl[..., ReplyChannels <: ChannelList, ...] (c: Context): c.Expr[(Nothing ⇒ Unit)] = { // calculate “channels: u.Type” and then: implicit val ttReplyChannels = c.TypeTag[ReplyChannels](channels) reify { ...[(..., ...[ReplyChannels]) ⇒ ..., ...]... } } “reify” picks up TypeTags and uses their .tpe söndag 10 februari 13
  • 22. Sharing Code with Runtime final def x(u: Universe)(list: u.Type, msg: u.Type) : List[u.Type] = { val imp = u.mkImporter(ru) val tpeReplyChannels = imp.importType(ru.typeOf[ReplyChannels[_]]) val tpeTNil = imp.importType(ru.typeOf[TNil]) // ... } otherwise there will be weird exceptions söndag 10 februari 13
  • 23. How to test it? def mkToolbox(compileOptions: String = "") : ToolBox[_ <: scala.reflect.api.Universe] = { val m = scala.reflect.runtime.currentMirror m.mkToolBox(options = compileOptions) } def eval(code: String, compileOptions: String = "-cp akka-actor/target/classes:akka-channels/target/classes") : Any = { val tb = mkToolbox(compileOptions) tb.eval(tb.parse(code)) } söndag 10 februari 13
  • 24. How to test it? intercept[ToolBoxError] { eval(""" import akka.channels._ import ChannelSpec._ implicit val c = new ChannelRef[TNil](null) new ChannelRef[(A, C) :+: TNil](null) <-!- B """) }.message must include( "target ChannelRef does not support messages of " + "types akka.channels.ChannelSpec.B.type") söndag 10 februari 13
  • 25. get it and learn more http://akka.io http://letitcrash.com http://typesafe.com söndag 10 februari 13