SlideShare une entreprise Scribd logo
1  sur  79
Télécharger pour lire hors ligne
Procedure Typing for Scala




                               Procedure Typing for Scala

                             Alexander Kuklev∗ , Alexander Temerev‡

                       * Institute of Theoretical Physics, University of Göttingen

                             ‡ Founder and CEO at Miriamlaurel Sàrl, Geneva


                                           April 10, 2012
Procedure Typing for Scala




     Functions and procedures



      In programming we have:
          – pure functions;
          – functions with side effects (AKA procedures).
Procedure Typing for Scala




     Functions and procedures



      In programming we have:
          – pure functions;
          – functions with side effects (AKA procedures).


      Scala does not differentiate between them:
          – both have types A => B .
Procedure Typing for Scala




                             But it should!
Procedure Typing for Scala




                                 But it should!
      Static side effect tracking enables
          – implicit parallelisability;
Procedure Typing for Scala




                                 But it should!
      Static side effect tracking enables
          – implicit parallelisability;
          – compile-time detection of a whole new class of problems:
             (resource acquisition and releasing problems, race conditions,
             deadlocks, etc.).
Procedure Typing for Scala




      Short list of applicable methodologies:
      Kleisli Arrows of Outrageous Fortune (2011, C. McBride)
      Capabilities for Uniqueness and Borrowing (2010, P. Haller, M. Odersky)
      Static Detection of Race Conditions [..] (2010, M. Christakis, K. Sagonas)
      Static Deadlock Detection [..] (2009, F. de Boer, I. Grabe,M. Steffen)
      Complete Behavioural Testing of Object-Oriented Systems using
      CCS-Augmented X-Machines (2002, M. Stannett, A. J. H. Simons)
      An integration testing method that is proved to find all faults
                                                (1997, F. Ipate, M. Holcombe)
Procedure Typing for Scala
  Specifying procedure categories




                            We propose a new syntax
      where a function definition may include a category it belongs to:

                                    A =>[Pure] B – pure functions;
                                    A =>[Proc] B – procedures.
Procedure Typing for Scala
  Specifying procedure categories
    There’s a lot more than Pure and Proc




      There is a whole lattice of categories between Pure and Proc :

             Logged: procedures with no side effects besides logging;
        Throws[E]: no side effects besides throwing exceptions of type E ;
        Reads(file): no side effects besides reading the file ;
                   etc.
Procedure Typing for Scala
  Specifying procedure categories
    Extensible approach




      An effect system should be extensible.
      ⇒ We must provide a way to define procedure categories.

      Procedure categories are binary types like Function[_,_] or
       Logged[_,_] 1




          1
           Definition of parameterized categories, e.g. Throws[E] or Reads(resource),
      is also possible with the help of type lambdas and/or type providers.
Procedure Typing for Scala
  Specifying procedure categories
    Extensible approach




      An effect system should be extensible.
      ⇒ We must provide a way to define procedure categories.

      Procedure categories are binary types like Function[_,_] or
       Logged[_,_] 1 equipped with some additional structure using an
      associated type class.




          1
           Definition of parameterized categories, e.g. Throws[E] or Reads(resource),
      is also possible with the help of type lambdas and/or type providers.
Procedure Typing for Scala
  Specifying procedure categories
    Extensible approach




                                     Syntax details

          – A =>[R] B               R[A,B]
          – A => B          Function[A,B] , i.e. type named “Function” from the
              local context, not necessarily the Function from Predef2 .




          2
          (A, B) should also mean Pair[A,B] from the local context, as they
      must be consistent with functions: (A, B) => C ∼ A => B => C .
                                                     =
Procedure Typing for Scala
  Specifying procedure categories
    Extensible approach


      Proposed syntax for definitions


      def process(d: Data):
        =>[Throws[InterruptedException]] Int = { ...

      // Procedure types can be dependent
      def copy(src: File, dest: File):
        =>[Reads(src), Writes(dest)] { ...

      // Pre- and postconditions can be treated as effects too:
      def open(file: File):
        =>[Pre{file@Closed}, Post{file@Open}] { ...

      Last two examples rely on recently added dependent method types.
      (N.B. Such stunts are hard to implement using type-and-effect systems.)
Procedure Typing for Scala
  Defining procedure categories




              How to define a procedure category?
Procedure Typing for Scala
  Defining procedure categories




      First of all, it should be a category in the usual mathematical sense,
      i.e. we have to provide procedure composition and its neutral.
      trait Category[Function[_,_]] {
        def id[T]: T => T
        def compose[A, B, C](f: B => C, g: A => B): A => C
      }
Procedure Typing for Scala
  Defining procedure categories




      To give an example, let’s model logged functions on pure functions:
      type Logged[A, B] = (A =>[Pure] (B, String))

      object Logged extends Category[Logged] {
        def id[T] = {x: T => (x, "")}
        def compose[A, B, C](f: B => C, g: A => B) = {x: A =>
          val (result1, logOutput1) = g(x)
          val (result2, logOutput2) = f(result1)
          (result2, logOutput1 + logOutput2)
        }
      }


      Besides their results, logged functions produce log output of type
      String. Composition of logged functions concatenates their logs.
Procedure Typing for Scala
  Defining procedure categories




      Linear functional composition is not enough.
         We want to construct arbitrary circuits.




              (This is the key step in enabling implicit parallelisability.)
Procedure Typing for Scala
  Defining procedure categories




      To make arbitrary circuits, we need just one additional operation
      besides composition:
      def affix[A, B, C, D](f: A => B, g: C => D): (A, C) => (B, D)
Procedure Typing for Scala
  Defining procedure categories




      In case of pure functions, affix is trivial:
         – the execution of f and g is independent.

      In case of procedures affix is not-so-trivial:
         – have to pass the effects of f to the execution context of g ;
         – execution order can be significant.
Procedure Typing for Scala
  Defining procedure categories




      Thus, procedures belong to a stronger structure than just a
      category, namely a structure embracing the affix operation.


                 Such a structure is called circuitry.
Procedure Typing for Scala
  Defining procedure categories




      A circuitry is a closed monoidal category with respect to the   affix
      operation, where affix splits as follows:
      trait Circuitry[F[_,_]] extends PairCategory[F] {
        def passr[A, B, C](f: A => B): (A, C) => (B, C)
        def passl[B, C, D](g: C => D): (B, C) => (B, D)
        override def affix[A, B, C, D](f: A => B, g: C => D) = {
          compose(passl(g), passr(f))
        }
      }




                                 +             =
Procedure Typing for Scala
  Defining procedure categories



      For the mathematicians among us:
      trait PairCategory[F[_,_]] extends Category[F] {
        type Pair[A, B]
        def assoc[X, Y, Z]: ((X, Y), Z) => (X, (Y, Z))
        def unassoc[X, Y, Z]: (X, (Y, Z)) => ((X, Y), Z)

          type Unit
          def cancelr[X]: (X, Unit) => X
          def cancell[X]: (Unit, X) => X
          def uncancelr[X]: X => (X, Unit)
          def uncancell[X]: X => (Unit, X)

          def curry[A, B, C](f: (A, B) => C): A => B => C
          def uncurry[A, B, C](f: A => B => C): (A, B) => C
          def affix[A, B, C, D](f: A => B, g: C => D): (A, B) => (C, D)
      }
Procedure Typing for Scala
  Defining procedure categories



      For the mathematicians among us:
      trait PairCategory[F[_,_]] extends Category[F] {
        type Pair[A, B]
        def assoc[X, Y, Z]: ((X, Y), Z) => (X, (Y, Z))
        def unassoc[X, Y, Z]: (X, (Y, Z)) => ((X, Y), Z)

          type Unit
          def cancelr[X]: (X, Unit) => X
          def cancell[X]: (Unit, X) => X
          def uncancelr[X]: X => (X, Unit)
          def uncancell[X]: X => (Unit, X)

          def curry[A, B, C](f: (A, B) => C): A => B => C
          def uncurry[A, B, C](f: A => B => C): (A, B) => C
          def affix[A, B, C, D](f: A => B, g: C => D): (A, B) => (C, D)
      }


                                  Don’t panic!
Procedure Typing for Scala
  Defining procedure categories



      For the mathematicians among us:
      trait PairCategory[F[_,_]] extends Category[F] {
        type Pair[A, B]
        def assoc[X, Y, Z]: ((X, Y), Z) => (X, (Y, Z))
        def unassoc[X, Y, Z]: (X, (Y, Z)) => ((X, Y), Z)

          type Unit
          def cancelr[X]: (X, Unit) => X
          def cancell[X]: (Unit, X) => X
          def uncancelr[X]: X => (X, Unit)
          def uncancell[X]: X => (Unit, X)

          def curry[A, B, C](f: (A, B) => C): A => B => C
          def uncurry[A, B, C](f: A => B => C): (A, B) => C
          def affix[A, B, C, D](f: A => B, g: C => D): (A, B) => (C, D)
      }


                                  Don’t panic!
      In most cases the default Pair and Unit work perfectly well.
      ⇒ No need to understand any of this, just use with Cartesian .
Procedure Typing for Scala
  Defining procedure categories




      Elements of circuitries are called generalised arrows.

      Besides procedures, circuitries provide a common formalism for:
         – reversible quantum computations;
         – electrical and logical circuits;
         – linear and affine logic;
         – actor model and other process calculi.

      Circuitries provide the most general formalism for computations, see
      “Multi-Level Languages are Generalized Arrows”, A. Megacz.
Procedure Typing for Scala
  Defining procedure categories




      We are talking mostly about procedure typing, so we are going to
      consider some special cases:


      Arrow circuitries3 : circuitries generalising           =>[Pure]   .

      Executable categories: categories generalising to                  =>[Proc]   .

      Procedure categories: executable cartesian4 procedure circuitries.




          3
              AKA plain old “arrows” in Haskell and scalaz.
          4
              i.e. having cartesian product types.
Procedure Typing for Scala
  Defining procedure categories




      trait ArrowCircuitry[F[_,_]] extends Circuitry[F] {
        def reify[A, B](f: A =>[Pure] B): A => B
        ... // With reify we get id and passl for free
      }


      trait Executable extends Category[_] {
        def eval[A, B](f: A => B): A =>[Proc] B
        // eval defines the execution strategy
      }


      trait ProcCategory[F[_,_]] extends ArrowCircuitry[F] with
          Executable with Cartesian {
        ... // Some additional goodies
      }
Procedure Typing for Scala
  Defining procedure categories




      It’s time to give a full definition of   =>[Logged]   :
      type Logged[A, B] = (A =>[Pure] (B, String))

      object LoggedCircuitryImpl extends ProcCategory[Logged] {
        def reify[A, B](f: A =>[Pure] B) = {x: A => (f(x), "")}
        def compose[A, B, C](f: B => C, g: A => B) = {x: A =>
          val (result1, logOutput1) = g(x)
          val (result2, logOutput2) = f(result1)
          (result2, logOutput1 + logOutput2)
        }
        def passr[A, B, C](f: A => B): = {x : (A, C) =>
          val (result, log) = f(x._1)
          ((result, x._2), log)
        }
        def eval[A, B](p: A => B) = {x: A =>
          val (result, log) = p(x)
          println(log); result
        }
      }
Procedure Typing for Scala
  Defining procedure categories




      It’s time to give a full definition of   =>[Logged]   :
      type Logged[A, B] = (A =>[Pure] (B, String))

      object LoggedCircuitryImpl extends ProcCategory[Logged] {
        def reify[A, B](f: A =>[Pure] B) = {x: A => (f(x), "")}
        def compose[A, B, C](f: B => C, g: A => B) = {x: A =>
          val (result1, logOutput1) = g(x)
          val (result2, logOutput2) = f(result1)
          (result2, logOutput1 + logOutput2)
        }
        def passr[A, B, C](f: A => B): = {x : (A, C) =>
          val (result, log) = f(x._1)
          ((result, x._2), log)
        }
        def eval[A, B](p: A => B) = {x: A =>
          val (result, log) = p(x)
          println(log); result
        }
      }


      Wasn’t that easy?
Procedure Typing for Scala
  Defining procedure categories




      Additionally we need a companion object for      Logged[_,_]   type.

      That’s where circuitry-specific primitives should be defined.
      object Logged {
        val log: Logged[Unit, Unit] = {s: String => ((),s)}
      }
Procedure Typing for Scala
  Defining procedure categories




      Other circuitry-specific primitives include:
         –    throw    and       catch    for   =>[Throws[E]]

         –    shift    and       reset    for   =>[Cont]

         –    match/case         and     if/else   for   =>[WithChoice]

         –    while    and recursion for           =>[WithLoops]

         – etc.

      Often they have to be implemented with Scala macros (available in
      a next major Scala release near you).
Procedure Typing for Scala
  Language purification by procedure typing




      Note that impure code is localised to the   eval   method.
      Thus, thorough usage of procedure typing localizes
      impurities to well-controlled places in libraries.

      Except for these, Scala becomes a clean multilevel language,
      with effective type systems inside blocks being type-and-effect
      systems internal to corresponding circuitries.
Procedure Typing for Scala
  Language purification by procedure typing




      Curry-Howard-Lambek correspondence
      relates type theories, logics and categories:
      For cartesian closed categories:
          Internal logic = constructive proposition logic
          Internal language = simply-typed λ-calculus
      For locally cartesian closed categories:
          Internal logic = constructive predicate logic
          Internal language = dependently-typed λ-calculus
          ...
Procedure Typing for Scala
  Language purification by procedure typing




      Curry-Howard-Lambek correspondence
      relates type theories, logics and categories:
      For cartesian closed categories:
          Internal logic = constructive proposition logic
          Internal language = simply-typed λ-calculus
      For locally cartesian closed categories:
          Internal logic = constructive predicate logic
          Internal language = dependently-typed λ-calculus
          ...
      Informally, the work of A. Megacz provides an extension of it:
      For arrow circuitries:
          Internal logics = contextual logics
          Internal languages = type-and-effect extended λ-calculi
Procedure Typing for Scala
  Language purification by procedure typing




      Scala purification/modularization programme

          – Design a lattice of procedure categories between Pure and
            Proc . In particular, reimplement flow control primitives as
            macro5 methods in companion objects of respective categories.




          5
         One reason for employing macros is to guarantee that scaffoldings will be
      completely removed in compile time with no overhead on the bytecode level.
Procedure Typing for Scala
  Language purification by procedure typing




      Scala purification/modularization programme

          – Design a lattice of procedure categories between Pure and
            Proc . In particular, reimplement flow control primitives as
            macro5 methods in companion objects of respective categories.
          – Implement rules for lightweight effect polymorphism using a
            system of implicits à la Rytz-Odersky-Haller (2012)




          5
         One reason for employing macros is to guarantee that scaffoldings will be
      completely removed in compile time with no overhead on the bytecode level.
Procedure Typing for Scala
  Language purification by procedure typing




      Scala purification/modularization programme

          – Design a lattice of procedure categories between Pure and
            Proc . In particular, reimplement flow control primitives as
            macro5 methods in companion objects of respective categories.
          – Implement rules for lightweight effect polymorphism using a
            system of implicits à la Rytz-Odersky-Haller (2012)
          – Retrofit Akka with circuitries internalizing an appropriate actor
            calculus + ownership/borrowing system (Haller, 2010).




          5
         One reason for employing macros is to guarantee that scaffoldings will be
      completely removed in compile time with no overhead on the bytecode level.
Procedure Typing for Scala
  Comparing with other notions of computation




                     How do circuitries compare to
                     other notions of computation?
Procedure Typing for Scala
  Comparing with other notions of computation
   Type-and-effect systems




      Type-and-effect systems are the most well studied approach to
      procedure typing:
Procedure Typing for Scala
  Comparing with other notions of computation
   Type-and-effect systems




      Type-and-effect systems are the most well studied approach to
      procedure typing: effects are specifiers as annotations for
      “functions”; type system is extended with rules for “effects”.
Procedure Typing for Scala
  Comparing with other notions of computation
   Type-and-effect systems




      Type-and-effect systems are the most well studied approach to
      procedure typing: effects are specifiers as annotations for
      “functions”; type system is extended with rules for “effects”.

      Circuitry formalism is not an alternative, but an enclosure for
      them.
Procedure Typing for Scala
  Comparing with other notions of computation
   Type-and-effect systems




      Direct implementation of type-and-effect systems
         – is rigid (hardly extensible) and
         – requires changes to the typechecker.
Procedure Typing for Scala
  Comparing with other notions of computation
   Type-and-effect systems




      Direct implementation of type-and-effect systems
         – is rigid (hardly extensible) and
         – requires changes to the typechecker.

        Embedding effects into the type system by means of
         the circuitry formalism resolves the issues above.
Procedure Typing for Scala
  Comparing with other notions of computation
   Monads


     Arrows generalise monads




      In Haskell, monads are used as basis for imperative programming,
      but they are often not general enough (see Hughes, 2000).

      Monads are similar to cartesian arrow circuitries. The only
      difference is that they are not equipped with non-linear composition.
Procedure Typing for Scala
  Comparing with other notions of computation
   Monads




      Monads
         – do not compose well,
         – prescribe rigid execution order,
         – are not general enough for concurrent computations.
Procedure Typing for Scala
  Comparing with other notions of computation
   Monads




      Monads
         – do not compose well,
         – prescribe rigid execution order,
         – are not general enough for concurrent computations.



              Circuitries were invented to cure this.
Procedure Typing for Scala
  Comparing with other notions of computation
   Applicatives


     Applicatives are a special case of arrows...



      If procedures of type =>[A] never depend on effects of other
      procedures of the same type, A is called essentially commutative.

      Example
      =>[Reads(config), Writes(log), Throws[NonBlockingException]]


      Essentially commutative arrows arise from applicative functors.
      They are flexible and easy to handle: you don’t have to propagate
      effects, just accumulate them behind the scenes.
Procedure Typing for Scala
  Comparing with other notions of computation
   Applicatives


     ...but not a closed special case!



      Composing applicatives may produce non-commutative circuitries
      like =>[Reads(file), Writes(file)] .
      Procedures of this type are no longer effect-independent: effect of
      writes have to be passed to subsequent reads.

      Besides these, there are also inherently non-commutative arrows
      such as those arising from monads6 , comonads and Hoare triples7 .




          6
              e.g. Tx = transaction monad, Cont = continuation passing monad.
          7
              pre- and postconditioned arrows.
Procedure Typing for Scala
  Comparing with other notions of computation
   Traditional imperative approach




               Can we do everything available in imperative
                  languages with arrows and circuitries?
Procedure Typing for Scala
  Comparing with other notions of computation
   Traditional imperative approach




               Can we do everything available in imperative
                  languages with arrows and circuitries?

      Any imperative code can be reduced to compose and affix.
Procedure Typing for Scala
  Comparing with other notions of computation
   Traditional imperative approach




               Can we do everything available in imperative
                  languages with arrows and circuitries?

      Any imperative code can be reduced to compose and affix.
      The reduction process is known as variable elimination, it can be
      understood as translation to a concatenative language like Forth.
Procedure Typing for Scala
  Comparing with other notions of computation
   Traditional imperative approach




               Can we do everything available in imperative
                  languages with arrows and circuitries?

      Any imperative code can be reduced to compose and affix.
      The reduction process is known as variable elimination, it can be
      understood as translation to a concatenative language like Forth.
      (The concatenative languages’ juxtaposition is an overloaded operator reducing
      to either compose or affix depending on how operands’ types match.)
Procedure Typing for Scala
  Comparing with other notions of computation
   Traditional imperative approach




               Can we do everything available in imperative
                  languages with arrows and circuitries?

      Any imperative code can be reduced to compose and affix.
      The reduction process is known as variable elimination, it can be
      understood as translation to a concatenative language like Forth.
      (The concatenative languages’ juxtaposition is an overloaded operator reducing
      to either compose or affix depending on how operands’ types match.)

      But! Writing code this way can be quite cumbersome.
Procedure Typing for Scala
  Do-notation




                Defining procedure categories is easy
                 enough. How about using them?
      We develop a quasi-imperative notation8 and implement it using
      macros.
               Our notation shares syntax with usual Scala imperative code...
               ...but has different semantics: it compiles to a circuit of
               appropriate type instead of being executed immediately.




          8
              Akin to Haskell’s do-notation, but much easier to use.
Procedure Typing for Scala
  Do-notation




                Defining procedure categories is easy
                 enough. How about using them?
      We develop a quasi-imperative notation8 and implement it using
      macros.
               Our notation shares syntax with usual Scala imperative code...
               ...but has different semantics: it compiles to a circuit of
               appropriate type instead of being executed immediately.

       Circuit notation for Scala is the topic of the part II...



          8
              Akin to Haskell’s do-notation, but much easier to use.
Procedure Typing for Scala
  Do-notation



     Do-notation example
           ...but here’s a small example to keep your interest

      Even pure functions have a side effect: they consume time.
      =>[Future] is an example of a retrofitting procedure category9 .

      =>[Future] {
        val a = alpha(x)
        val b = beta(x)
        after (a | b) {
          Log.info("First one is completed")
        }
        after (a & b) {
          Log.info("Both completed")
        }
        gamma(a, b)
      }


          9
              its reify is a macro, so any procedures can be retrofitted to be =>[Future].
Procedure Typing for Scala
  Do-notation




      Literature:
          – The marriage of effects and monads, P. Wadler, P. Thiemann
          – Generalising monads to arrows, J. Hughes
          – The Arrow Calculus, S. Lindley, P. Wadler, and J. Yallop
          – Categorical semantics for arrows, B. Jacobs et al.
          – What is a Categorical Model of Arrows?, R. Atkey
          – Parameterized Notions of Computation, R. Atkey
          – Multi-Level Languages are Generalized Arrows, A. Megacz
Procedure Typing for Scala
  Syntax for Circuitires




                       Part II: Syntax for Circuitires




                                     A cup of coffee?
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      How do you use an arrow (say f: Logged[Int, String] ) in
      present Scala code?

       println(f(5)) seems to be the obvious way, but that’s
      impossible, application is not defined for f.

      To facilitate such natural notation, we need implicit unboxing.
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      Preliminaries
      A wrapping is a type F[_] equipped with eval[T](v: F[T]): T
      and reify[T](expr: => T): F[T] (reify often being a macro) so
      that
        eval(reify(x)) ≡ x and
        reify(eval(x)) ≡ x for all x of the correct type.
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      Preliminaries
      A wrapping is a type F[_] equipped with eval[T](v: F[T]): T
      and reify[T](expr: => T): F[T] (reify often being a macro) so
      that
        eval(reify(x)) ≡ x and
        reify(eval(x)) ≡ x for all x of the correct type.

      A prototypical example where reify is a macro is Expr[T]. Example
      with no macros involved is Future[T] (with await as eval).
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      Preliminaries
      Implicit unboxing is this: whenever a value of the wrapping type
      F[T] is found where a value of type T is accepted, its eval is called
      implicitly.

      In homoiconic languages (including Scala), all expressions can be
      considered initially having the type Expr[T] and being unboxed into
      T by an implicit unboxing rule Expr[T] => T .
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      Syntax proposal
      Let’s introduce an instruction implicit[F] enabling implicit
      unboxing for F in its scope.

      Implicit contexts can be implemented using macros:
          – macro augments the relevant scope by F.reify as an implicit
            conversion from F[T] to T;
          – F.eval is applied to every occurrence of a symbol having or
            returning type F[T] which is defined outside of its scope.
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      Code that uses futures and promises can be made much more
      readable by implicit unboxing.

      An example: dataflows in Akka 2.0. Presently they look like this:
      flow {
        z << (x() + y())
        if (v() > u) println("z = " + z())
      }
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      Now this can be recast without any unintuitive empty parentheses:
      flow {
        z << x + y
        if (v > u) println("z = " + z)
      }
Procedure Typing for Scala
  Syntax for Circuitires
    Implicit Unboxing




      Back to our Logged example:
      implicit[Logged]
      def example(f: Int =>[Logged] String, n: Int): List[String] {
        f(n).split(", ")
      }

      Which translates to:
      def example(f: Int =>[Logged] String, n: Int): List[String] {
        LoggedCircuitryImpl.eval(f)(n).split(", ")
      }
Procedure Typing for Scala
  Syntax for Circuitires
    Purifying Scala




      Now, which procedure category should example() belong to?

      As it evaluates =>[Logged], it should be =>[Logged] itself. This
      allows its reinterpretation without any usage of eval:
      def example(f: Int =>[Logged] String, n: Int): List[String] = {
        import LoggedCircuitryImpl._
        reify{n} andThen f andThen reify{_.split(", ")}
      }

      This is now a pure code generating a new circuit of the type
      =>[Logged] based on the existing one (f) and some pure functions.
Procedure Typing for Scala
  Syntax for Circuitires
    Purifying Scala


     Purity Declaration



      Let’s introduce @pure annotation which explicitly forbids calling
      any functions with side effects and assignments of foreign variables.
      This renders the code pure.

      Procedure with side effects have to be composed by circuit
      composition operations which are pure. The execution of
      procedures, which is impure, always lies outside of the scope.

      All code examples below are to be read as @pure .
Procedure Typing for Scala
  Syntax for Circuitires
    Purifying Scala




      Inside of @pure implicit unboxing for arrows becomes
      implicit circuit notation, which is operationally
      indistinguishable, but semantically different.
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      Circuit notation, general idea:
          – write circuitry type like =>[X] in front of a braced code block;
          – the code block will be reinterpreted as a circuitry of the given
            type (via macros).
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      Example:
      =>[Logged] {
        f(x) + g(x)
      }

      Result:
      (reify{x} andThen reify(dup) andThen (f affix g) andThen reify{_ + _})
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      In presence of implicit[X] every free braced block {...}
      which uses external symbols of the type =>[X] should be
      treated as =>[X] {...} , an implicit form of circuit syntax.
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      The desugaring rules producing operationally indistinguishable
      circuits from imperative-style code blocks are quite complicated,
      but certainly doable.

      To make the other direction possible, we need an additional
      operator: after .
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      Consider two arrows f: Unit => Unit and g: Unit => Unit .
      They can be composed in two ways: f affix g (out-of-order) and
      f andThen g (in-order).

       affix in circuit notation will obviously look like f; g , though for
       andThen we need some new syntax:

      =>[Future] {
        val n = f
        after(n) g
      }
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      Without after , =>[Future] and other similar circuitries respect
      only dataflow ordering, but ignore the order of independent effects
      (e.g. writing into a log).

      By combining usual imperative notation and after ,
      any possible circuit configurations can be achieved.
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      Now the example stated above is fully understandable:
      =>[Future] {
        val a = alpha(x)
        val b = beta(x)
        after (a | b) {
          Log.info("First one is completed")
        }
        after (a & b) {
          Log.info("Both completed")
        }
        gamma(a, b)
      }

      ( after trivially supports any combinations of ands and ors.)
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      Blocks as Objects
      For the sake of composability, blocks should be treated as
      anonymous classes extending their arrow type:
      =>[Future] {
        val result = {
          @expose val partialResult = compute1(x)
          compute2(partialResult)
        }
        after (result.partialResult) {
          Log.info("Partial result ready")
        }
      }

      The result in the after context is not just =>[Future] Int , but
      its anonymous descendant with a public member partialResult .
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      Of course, it should also work for named blocks:
      def lengthyComputation(x: Double): Double = {
       var _progress = 0.0      // goes from 0.0 to 1.0
       @expose def progress = _progress // public getter
       ... // _progress is updated when necessary
      }

      val f = future someLengthyCalculation(x)
      while (!f.isDone) {
       Log.info("Progress: " + f.progress)
       wait(500 ms)
      }

      (This is a perfect example of what can easily be done with macros.)
Procedure Typing for Scala
  Syntax for Circuitires
    Circuit notation




      The exact desugaring rules are quite complex (but perfectly real).
      We hope these examples gave you some insight how everything
      might work.




                               Thank you!

Contenu connexe

Tendances (19)

Functional Objects & Function and Closures
Functional Objects  & Function and ClosuresFunctional Objects  & Function and Closures
Functional Objects & Function and Closures
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 
Scala Intro
Scala IntroScala Intro
Scala Intro
 
Stepping Up : A Brief Intro to Scala
Stepping Up : A Brief Intro to ScalaStepping Up : A Brief Intro to Scala
Stepping Up : A Brief Intro to Scala
 
Scala
ScalaScala
Scala
 
Google06
Google06Google06
Google06
 
Workshop Scala
Workshop ScalaWorkshop Scala
Workshop Scala
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
 
A Tour Of Scala
A Tour Of ScalaA Tour Of Scala
A Tour Of Scala
 
Scala - brief intro
Scala - brief introScala - brief intro
Scala - brief intro
 
Scala in a nutshell by venkat
Scala in a nutshell by venkatScala in a nutshell by venkat
Scala in a nutshell by venkat
 
The Evolution of Scala
The Evolution of ScalaThe Evolution of Scala
The Evolution of Scala
 
Core java Essentials
Core java EssentialsCore java Essentials
Core java Essentials
 
Functional Programming In Practice
Functional Programming In PracticeFunctional Programming In Practice
Functional Programming In Practice
 
Scala eXchange opening
Scala eXchange openingScala eXchange opening
Scala eXchange opening
 
Java tutorial for Beginners and Entry Level
Java tutorial for Beginners and Entry LevelJava tutorial for Beginners and Entry Level
Java tutorial for Beginners and Entry Level
 
Introduction to programming in scala
Introduction to programming in scalaIntroduction to programming in scala
Introduction to programming in scala
 
scala
scalascala
scala
 

En vedette

Scala in practice
Scala in practiceScala in practice
Scala in practiceTomer Gabel
 
Scalding: Twitter's Scala DSL for Hadoop/Cascading
Scalding: Twitter's Scala DSL for Hadoop/CascadingScalding: Twitter's Scala DSL for Hadoop/Cascading
Scalding: Twitter's Scala DSL for Hadoop/Cascadingjohnynek
 
BigData, Hadoop과 Node.js, R2
BigData, Hadoop과 Node.js, R2BigData, Hadoop과 Node.js, R2
BigData, Hadoop과 Node.js, R2고포릿 default
 
Elixirと他言語の比較的紹介 ver.2
Elixirと他言語の比較的紹介ver.2Elixirと他言語の比較的紹介ver.2
Elixirと他言語の比較的紹介 ver.2Tsunenori Oohara
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Yasutaka Kawamoto
 
PHP7はなぜ速いのか
PHP7はなぜ速いのかPHP7はなぜ速いのか
PHP7はなぜ速いのかYoshio Hanawa
 
java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰Sungchul Park
 
地獄のElixir(目黒スタートアップ勉強会)
地獄のElixir(目黒スタートアップ勉強会)地獄のElixir(目黒スタートアップ勉強会)
地獄のElixir(目黒スタートアップ勉強会)Tsunenori Oohara
 
PHP7で変わること ——言語仕様とエンジンの改善ポイント
PHP7で変わること ——言語仕様とエンジンの改善ポイントPHP7で変わること ——言語仕様とエンジンの改善ポイント
PHP7で変わること ——言語仕様とエンジンの改善ポイントYoshio Hanawa
 
Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)
Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)
Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)NTT DATA OSS Professional Services
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)NTT DATA OSS Professional Services
 
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンAkihiko Horiuchi
 
DIAMOND CUTTING
DIAMOND CUTTINGDIAMOND CUTTING
DIAMOND CUTTINGTom Choon
 

En vedette (17)

Scala in practice
Scala in practiceScala in practice
Scala in practice
 
Scala profiling
Scala profilingScala profiling
Scala profiling
 
Scalding: Twitter's Scala DSL for Hadoop/Cascading
Scalding: Twitter's Scala DSL for Hadoop/CascadingScalding: Twitter's Scala DSL for Hadoop/Cascading
Scalding: Twitter's Scala DSL for Hadoop/Cascading
 
BigData, Hadoop과 Node.js, R2
BigData, Hadoop과 Node.js, R2BigData, Hadoop과 Node.js, R2
BigData, Hadoop과 Node.js, R2
 
RESTful Java
RESTful JavaRESTful Java
RESTful Java
 
Elixirと他言語の比較的紹介 ver.2
Elixirと他言語の比較的紹介ver.2Elixirと他言語の比較的紹介ver.2
Elixirと他言語の比較的紹介 ver.2
 
Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方Go言語によるwebアプリの作り方
Go言語によるwebアプリの作り方
 
PHP7はなぜ速いのか
PHP7はなぜ速いのかPHP7はなぜ速いのか
PHP7はなぜ速いのか
 
java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰
 
地獄のElixir(目黒スタートアップ勉強会)
地獄のElixir(目黒スタートアップ勉強会)地獄のElixir(目黒スタートアップ勉強会)
地獄のElixir(目黒スタートアップ勉強会)
 
PHP7で変わること ——言語仕様とエンジンの改善ポイント
PHP7で変わること ——言語仕様とエンジンの改善ポイントPHP7で変わること ——言語仕様とエンジンの改善ポイント
PHP7で変わること ——言語仕様とエンジンの改善ポイント
 
Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)
Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)
Apache Spark超入門 (Hadoop / Spark Conference Japan 2016 講演資料)
 
Scala Days NYC 2016
Scala Days NYC 2016Scala Days NYC 2016
Scala Days NYC 2016
 
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
Apache Sparkに手を出してヤケドしないための基本 ~「Apache Spark入門より」~ (デブサミ 2016 講演資料)
 
GoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホンGoによるWebアプリ開発のキホン
GoによるWebアプリ開発のキホン
 
DIAMOND CUTTING
DIAMOND CUTTINGDIAMOND CUTTING
DIAMOND CUTTING
 
Ndwa leadingwith love digital journal 2012
Ndwa leadingwith love digital journal 2012Ndwa leadingwith love digital journal 2012
Ndwa leadingwith love digital journal 2012
 

Similaire à Procedure Typing for Scala

Loops and functions in r
Loops and functions in rLoops and functions in r
Loops and functions in rmanikanta361
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Languageleague
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskellnebuta
 
Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010JUG Lausanne
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed worldDebasish Ghosh
 
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021Peng Cheng
 
sonam Kumari python.ppt
sonam Kumari python.pptsonam Kumari python.ppt
sonam Kumari python.pptssuserd64918
 
Matlab Functions
Matlab FunctionsMatlab Functions
Matlab FunctionsUmer Azeem
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concernssaintiss
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with ScalaNeelkanth Sachdeva
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdfHiroshi Ono
 

Similaire à Procedure Typing for Scala (20)

Loops and functions in r
Loops and functions in rLoops and functions in r
Loops and functions in r
 
The Scala Programming Language
The Scala Programming LanguageThe Scala Programming Language
The Scala Programming Language
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
 
Lecture 3
Lecture 3Lecture 3
Lecture 3
 
Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010Introduction à Scala - Michel Schinz - January 2010
Introduction à Scala - Michel Schinz - January 2010
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
Shape Safety in Tensor Programming is Easy for a Theorem Prover -SBTB 2021
 
sonam Kumari python.ppt
sonam Kumari python.pptsonam Kumari python.ppt
sonam Kumari python.ppt
 
Matlab Functions
Matlab FunctionsMatlab Functions
Matlab Functions
 
Java gets a closure
Java gets a closureJava gets a closure
Java gets a closure
 
C# programming
C# programming C# programming
C# programming
 
Machine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting ConcernsMachine-level Composition of Modularized Crosscutting Concerns
Machine-level Composition of Modularized Crosscutting Concerns
 
Scala in Places API
Scala in Places APIScala in Places API
Scala in Places API
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 
scalaliftoff2009.pdf
scalaliftoff2009.pdfscalaliftoff2009.pdf
scalaliftoff2009.pdf
 

Dernier

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 

Dernier (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 

Procedure Typing for Scala

  • 1. Procedure Typing for Scala Procedure Typing for Scala Alexander Kuklev∗ , Alexander Temerev‡ * Institute of Theoretical Physics, University of Göttingen ‡ Founder and CEO at Miriamlaurel Sàrl, Geneva April 10, 2012
  • 2. Procedure Typing for Scala Functions and procedures In programming we have: – pure functions; – functions with side effects (AKA procedures).
  • 3. Procedure Typing for Scala Functions and procedures In programming we have: – pure functions; – functions with side effects (AKA procedures). Scala does not differentiate between them: – both have types A => B .
  • 4. Procedure Typing for Scala But it should!
  • 5. Procedure Typing for Scala But it should! Static side effect tracking enables – implicit parallelisability;
  • 6. Procedure Typing for Scala But it should! Static side effect tracking enables – implicit parallelisability; – compile-time detection of a whole new class of problems: (resource acquisition and releasing problems, race conditions, deadlocks, etc.).
  • 7. Procedure Typing for Scala Short list of applicable methodologies: Kleisli Arrows of Outrageous Fortune (2011, C. McBride) Capabilities for Uniqueness and Borrowing (2010, P. Haller, M. Odersky) Static Detection of Race Conditions [..] (2010, M. Christakis, K. Sagonas) Static Deadlock Detection [..] (2009, F. de Boer, I. Grabe,M. Steffen) Complete Behavioural Testing of Object-Oriented Systems using CCS-Augmented X-Machines (2002, M. Stannett, A. J. H. Simons) An integration testing method that is proved to find all faults (1997, F. Ipate, M. Holcombe)
  • 8. Procedure Typing for Scala Specifying procedure categories We propose a new syntax where a function definition may include a category it belongs to: A =>[Pure] B – pure functions; A =>[Proc] B – procedures.
  • 9. Procedure Typing for Scala Specifying procedure categories There’s a lot more than Pure and Proc There is a whole lattice of categories between Pure and Proc : Logged: procedures with no side effects besides logging; Throws[E]: no side effects besides throwing exceptions of type E ; Reads(file): no side effects besides reading the file ; etc.
  • 10. Procedure Typing for Scala Specifying procedure categories Extensible approach An effect system should be extensible. ⇒ We must provide a way to define procedure categories. Procedure categories are binary types like Function[_,_] or Logged[_,_] 1 1 Definition of parameterized categories, e.g. Throws[E] or Reads(resource), is also possible with the help of type lambdas and/or type providers.
  • 11. Procedure Typing for Scala Specifying procedure categories Extensible approach An effect system should be extensible. ⇒ We must provide a way to define procedure categories. Procedure categories are binary types like Function[_,_] or Logged[_,_] 1 equipped with some additional structure using an associated type class. 1 Definition of parameterized categories, e.g. Throws[E] or Reads(resource), is also possible with the help of type lambdas and/or type providers.
  • 12. Procedure Typing for Scala Specifying procedure categories Extensible approach Syntax details – A =>[R] B R[A,B] – A => B Function[A,B] , i.e. type named “Function” from the local context, not necessarily the Function from Predef2 . 2 (A, B) should also mean Pair[A,B] from the local context, as they must be consistent with functions: (A, B) => C ∼ A => B => C . =
  • 13. Procedure Typing for Scala Specifying procedure categories Extensible approach Proposed syntax for definitions def process(d: Data): =>[Throws[InterruptedException]] Int = { ... // Procedure types can be dependent def copy(src: File, dest: File): =>[Reads(src), Writes(dest)] { ... // Pre- and postconditions can be treated as effects too: def open(file: File): =>[Pre{file@Closed}, Post{file@Open}] { ... Last two examples rely on recently added dependent method types. (N.B. Such stunts are hard to implement using type-and-effect systems.)
  • 14. Procedure Typing for Scala Defining procedure categories How to define a procedure category?
  • 15. Procedure Typing for Scala Defining procedure categories First of all, it should be a category in the usual mathematical sense, i.e. we have to provide procedure composition and its neutral. trait Category[Function[_,_]] { def id[T]: T => T def compose[A, B, C](f: B => C, g: A => B): A => C }
  • 16. Procedure Typing for Scala Defining procedure categories To give an example, let’s model logged functions on pure functions: type Logged[A, B] = (A =>[Pure] (B, String)) object Logged extends Category[Logged] { def id[T] = {x: T => (x, "")} def compose[A, B, C](f: B => C, g: A => B) = {x: A => val (result1, logOutput1) = g(x) val (result2, logOutput2) = f(result1) (result2, logOutput1 + logOutput2) } } Besides their results, logged functions produce log output of type String. Composition of logged functions concatenates their logs.
  • 17. Procedure Typing for Scala Defining procedure categories Linear functional composition is not enough. We want to construct arbitrary circuits. (This is the key step in enabling implicit parallelisability.)
  • 18. Procedure Typing for Scala Defining procedure categories To make arbitrary circuits, we need just one additional operation besides composition: def affix[A, B, C, D](f: A => B, g: C => D): (A, C) => (B, D)
  • 19. Procedure Typing for Scala Defining procedure categories In case of pure functions, affix is trivial: – the execution of f and g is independent. In case of procedures affix is not-so-trivial: – have to pass the effects of f to the execution context of g ; – execution order can be significant.
  • 20. Procedure Typing for Scala Defining procedure categories Thus, procedures belong to a stronger structure than just a category, namely a structure embracing the affix operation. Such a structure is called circuitry.
  • 21. Procedure Typing for Scala Defining procedure categories A circuitry is a closed monoidal category with respect to the affix operation, where affix splits as follows: trait Circuitry[F[_,_]] extends PairCategory[F] { def passr[A, B, C](f: A => B): (A, C) => (B, C) def passl[B, C, D](g: C => D): (B, C) => (B, D) override def affix[A, B, C, D](f: A => B, g: C => D) = { compose(passl(g), passr(f)) } } + =
  • 22. Procedure Typing for Scala Defining procedure categories For the mathematicians among us: trait PairCategory[F[_,_]] extends Category[F] { type Pair[A, B] def assoc[X, Y, Z]: ((X, Y), Z) => (X, (Y, Z)) def unassoc[X, Y, Z]: (X, (Y, Z)) => ((X, Y), Z) type Unit def cancelr[X]: (X, Unit) => X def cancell[X]: (Unit, X) => X def uncancelr[X]: X => (X, Unit) def uncancell[X]: X => (Unit, X) def curry[A, B, C](f: (A, B) => C): A => B => C def uncurry[A, B, C](f: A => B => C): (A, B) => C def affix[A, B, C, D](f: A => B, g: C => D): (A, B) => (C, D) }
  • 23. Procedure Typing for Scala Defining procedure categories For the mathematicians among us: trait PairCategory[F[_,_]] extends Category[F] { type Pair[A, B] def assoc[X, Y, Z]: ((X, Y), Z) => (X, (Y, Z)) def unassoc[X, Y, Z]: (X, (Y, Z)) => ((X, Y), Z) type Unit def cancelr[X]: (X, Unit) => X def cancell[X]: (Unit, X) => X def uncancelr[X]: X => (X, Unit) def uncancell[X]: X => (Unit, X) def curry[A, B, C](f: (A, B) => C): A => B => C def uncurry[A, B, C](f: A => B => C): (A, B) => C def affix[A, B, C, D](f: A => B, g: C => D): (A, B) => (C, D) } Don’t panic!
  • 24. Procedure Typing for Scala Defining procedure categories For the mathematicians among us: trait PairCategory[F[_,_]] extends Category[F] { type Pair[A, B] def assoc[X, Y, Z]: ((X, Y), Z) => (X, (Y, Z)) def unassoc[X, Y, Z]: (X, (Y, Z)) => ((X, Y), Z) type Unit def cancelr[X]: (X, Unit) => X def cancell[X]: (Unit, X) => X def uncancelr[X]: X => (X, Unit) def uncancell[X]: X => (Unit, X) def curry[A, B, C](f: (A, B) => C): A => B => C def uncurry[A, B, C](f: A => B => C): (A, B) => C def affix[A, B, C, D](f: A => B, g: C => D): (A, B) => (C, D) } Don’t panic! In most cases the default Pair and Unit work perfectly well. ⇒ No need to understand any of this, just use with Cartesian .
  • 25. Procedure Typing for Scala Defining procedure categories Elements of circuitries are called generalised arrows. Besides procedures, circuitries provide a common formalism for: – reversible quantum computations; – electrical and logical circuits; – linear and affine logic; – actor model and other process calculi. Circuitries provide the most general formalism for computations, see “Multi-Level Languages are Generalized Arrows”, A. Megacz.
  • 26. Procedure Typing for Scala Defining procedure categories We are talking mostly about procedure typing, so we are going to consider some special cases: Arrow circuitries3 : circuitries generalising =>[Pure] . Executable categories: categories generalising to =>[Proc] . Procedure categories: executable cartesian4 procedure circuitries. 3 AKA plain old “arrows” in Haskell and scalaz. 4 i.e. having cartesian product types.
  • 27. Procedure Typing for Scala Defining procedure categories trait ArrowCircuitry[F[_,_]] extends Circuitry[F] { def reify[A, B](f: A =>[Pure] B): A => B ... // With reify we get id and passl for free } trait Executable extends Category[_] { def eval[A, B](f: A => B): A =>[Proc] B // eval defines the execution strategy } trait ProcCategory[F[_,_]] extends ArrowCircuitry[F] with Executable with Cartesian { ... // Some additional goodies }
  • 28. Procedure Typing for Scala Defining procedure categories It’s time to give a full definition of =>[Logged] : type Logged[A, B] = (A =>[Pure] (B, String)) object LoggedCircuitryImpl extends ProcCategory[Logged] { def reify[A, B](f: A =>[Pure] B) = {x: A => (f(x), "")} def compose[A, B, C](f: B => C, g: A => B) = {x: A => val (result1, logOutput1) = g(x) val (result2, logOutput2) = f(result1) (result2, logOutput1 + logOutput2) } def passr[A, B, C](f: A => B): = {x : (A, C) => val (result, log) = f(x._1) ((result, x._2), log) } def eval[A, B](p: A => B) = {x: A => val (result, log) = p(x) println(log); result } }
  • 29. Procedure Typing for Scala Defining procedure categories It’s time to give a full definition of =>[Logged] : type Logged[A, B] = (A =>[Pure] (B, String)) object LoggedCircuitryImpl extends ProcCategory[Logged] { def reify[A, B](f: A =>[Pure] B) = {x: A => (f(x), "")} def compose[A, B, C](f: B => C, g: A => B) = {x: A => val (result1, logOutput1) = g(x) val (result2, logOutput2) = f(result1) (result2, logOutput1 + logOutput2) } def passr[A, B, C](f: A => B): = {x : (A, C) => val (result, log) = f(x._1) ((result, x._2), log) } def eval[A, B](p: A => B) = {x: A => val (result, log) = p(x) println(log); result } } Wasn’t that easy?
  • 30. Procedure Typing for Scala Defining procedure categories Additionally we need a companion object for Logged[_,_] type. That’s where circuitry-specific primitives should be defined. object Logged { val log: Logged[Unit, Unit] = {s: String => ((),s)} }
  • 31. Procedure Typing for Scala Defining procedure categories Other circuitry-specific primitives include: – throw and catch for =>[Throws[E]] – shift and reset for =>[Cont] – match/case and if/else for =>[WithChoice] – while and recursion for =>[WithLoops] – etc. Often they have to be implemented with Scala macros (available in a next major Scala release near you).
  • 32. Procedure Typing for Scala Language purification by procedure typing Note that impure code is localised to the eval method. Thus, thorough usage of procedure typing localizes impurities to well-controlled places in libraries. Except for these, Scala becomes a clean multilevel language, with effective type systems inside blocks being type-and-effect systems internal to corresponding circuitries.
  • 33. Procedure Typing for Scala Language purification by procedure typing Curry-Howard-Lambek correspondence relates type theories, logics and categories: For cartesian closed categories: Internal logic = constructive proposition logic Internal language = simply-typed λ-calculus For locally cartesian closed categories: Internal logic = constructive predicate logic Internal language = dependently-typed λ-calculus ...
  • 34. Procedure Typing for Scala Language purification by procedure typing Curry-Howard-Lambek correspondence relates type theories, logics and categories: For cartesian closed categories: Internal logic = constructive proposition logic Internal language = simply-typed λ-calculus For locally cartesian closed categories: Internal logic = constructive predicate logic Internal language = dependently-typed λ-calculus ... Informally, the work of A. Megacz provides an extension of it: For arrow circuitries: Internal logics = contextual logics Internal languages = type-and-effect extended λ-calculi
  • 35. Procedure Typing for Scala Language purification by procedure typing Scala purification/modularization programme – Design a lattice of procedure categories between Pure and Proc . In particular, reimplement flow control primitives as macro5 methods in companion objects of respective categories. 5 One reason for employing macros is to guarantee that scaffoldings will be completely removed in compile time with no overhead on the bytecode level.
  • 36. Procedure Typing for Scala Language purification by procedure typing Scala purification/modularization programme – Design a lattice of procedure categories between Pure and Proc . In particular, reimplement flow control primitives as macro5 methods in companion objects of respective categories. – Implement rules for lightweight effect polymorphism using a system of implicits à la Rytz-Odersky-Haller (2012) 5 One reason for employing macros is to guarantee that scaffoldings will be completely removed in compile time with no overhead on the bytecode level.
  • 37. Procedure Typing for Scala Language purification by procedure typing Scala purification/modularization programme – Design a lattice of procedure categories between Pure and Proc . In particular, reimplement flow control primitives as macro5 methods in companion objects of respective categories. – Implement rules for lightweight effect polymorphism using a system of implicits à la Rytz-Odersky-Haller (2012) – Retrofit Akka with circuitries internalizing an appropriate actor calculus + ownership/borrowing system (Haller, 2010). 5 One reason for employing macros is to guarantee that scaffoldings will be completely removed in compile time with no overhead on the bytecode level.
  • 38. Procedure Typing for Scala Comparing with other notions of computation How do circuitries compare to other notions of computation?
  • 39. Procedure Typing for Scala Comparing with other notions of computation Type-and-effect systems Type-and-effect systems are the most well studied approach to procedure typing:
  • 40. Procedure Typing for Scala Comparing with other notions of computation Type-and-effect systems Type-and-effect systems are the most well studied approach to procedure typing: effects are specifiers as annotations for “functions”; type system is extended with rules for “effects”.
  • 41. Procedure Typing for Scala Comparing with other notions of computation Type-and-effect systems Type-and-effect systems are the most well studied approach to procedure typing: effects are specifiers as annotations for “functions”; type system is extended with rules for “effects”. Circuitry formalism is not an alternative, but an enclosure for them.
  • 42. Procedure Typing for Scala Comparing with other notions of computation Type-and-effect systems Direct implementation of type-and-effect systems – is rigid (hardly extensible) and – requires changes to the typechecker.
  • 43. Procedure Typing for Scala Comparing with other notions of computation Type-and-effect systems Direct implementation of type-and-effect systems – is rigid (hardly extensible) and – requires changes to the typechecker. Embedding effects into the type system by means of the circuitry formalism resolves the issues above.
  • 44. Procedure Typing for Scala Comparing with other notions of computation Monads Arrows generalise monads In Haskell, monads are used as basis for imperative programming, but they are often not general enough (see Hughes, 2000). Monads are similar to cartesian arrow circuitries. The only difference is that they are not equipped with non-linear composition.
  • 45. Procedure Typing for Scala Comparing with other notions of computation Monads Monads – do not compose well, – prescribe rigid execution order, – are not general enough for concurrent computations.
  • 46. Procedure Typing for Scala Comparing with other notions of computation Monads Monads – do not compose well, – prescribe rigid execution order, – are not general enough for concurrent computations. Circuitries were invented to cure this.
  • 47. Procedure Typing for Scala Comparing with other notions of computation Applicatives Applicatives are a special case of arrows... If procedures of type =>[A] never depend on effects of other procedures of the same type, A is called essentially commutative. Example =>[Reads(config), Writes(log), Throws[NonBlockingException]] Essentially commutative arrows arise from applicative functors. They are flexible and easy to handle: you don’t have to propagate effects, just accumulate them behind the scenes.
  • 48. Procedure Typing for Scala Comparing with other notions of computation Applicatives ...but not a closed special case! Composing applicatives may produce non-commutative circuitries like =>[Reads(file), Writes(file)] . Procedures of this type are no longer effect-independent: effect of writes have to be passed to subsequent reads. Besides these, there are also inherently non-commutative arrows such as those arising from monads6 , comonads and Hoare triples7 . 6 e.g. Tx = transaction monad, Cont = continuation passing monad. 7 pre- and postconditioned arrows.
  • 49. Procedure Typing for Scala Comparing with other notions of computation Traditional imperative approach Can we do everything available in imperative languages with arrows and circuitries?
  • 50. Procedure Typing for Scala Comparing with other notions of computation Traditional imperative approach Can we do everything available in imperative languages with arrows and circuitries? Any imperative code can be reduced to compose and affix.
  • 51. Procedure Typing for Scala Comparing with other notions of computation Traditional imperative approach Can we do everything available in imperative languages with arrows and circuitries? Any imperative code can be reduced to compose and affix. The reduction process is known as variable elimination, it can be understood as translation to a concatenative language like Forth.
  • 52. Procedure Typing for Scala Comparing with other notions of computation Traditional imperative approach Can we do everything available in imperative languages with arrows and circuitries? Any imperative code can be reduced to compose and affix. The reduction process is known as variable elimination, it can be understood as translation to a concatenative language like Forth. (The concatenative languages’ juxtaposition is an overloaded operator reducing to either compose or affix depending on how operands’ types match.)
  • 53. Procedure Typing for Scala Comparing with other notions of computation Traditional imperative approach Can we do everything available in imperative languages with arrows and circuitries? Any imperative code can be reduced to compose and affix. The reduction process is known as variable elimination, it can be understood as translation to a concatenative language like Forth. (The concatenative languages’ juxtaposition is an overloaded operator reducing to either compose or affix depending on how operands’ types match.) But! Writing code this way can be quite cumbersome.
  • 54. Procedure Typing for Scala Do-notation Defining procedure categories is easy enough. How about using them? We develop a quasi-imperative notation8 and implement it using macros. Our notation shares syntax with usual Scala imperative code... ...but has different semantics: it compiles to a circuit of appropriate type instead of being executed immediately. 8 Akin to Haskell’s do-notation, but much easier to use.
  • 55. Procedure Typing for Scala Do-notation Defining procedure categories is easy enough. How about using them? We develop a quasi-imperative notation8 and implement it using macros. Our notation shares syntax with usual Scala imperative code... ...but has different semantics: it compiles to a circuit of appropriate type instead of being executed immediately. Circuit notation for Scala is the topic of the part II... 8 Akin to Haskell’s do-notation, but much easier to use.
  • 56. Procedure Typing for Scala Do-notation Do-notation example ...but here’s a small example to keep your interest Even pure functions have a side effect: they consume time. =>[Future] is an example of a retrofitting procedure category9 . =>[Future] { val a = alpha(x) val b = beta(x) after (a | b) { Log.info("First one is completed") } after (a & b) { Log.info("Both completed") } gamma(a, b) } 9 its reify is a macro, so any procedures can be retrofitted to be =>[Future].
  • 57. Procedure Typing for Scala Do-notation Literature: – The marriage of effects and monads, P. Wadler, P. Thiemann – Generalising monads to arrows, J. Hughes – The Arrow Calculus, S. Lindley, P. Wadler, and J. Yallop – Categorical semantics for arrows, B. Jacobs et al. – What is a Categorical Model of Arrows?, R. Atkey – Parameterized Notions of Computation, R. Atkey – Multi-Level Languages are Generalized Arrows, A. Megacz
  • 58. Procedure Typing for Scala Syntax for Circuitires Part II: Syntax for Circuitires A cup of coffee?
  • 59. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing How do you use an arrow (say f: Logged[Int, String] ) in present Scala code? println(f(5)) seems to be the obvious way, but that’s impossible, application is not defined for f. To facilitate such natural notation, we need implicit unboxing.
  • 60. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing Preliminaries A wrapping is a type F[_] equipped with eval[T](v: F[T]): T and reify[T](expr: => T): F[T] (reify often being a macro) so that eval(reify(x)) ≡ x and reify(eval(x)) ≡ x for all x of the correct type.
  • 61. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing Preliminaries A wrapping is a type F[_] equipped with eval[T](v: F[T]): T and reify[T](expr: => T): F[T] (reify often being a macro) so that eval(reify(x)) ≡ x and reify(eval(x)) ≡ x for all x of the correct type. A prototypical example where reify is a macro is Expr[T]. Example with no macros involved is Future[T] (with await as eval).
  • 62. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing Preliminaries Implicit unboxing is this: whenever a value of the wrapping type F[T] is found where a value of type T is accepted, its eval is called implicitly. In homoiconic languages (including Scala), all expressions can be considered initially having the type Expr[T] and being unboxed into T by an implicit unboxing rule Expr[T] => T .
  • 63. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing Syntax proposal Let’s introduce an instruction implicit[F] enabling implicit unboxing for F in its scope. Implicit contexts can be implemented using macros: – macro augments the relevant scope by F.reify as an implicit conversion from F[T] to T; – F.eval is applied to every occurrence of a symbol having or returning type F[T] which is defined outside of its scope.
  • 64. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing Code that uses futures and promises can be made much more readable by implicit unboxing. An example: dataflows in Akka 2.0. Presently they look like this: flow { z << (x() + y()) if (v() > u) println("z = " + z()) }
  • 65. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing Now this can be recast without any unintuitive empty parentheses: flow { z << x + y if (v > u) println("z = " + z) }
  • 66. Procedure Typing for Scala Syntax for Circuitires Implicit Unboxing Back to our Logged example: implicit[Logged] def example(f: Int =>[Logged] String, n: Int): List[String] { f(n).split(", ") } Which translates to: def example(f: Int =>[Logged] String, n: Int): List[String] { LoggedCircuitryImpl.eval(f)(n).split(", ") }
  • 67. Procedure Typing for Scala Syntax for Circuitires Purifying Scala Now, which procedure category should example() belong to? As it evaluates =>[Logged], it should be =>[Logged] itself. This allows its reinterpretation without any usage of eval: def example(f: Int =>[Logged] String, n: Int): List[String] = { import LoggedCircuitryImpl._ reify{n} andThen f andThen reify{_.split(", ")} } This is now a pure code generating a new circuit of the type =>[Logged] based on the existing one (f) and some pure functions.
  • 68. Procedure Typing for Scala Syntax for Circuitires Purifying Scala Purity Declaration Let’s introduce @pure annotation which explicitly forbids calling any functions with side effects and assignments of foreign variables. This renders the code pure. Procedure with side effects have to be composed by circuit composition operations which are pure. The execution of procedures, which is impure, always lies outside of the scope. All code examples below are to be read as @pure .
  • 69. Procedure Typing for Scala Syntax for Circuitires Purifying Scala Inside of @pure implicit unboxing for arrows becomes implicit circuit notation, which is operationally indistinguishable, but semantically different.
  • 70. Procedure Typing for Scala Syntax for Circuitires Circuit notation Circuit notation, general idea: – write circuitry type like =>[X] in front of a braced code block; – the code block will be reinterpreted as a circuitry of the given type (via macros).
  • 71. Procedure Typing for Scala Syntax for Circuitires Circuit notation Example: =>[Logged] { f(x) + g(x) } Result: (reify{x} andThen reify(dup) andThen (f affix g) andThen reify{_ + _})
  • 72. Procedure Typing for Scala Syntax for Circuitires Circuit notation In presence of implicit[X] every free braced block {...} which uses external symbols of the type =>[X] should be treated as =>[X] {...} , an implicit form of circuit syntax.
  • 73. Procedure Typing for Scala Syntax for Circuitires Circuit notation The desugaring rules producing operationally indistinguishable circuits from imperative-style code blocks are quite complicated, but certainly doable. To make the other direction possible, we need an additional operator: after .
  • 74. Procedure Typing for Scala Syntax for Circuitires Circuit notation Consider two arrows f: Unit => Unit and g: Unit => Unit . They can be composed in two ways: f affix g (out-of-order) and f andThen g (in-order). affix in circuit notation will obviously look like f; g , though for andThen we need some new syntax: =>[Future] { val n = f after(n) g }
  • 75. Procedure Typing for Scala Syntax for Circuitires Circuit notation Without after , =>[Future] and other similar circuitries respect only dataflow ordering, but ignore the order of independent effects (e.g. writing into a log). By combining usual imperative notation and after , any possible circuit configurations can be achieved.
  • 76. Procedure Typing for Scala Syntax for Circuitires Circuit notation Now the example stated above is fully understandable: =>[Future] { val a = alpha(x) val b = beta(x) after (a | b) { Log.info("First one is completed") } after (a & b) { Log.info("Both completed") } gamma(a, b) } ( after trivially supports any combinations of ands and ors.)
  • 77. Procedure Typing for Scala Syntax for Circuitires Circuit notation Blocks as Objects For the sake of composability, blocks should be treated as anonymous classes extending their arrow type: =>[Future] { val result = { @expose val partialResult = compute1(x) compute2(partialResult) } after (result.partialResult) { Log.info("Partial result ready") } } The result in the after context is not just =>[Future] Int , but its anonymous descendant with a public member partialResult .
  • 78. Procedure Typing for Scala Syntax for Circuitires Circuit notation Of course, it should also work for named blocks: def lengthyComputation(x: Double): Double = { var _progress = 0.0 // goes from 0.0 to 1.0 @expose def progress = _progress // public getter ... // _progress is updated when necessary } val f = future someLengthyCalculation(x) while (!f.isDone) { Log.info("Progress: " + f.progress) wait(500 ms) } (This is a perfect example of what can easily be done with macros.)
  • 79. Procedure Typing for Scala Syntax for Circuitires Circuit notation The exact desugaring rules are quite complex (but perfectly real). We hope these examples gave you some insight how everything might work. Thank you!