Upgrade to Pro — share decks privately, control downloads, hide ads and more …

COP@ECOOP 2015 - ConGolo

COP@ECOOP 2015 - ConGolo

Towards a Decoupled Context-Oriented Programming Language
for the Internet of Things

Frédéric Le Mouël

July 05, 2015
Tweet

More Decks by Frédéric Le Mouël

Other Decks in Research

Transcript

  1. Towards a Decoupled Context- Oriented Programming Language for the Internet

    of Things Baptiste Maingret*, Frédéric Le Mouël*, Julien Ponge*, Nicolas Stouls*, Jian Cao#, Yannick Loiseau% * University of Lyon, INSA Lyon, INRIA CITI Lab, France # Shanghai Jiao Tong University, China % Blaise Pascal University, France COP @ ECOOP - July 5 2015
  2. • Java 7 - July 2011 • JVM support for

    dynamic languages • JSR 292, new invokedynamic bytecode • core method dispatching Why a COP language ?
  3. • Julien Ponge & Frédéric Le Mouël • Nothing to

    do in July 2011 ? • Summer Hackathons Why a COP language ?
  4. • Summer Hackathons Why a COP language ? Jooflux Java

    agent for dynamic AOP Golo A lightweight dynamic language for the JVM [Jooflux] J. Ponge and F. Le Mouël. JooFlux: Hijacking Java 7 InvokeDynamic To Support Live Code Modifications. Research Report INRIA CITI Lab, INSA Lyon, 2012 https://github.com/dynamid/jooflux [Golo]  J.  Ponge,  F.  Le  Mouël,  and  N.  Stouls.  Golo,  a  dynamic,  light  and  efficient   language   for   post-­‐invokedynamic   JVM.   In   Proceedings   of   the   11th   International   Conference  on  Principles  and  Practice  of  Programming  in  Java  (PPPJ'2013),  pp.  153– 158,  Stuttgart,  Germany,  September  2013.   http://golo-­‐lang.org  
  5. « comme une poule devant un couteau » « a

    rabbit in the headlights » Why a COP language ? Usage ?
  6. Dynamic Light Efficient IoT Gateway/Box Why a COP language ?

    Con Hardened Truffle Easy to dev Easy to hack Rapid POC Dev
  7. • Yet another JVM dynamic language - A simple one

    • 100% Java compliant • Active academic and industrial community • Eclipse Incubating Technology Project https://projects.eclipse.org/projects/technology.golo/ June 2015 !
  8. module  hello.World   function  main  =  |args|  {   let

     nochange  =  4   var  i  =  1   i  =  i  +  1      println("Hello  world!"  +  nochange  +  i)   } module function constant (immutable) variable (mutable)
  9. module  mainEntryPoint   function  main  =  |args|  {    

     println("-­‐>  "  +  args:  get(0):  toString())   } function invocation
  10. let  adder  =  |a,  b|  {      return  a

     +  b   }   println(adder:  invokeWithArguments(1,  2))   let  addToTen  =  adder:  bindTo(10)   println(addToTen:  invokeWithArguments(2))   let  adderShort  =  |a,  b|  -­‐>  a  +  b   println(addShort(1,  2))   closure compact closure
  11. let  f  =  (|x|  -­‐>  x  +  1):  andThen(|x|  -­‐>

     x  -­‐  10):   andThen(|x|  -­‐>  x  *  100)   #  -­‐500   println(f(4)) closure composition
  12. let  f  =  |x|  -­‐>  |y|  -­‐>  |z|  -­‐>  x

     +  y  +  z   let  f1  =  f(1)   let  f2  =  f1(2)   let  f3  =  f2(3)   #  Prints  '6'   println(f3())   #  Prints  '6'   println(f(1)(2)(3)()) closure intermediate references
  13. module  foo   augment  java.lang.String  {      function  wrap

     =     |this,  left,  right|  -­‐>  left  +  this  +  right   }   function  wrapped  =  -­‐>  "abc":  wrap("(",  ")") augmentation
  14. let  person  =  DynamicObject():  name("MrBean"):   email("[email protected]")   #  prints

     "Mr  Bean"   println(person:  name())   #  prints  "Mr  Beanz"   person:  name("Mr  Beanz")   println(person:  name()) dynamic object
  15. local  function  mrbean  =  -­‐>  DynamicObject():      name("Mr  Bean"):

         email("[email protected]"):      define("toString",  |this|  -­‐>     this:  name()  +  "  <"  +  this:  email()  +  ">")   function  main  =  |args|  {      let  bean  =  mrbean()      println(bean:  toString())      bean:  define("toString",  |this|  -­‐>  this:  name())      println(bean:  toString())   } dynamic object dynamic function definition
  16. • Closures to single-method interface • Reusable/Named augmentations • Struct

    augmentations • Adapters / Decorators • Anonymous modules • Workers / Concurrency • Predefined functions (preconditions…) • Templates / JSON and much more … dynamic - YES but how to activate / react ?
  17. State of the Art: Jcop example public  class  Hero  {

        public  void  move(Direction  dir)  {…}   public  Position  getPos()  {...}     layer  ConfusedHeroLayer  {  //layer  extension     private  Position  getPos()  {…}   public  void  move(Direction  dir)  {   proceed(dir);   }     private  Direction  getNewDir(Direction  original)   {if  (original.isWest()  then  …}   }     }   Context inside the main code Decision making inside the main code
  18. State of the Art: ServalCJ example context  GPSon   active(int

     s)  :after  call(void   Nav.onStatusChanged(*))  &&  args(s)
 &&  if(GPS.AVAILABLE==s)     until(int  s)  :after  call(void   Nav.onStatusChanged(*))  &&  args(s)     &&  if(GPS.AVAILABLE!=s);     Context outside the main code Decision making inside the context
  19. contributions • Abstract and separate • the context tracking •

    the decision-making process • Externalize these interactions • API-defined • Event-based handling Con
  20. language enhancements Con module  MMORPG   let  contexts  =  [ConfusedHero(),

     Weather()]     function  Hero  =  ||  {  
 return  DynamicObject():  
 contexts([ConfusedHero,  Weather])
 external classes Context API Context module scope (for event-sensitivity) function contextual-sensitivity
  21. language enhancements Con module  MMORPG   let  contexts  =  [ConfusedHero(),

     Weather()]     function  Hero  =  ||  {  
 return  DynamicObject():  
 contexts([ConfusedHero,  Weather]):  
 #  base  functions  
 define("move",  |this,  dir|  -­‐>  ...):  
 define("getPos";  |this|  -­‐>  ...):   Context classic functions
  22. language enhancements Con module  MMORPG   let  contexts  =  [ConfusedHero(),

     Weather()]     function  Hero  =  ||  {  
 return  DynamicObject():  
 contexts([ConfusedHero,  Weather]):  
 #  base  function  
 define("move",  |this,  dir|  -­‐>  ...):  
 define("getPos",  |this|  -­‐>  ...):  
 #  layered  function,  invoked  before  base  method  
 define("getPos",  |this,  dir|@(ConfusedHero=TRUE)+  -­‐>…):   #  layered  function,  invoked  after  base  method   define("move",  |this,  dir|+@(ConfusedHero=TRUE)  -­‐>  ...)   layered functions without ‘layer’ keyword Context no pseudo-contextual layer naming
  23. language enhancements Con module  MMORPG   let  contexts  =  [ConfusedHero(),

     Weather()]     function  Hero  =  ||  {  
 return  DynamicObject():  
 contexts([ConfusedHero,  Weather]):  
 #  base  function  
 define("move",  |this,  dir|  -­‐>  ...):  
 define("getPos",  |this|  -­‐>  ...):  
 #  layered  function,  invoked  before  base  method  
 define("getPos",  |this,  dir|@(ConfusedHero=TRUE)+  -­‐>…):   #  layered  function,  invoked  after  base  method   define("move",  |this,  dir|+@(ConfusedHero=TRUE)  -­‐>  ...)   @(ContextPredicate)+   invoke before Context
  24. language enhancements Con module  MMORPG   let  contexts  =  [ConfusedHero(),

     Weather()]     function  Hero  =  ||  {  
 return  DynamicObject():  
 contexts([ConfusedHero,  Weather]):  
 #  base  function  
 define("move",  |this,  dir|  -­‐>  ...):  
 define("getPos",  |this|  -­‐>  ...):  
 #  layered  function,  invoked  before  base  method  
 define("getPos",  |this,  dir|@(ConfusedHero=TRUE)+  -­‐>…):   #  layered  function,  invoked  after  base  method   define("move",  |this,  dir|+@(ConfusedHero=TRUE)  -­‐>  ...)   +@(ContextPredicate)   invoke after Context
  25. language enhancements Con module  MMORPG   let  contexts  =  [ConfusedHero(),

     Weather()]     function  Hero  =  ||  {  
 return  DynamicObject():  
 contexts([ConfusedHero,  Weather]):  
 #  base  function  
 define("move",  |this,  dir|  -­‐>  ...):  
 ...   define("move",  |this,  dir|@(ConfusedHero=TRUE)  ={  
 proceed(dir)  
 ...  
 }     }   possibility to call the base function Context
  26. language enhancements Con module  MMORPG   #  no  contexts  ?

     let  contexts  =  []   Context default behavior no event-sensitivity one or zero context declaration
  27. language enhancements Con module  MMORPG   let  misterPresident  =  my.app.myDecisionMaker()

        function  Hero  =  |decisionMaker|  {   return  DynamicObject():  
 decisionmaker(decisionMaker)     }       let  batman  =  Hero(misterPresident)   Decision Making DecisionMaker API module scope decision-maker function referee several possible decision-makers
  28. language enhancements Con module  MMORPG   #  no  decision-­‐maker  ?

     let  god  =  DefaultDecisionMaker(){}   Decision Making default behavior global decision-maker singleton pattern
  29. language enhancements Con module  MMORPG   #  no  decision-­‐maker  ?

     let  god  =  DefaultDecisionMaker(){}     let  misterPresident  =  my.app.myDecisionMaker()     misterPresident:  global(true)  #defining  misterPresident  as   god   let  batman  =  Hero()    #contextual  object
 batman:  move()  #handle  by  misterPresident
 Decision Making defining global decision-maker
  30. architecture Con (...)   bipush  40   invokedynamic  (...)  

    "java/lang/Integer.valueOf":(I)Ljava/lang/Integer;   invokestatic  Bootstrap.dynvokeStatic:(...)L/java/ lang/invoke/CallSite; Runtime bytecode Runtime Bootstrap Management Target Class valueOf(){...}   otherMethod(){...}   Callsite Management Callsite invokedynamic Method invocation
  31. architecture Con (...)   invokedynamic  (...)   Runtime bytecode Runtime

    Bootstrap Management Target Class foo||@Context1{…}   foo||@Context2{…}   foo||@Context3{…} Callsite Management event-based handling Method invocation Decision- Maker Context Manager Method invocation Publish/Subscribe Events Function Invocation Event Context Event
  32. architecture Con (...)   invokedynamic  (...)   Runtime bytecode Runtime

    Bootstrap Management Target Class foo||@Context1{…}   foo||@Context2{…}   foo||@Context3{…} Callsite Management event-based handling Method invocation Decision- Maker Context Manager Method invocation Publish/Subscribe Events Function Invocation Event Context Event Different IoT devices
  33. architecture Con Target Class foo||@Context1{…}   foo||@Context2{…}   foo||@Context3{…} Decision-

    Maker Context Manager Method invocation Context Event event-based handling Decision- Maker Target Class bar||@Context1{…}   bar||@Context2{…}   bar||@Context3{…} Publish/Subscribe Events Function Invocation Event Decision- Maker Global Decision- Maker
  34. architecture Con Target Class foo||@Context1{…}   foo||@Context2{…}   foo||@Context3{…} Decision-

    Maker Context Manager Method invocation Function Invocation Event Context Event event-based handling let  env  =   MessagingEnvironment.builder():   withFixedThreadPool()   let  topic  =  env:  topic()   topic:  register(|message|  -­‐>   println(">>>  "  +  message))   topic:  send("[call?]")   Thread.sleep(1000_L)   topic:  send("Die  !")
  35. module  congolo.Greenhouse   …   import  gololang.concurrent.messaging.MessagingEnvironment   import  …congolo.decisionmaker.DefaultDecisionMaker

      function  GreenHouse  =  {      return  DynamicObject():      temperature(0):      define("toString",  |this|  -­‐>  "Greenhouse  #"  +  this:  id()):      define("regulate",  |this|  -­‐>  println(this  +  "  regulated"))   }   function  regulate  =  |greenhouse|@(TemperatureTooHot){      println("Cooling  "  +  greenhouse)   }   function  regulate  =  |greenhouse|@(TemperatureTooCold){      println("Warming  "  +  greenhouse)   } IoT use-case Con Smart farm main Green House definion COP functions
  36. IoT use-case Con module  congolo.Greenhouse   …   function  main

     =  |args|  {   …      let  context  =  context.TemperatureContext()      let  cm  =  ContextManager.INSTANCE()      cm:  register("Greenhouse",  context)          let  dm  =  decisionmaker.GreenDecisionMaker()      DecisionMakerManager.setDecisionMaker(dm)   …   } Smart farm main
  37. IoT use-case Con module  congolo.Greenhouse   …   function  main

     =  |args|  {   …      var  greenHouses  =  set[]      for  (var  i  =  0,  i  <  greenHousePoolSize,  i  =  i  +  1){          greenHouses:  add(GreenHouse())      }      for  (var  i  =  0,  i  <  STEPS,  i  =  i  +  1)  {          Thread.sleep(DELAY)          context:  setValue(randomGen:  nextInt(40))          foreach  greenHouse  in  greenHouses  {              regulate(greenHouse)          }      }   Smart farm main
  38. IoT use-case Con public  class  GreenDecisionMaker  extends   DefaultDecisionMaker  {

      @Override    public  void  decide(Event  event)  {   String  activatedContextName  =  null;   Object  source  =  event.getSource();   Context  context  =   ContextManager.INSTANCE.getContext(((Class)source)   .getSimpleName());     Object  contextValue  =  ((ConcreteValue)   context).getValue();         Smart farm decision-maker
  39. IoT use-case Con public  class  GreenDecisionMaker  extends   DefaultDecisionMaker  {

      @Override    public  void  decide(Event  event)  {   …        if  ((Integer)  contextValue  >  10)  {                  activatedContextName  =  "TemperatureTooHot";              }  else  {                  activatedContextName  =  "TemperatureTooCold";              } Smart farm decision-maker
  40. IoT use-case Con …   MethodHandle  handle  =  findHandle(  

           (Class)  source,        ((FunctionInvocationEvent)  event).getMethod()+     ContextualFunctionProxy.CONTEXTSUFFIX  +   activatedContextName,          ((FunctionInvocationEvent)  event).getParameters());          ((FunctionInvocationEvent)  event).setHandle(handle);          this.proxyTopic.send(event);   } Smart farm decision-maker Hard ! To simplify Event send !
  41. performance Con 1 100 10000 Single - Event Single -

    Callsite Layered(10) - Event yered(10) - Callsite 2,7 1,9 55 29 3 840 3 998 5 939 6 135 Golo Congolo Number of calls / ms micro-benchmarks
  42. conclusion Con • extensible by separation of concerns at runtime

    • performance to improve • performance relevant for IoT - comparable to Subjective-C - same order of magnitude x1000 • messaging performance ok
  43. discussions Con module  MMORPG   let  contexts  =  [ConfusedHero(),  Weather()]

        function  Hero  =  ||  {  
 return  DynamicObject():  
 contexts([ConfusedHero,  Weather]):  
 #  base  function  
 define("move",  |this,  dir|  -­‐>  ...):  
 ...   define("move",  |this,  dir|@(ConfusedHero=TRUE)  ={  
 proceed(dir)  
 ...  
 }     }   complex context matching ? ontology? Context
  44. discussions Con (...)   invokedynamic  (...)   Runtime bytecode Runtime

    Bootstrap Management Target Class foo||@Context1{…}   foo||@Context2{…}   foo||@Context3{…} Callsite Management event-based handling Method invocation Decision- Maker Context Manager Method invocation Publish/Subscribe Events Function Invocation Event Context Event caching ? prefetching ? profiling ?
  45. discussions Con Target Class foo||@Context1{…}   foo||@Context2{…}   foo||@Context3{…} Decision-

    Maker Context Manager Method invocation event-based handling Decision- Maker Target Class bar||@Context1{…}   bar||@Context2{…}   bar||@Context3{…} Decision- Maker Global Decision- Maker coordination ?