trait Alg[ T ] { Final Embedding def Lit( n : Int): T def Add( l : T , r : T ): T } trait Exp { def fold[T](alg: Alg[T]): T } def Lit( n : Int) = new Exp { def fold[ T ]( alg : Alg[ T ]) = alg .lit( n ) } def Add( l : Exp, r : Exp) = new Exp { def fold[ T ]( alg : Alg[ T ]) = alg .Add( l .fold( alg ), r .fold( alg )) } 11/42
To study the relationship of embedding approaches, we should study defunctionalization and refunctionalization 12/42
To study the relationship of embedding approaches, we should study defunctionalization and refunctionalization (for Scala-ish languages?!) 12/42
Modular, Scalable, and Compositional Encoding (of Attribute Grammars in Scala) Rendel, Brachthäuser, Ostermann 2014 (From Object Algebras to ...) 13/42
Two Dimensions of Modularity constructors consumer 14/42
Third Dimension of Modularity To scale to large programs, solutions to the expression problem need to support components with inner structure: ● Consumers that depend on other consumers. ● Consumers that depend on context information. ● Consumers that are fused together. 15/42
Bottom-Up Data Flow 16/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Synthesized Attributes Grammar Equations e 0 → n { Lit } e 0. value = n e 1 → e 2 "+" e 3 { Add } e 1 .value = e 2 .value + e 3 .value Signature Algebra trait Sig[ E ] { val Alg = new Sig[Int] { ⇒ E def Lit = n ⇒ def Lit: Int n def Add: ( E , E ) ⇒ def Add = ( e 2 , e 3 ) ⇒ E e 2 + e 3 } } 17/42
Top-Down Data Flow 18/42
Inherited Attributes Grammar Equations e 0 → n { Lit } e 2 . left = true e 1 → e 2 "+" e 3 { Add } e 3 .left = false Signature Algebra trait Sig[ E ] { val Alg = new Sig[Bool] { ⇒ E def Add 1 = e ⇒ def Add 1 : E true def Add 2 : ( E , E ) ⇒ def Add 2 = ( e 1 , e 2 ) ⇒ E false } } 19/42
Inherited Attributes Grammar Equations e 0 → n { Lit } e 2 . left = true e 1 → e 2 "+" e 3 { Add } e 3 .left = false Signature Algebra trait Sig[ E ] { val Alg = new Sig[Bool] { ⇒ E def Add 1 = e ⇒ def Add 1 : E true def Add 2 : ( E , E ) ⇒ def Add 2 = ( e 1 , e 2 ) ⇒ E false } } 19/42
Inherited Attributes Grammar Equations e 0 → n { Lit } e 2 . left = true e 1 → e 2 "+" e 3 { Add } e 3 .left = false Signature Algebra trait Sig[ E ] { val Alg = new Sig[Bool] { ⇒ E def Add 1 = e ⇒ def Add 1 : E true def Add 2 : ( E , E ) ⇒ def Add 2 = ( e 1 , e 2 ) ⇒ E false } } 19/42
Inherited Attributes Grammar Equations e 0 → n { Lit } e 2 . left = true e 1 → e 2 "+" e 3 { Add } e 3 .left = false Signature Algebra trait Sig[ E ] { val Alg = new Sig[Bool] { ⇒ E def Add 1 = e ⇒ def Add 1 : E true def Add 2 : ( E , E ) ⇒ def Add 2 = ( e 1 , e 2 ) ⇒ E false } } 19/42
Inherited Attributes Grammar Equations e 0 → n { Lit } e 2 . left = true e 1 → e 2 "+" e 3 { Add } e 3 .left = false Signature Algebra trait Sig[ E ] { val Alg = new Sig[Bool] { ⇒ E def Add 1 = e ⇒ def Add 1 : E true def Add 2 : ( E , E ) ⇒ def Add 2 = ( e 1 , e 2 ) ⇒ E false } } 19/42
Inherited Attributes Grammar Equations e 0 → n { Lit } e 2 . left = true e 1 → e 2 "+" e 3 { Add } e 3 .left = false Signature Algebra trait Sig[ E ] { val Alg = new Sig[Bool] { ⇒ E def Add 1 = e ⇒ def Add 1 : E true def Add 2 : ( E , E ) ⇒ def Add 2 = ( e 1 , e 2 ) ⇒ E false } } 19/42
Composition 20/42
Composition compose 20/42
Composition compose 20/42
Composition assemble 20/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[Mix[A, B]] = { ... 21/42
compose( , ) = Extensible Records trait HasValue { def value: Int } trait HasLeft { def left: Bool } def mix[ A , B ]( implicit m: Mix[A, B]): ( A , B ) ⇒ A with B Implicit Macros implicit def mixAll[A, B]: Mix[A, B] = macro impl[A, B] def impl[A, B](c: Context)(implicit aT: c.WeakTypeTag[A], bT: c.WeakTypeTag[B]): c.Expr[ Mix [A, B]] = { ... 21/42
compose( , ) = Dependency Tracking trait Sig[- E , - C , + O ] { ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } 22/42
compose( , ) = Dependency Tracking trait Sig[- E , - C , + O ] { ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } 22/42
compose( , ) = Dependency Tracking trait Sig[- E , - C , + O ] { current node ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } 22/42
compose( , ) = Dependency Tracking trait Sig[- E , - C , + O ] { current node ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } children 22/42
compose( , ) = Dependency Tracking context from parent trait Sig[- E , - C , + O ] { current node ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } 22/42
compose( , ) = Dependency Tracking trait Sig[- E , - C , + O ] { current node ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } 22/42
compose( , ) = Dependency Tracking trait Sig[- E , - C , + O ] { ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } 22/42
compose( , ) = Dependency Tracking trait Sig[- E , - C , + O ] { ⇒ C ⇒ def Lit: Int O def Add: ( E , E ) ⇒ C ⇒ O } 22/42
compose( , ) = Composing two algebras def compose [E 1 , C 1 , O 1 , E 2 , C 2 >: C 1 with O 1 , O 2 ] (alg 1 : Sig[E 1 , C 1 , O 1 ], alg 2 : Sig[E 2 , C 2 , O 2 ]): Sig[E 1 with E 2 , C 1 , O 1 with O 2 ] 23/42
compose( , ) = Composing two algebras def compose [E 1 , C 1 , O 1 , E 2 , C 2 >: C 1 with O 1 , O 2 ] (alg 1 : Sig[E 1 , C 1 , O 1 ], alg 2 : Sig[E 2 , C 2 , O 2 ]): Sig[E 1 with E 2 , C 1 , O 1 with O 2 ] 23/42
compose( , ) = Composing two algebras def compose [E 1 , C 1 , O 1 , E 2 , C 2 >: C 1 with O 1 , O 2 ] (alg 1 : Sig[E 1 , C 1 , O 1 ], alg 2 : Sig[E 2 , C 2 , O 2 ]): Sig[E 1 with E 2 , C 1 , O 1 with O 2 ] 23/42
compose( , ) = Composing two algebras def compose [E 1 , C 1 , O 1 , E 2 , C 2 >: C 1 with O 1 , O 2 ] (alg 1 : Sig[E 1 , C 1 , O 1 ], alg 2 : Sig[E 2 , C 2 , O 2 ]): Sig[E 1 with E 2 , C 1 , O 1 with O 2 ] 23/42
compose( , ) = Composing two algebras def compose [E 1 , C 1 , O 1 , E 2 , C 2 >: C 1 with O 1 , O 2 ] (alg 1 : Sig[E 1 , C 1 , O 1 ], alg 2 : Sig[E 2 , C 2 , O 2 ]): Sig[E 1 with E 2 , C 1 , O 1 with O 2 ] 23/42
compose( , ) = Composing two algebras def compose [E 1 , C 1 , O 1 , E 2 , C 2 >: C 1 with O 1 , O 2 ] (alg 1 : Sig[E 1 , C 1 , O 1 ], alg 2 : Sig[E 2 , C 2 , O 2 ]): Sig[E 1 with E 2 , C 1 , O 1 with O 2 ] 23/42
Recommend
More recommend