Semantic Modularity for DSLs Bruno C. d. S. Oliveira The University of Hong Kong
Can you give a 35m talk on Domain- specific type systems using Object Algebras?
Sure!
That should be easy I know Object Algebras well!
Humm… Wait a minute! How about domain-specific type systems?
A little twist on Sebastian’s invitation • How to use type systems to develop: • modular • reusable • separately compilable • and type-safe (of course!) DSL components
My work • Lots of mentions to composition/modularity this week. • Highly overload term • My work is primarily on semantic modularity • Not syntax/parser modularity • Not syntactic modularity
DSL Components
Syntactic (AST) Components Logic Arithmetic true, false, 1,3+4,5*6 if true then false else true Binding Graphics \x . x, \x . (\y . y) x point(3,4), scale(2,point(4,5))
Semantic Components Pretty Printing Evaluation pp (x+y) -> [x+y] -> [x] + [y] pp x + “ + “ + pp y Type-checking tcheck (n) -> Int
Syntactic Compositions Arithmetic + Logic + Binding \x . if x then x+1 else x Arithmetic + Binding + Graphics \x y. point(10+x, point 10 + y)
Semantic Compositions Evaluation + Type- Checking [x+y] -> [x] + [y] Evaluation + Pretty Printing tcheck (n) -> Int [x+y] -> [x] + [y] pp (x+y) -> pp x + “ + “ + pp y
The Matrix
The Matrix Arithmetic Logic Binding Graphics [point(e1,e2)] Evaluation [n] -> n [true] -> true [x] = x = … Type- tc(true) tc(x,e) -> tc(point(e1,e2)) tc(n) -> Int Checking -> Bool lookup(x,e) -> Point Pretty- pp(n) -> pp(true) -> pp(point(e1,e2 pp(x) = x Printing n.toString true.toString )) = …
How to Program such Components? Meta-Programming Casts Reflection Superimposition Dynamic Languages
How to Program such Components/Compositions? • How about: • Type-safety ? absence of pattern matching and/or messageNotUnderstood errors; safe composition • IDE support (code completion, refactoring,…)? • Separate Compilation ? • Maintainability ? • We would like to program such components modularly while still having all of the above !
The Matrix Each cell can be viewed as a separate module! Arithmetic Logic Binding Graphics Each Module should allow for: • Static type-checking [point(e1,e2)] • Separate compilation Evaluation [n] -> n [true] -> true [x] = x = … Each composition should ensure Type- tc(true) tc(x,e) -> tc(point(e1,e2)) that interpretations handle all tc(n) -> Int Checking -> Bool lookup(x,e) -> Point cases Pretty- pp(n) -> pp(true) -> pp(point(e1,e2 pp(x) = x Printing n.toString true.toString )) = …
The Matrix The Expression Problem! Arithmetic Logic Binding Graphics [point(e1,e2)] Evaluation [n] -> n [true] -> true [x] = x = … Type- tc(true) tc(x,e) -> tc(point(e1,e2)) tc(n) -> Int Checking -> Bool lookup(x,e) -> Point Pretty- pp(n) -> pp(true) -> pp(point(e1,e2 pp(x) = x Printing n.toString true.toString )) = …
Object Algebras
Object Algebras • Lightweight technique (a design pattern) to solve the Expression Problem and various other (semantic) modularity issues. • In their basic form, they work on common OO languages (Java, C#, Scala, …) • Inspired by type-theoretic encodings of datatypes
Theory • Object Algebra interfaces are simply algebraic signatures of some primitive built-in sorts signature E lit: Int → E add: E × E → E A general algebraic sign • From an OO point to view they can be viewed both as: • (Internal) Visitor interfaces • Generic Abstract Factory Interfaces
Extensibility interface IntAlg<A> { A lit( int x); A add(A e1, A e2); } interface IntBoolAlg<A> extends IntAlg<A> { A bool(Boolean b); A iff(A e1, A e2, A e3); } Extensibility!
Demo
Uses of Object Algebras • Batch Script Language interface BatchFactory<E> { E Var(String name); // variable reference E Data(Object value); // simple constant (number, string, or date) E Fun(String var , E body); E Prim(Op op, List<E> args); // unary and binary operators E Prop(E base, String field); // field access E Assign(Op op, E target, E source); // assignment E Let(String var , E expression, E body); // control flow E If(E condition, E thenExp, E elseExp); E Loop(Op op, String var , E collection, E body); E Call(E target, String method, List<E> args); // method invocation E In(String location); // reading and writing forest E Out(String location, E expression); } Fig. 13. Batch script language abstract syntax Oliveira and Cook, Extensibility for the Masses: Practical Extensibility with • Object Algebras, ECOOP (2012)
Uses of Object Algebras • Batch Script Language interface PartitionFactory<E> extends BatchFactory<E> { E Other(Object external, E... subs); E DynamicCall(E target, String method, List<E> args); E Mobile(String type, Object obj, E exp); } Oliveira and Cook, Extensibility for the Masses: Practical Extensibility with • Object Algebras, ECOOP (2012)
Uses of Object Algebras • One-pass Modular (subset of) C compiler long some_function () ; /* int */ other_function () ; /* int */ calling_function () { long test1 ; register /* int */ test2 ; test1 = some_function () ; if ( test1 > 0 ) test2 = 0 ; else test2 = other_function () ; return test2 ; } • Rendel et al., From Object Algebras to Attribute Grammars , OOPSLA (2014)
Uses of Object Algebras • QL Language with Object Algebras form HouseOwning { soldHouse : "Did you sell a house?" boolean boughtHouse : "Did you buy a house?" boolean if (soldHouse) { sellingPrice : "Selling price : " integer privateDebt : "Private debts : " integer valueResidue : "Value residue : " integer = (sellingPrice - privateDebt) } } Gouseti et al., Extensible Language Implementation with Object Algebras, • GPCE (2014)
Uses of Object Algebras • Streams a la Carte int sum = widgets.stream() .filter(b -> b.getColor() == RED) .mapToInt(b -> b.getWeight()) .sum(); Biboudis et al. , Streams à la carte. Extensible Pipelines with Object Algebras. • submitted
Some Work on Object Algebras • First paper Oliveira and Cook, Extensibility for the Masses: Practical Extensibility with • Object Algebras , ECOOP (2012) • Increasing the expressive power of object algebras: Oliveira et al., Feature-Oriented Programming with Object Algebras , • ECOOP (2013) Rendel et al., From Object Algebras to Attribute Grammars , OOPSLA • (2014) • Domain-Specific Languages Gouseti et al., Extensible Language Implementation with Object Algebras, • GPCE (2014) Biboudis et al. , Streams à la carte. Extensible Pipelines with Object • Algebras. submitted
Pre-History of Object Algebras • Church Encodings of Datatypes as (Haskell) Type Classes Hinze, Generics for the Masses , ICFP (2004) and JFP (2006) • Oliveira and Gibbons, TypeCase: A Design Pattern for Type-Indexed Functions , HW • (2005) • Extensibility: Solving the Expression Problem (Haskell) Oliveira et al., Extensible and Modular Generics for the Masses , TFP (2006) • • Applications to Embedded DSLs (Haskell & Scala) • Carrete et al., Finally tagless, partially evaluated: Tagless staged interpreters for simpler typed languages , APLAS (2007) & JFP (2009) • Hofer et al., Polymorphic Embedding of DSLs , GPCE (2008) • Rompf and Odersky, Lightweight Modular Staging , GPCE (2010) • Modular Visitors & Church Encodings (Scala) Oliveira et al., The Visitor Pattern as a Reusable Type-Safe Component , OOPSLA • (2008) • Oliveira, Modular Visitor Components , ECOOP (2009 )
Structure-Shy Components
Semantic Components FreeVars Substitution fv(e1+e2) -> fv(e1) + [x -> e] (e1+e2) -> + fv(e2) [x -> e] e1+ [x -> e] e2
The Matrix Arithmetic Logic Binding Graphics FreeVars Boring! Boring! Interesting! Boring! Substitution Boring! Boring! Interesting! Boring!
Recommend
More recommend