280 likes | 413 Views
The Genamics P rojec t. – the interaction between generics and dynamics – Peter Achten, Ralf Hinze. Outline. Context & motivation The Genamics Project generic functions for labelled state transition systems dynamic instance creation of generic functions Conclusions.
E N D
The Genamics Project – the interaction between generics and dynamics – Peter Achten, Ralf Hinze
Outline • Context & motivation • The Genamics Project • generic functions for labelled state transition systems • dynamic instance creation of generic functions • Conclusions The Genamics Project
Context & motivation • Functional I/O; GUIs; Clean Object I/O • Programmer’s skill level: • higher-order functions, algebraic types (basic) • algebraic type constructors (bit advanced) • type constructor classes (advanced) • Object I/O library (cope with ‘large’ library) The Genamics Project
Context & motivation (2) • Essential features of Object I/O: • GUI objects are described by data structures • Compositional to form more complex objects • DSL: language elements (data types) + glue rules (type constructor classes + instances) • Labelled state transition system (initial state values & higher order functions) The Genamics Project
Context & motivation (3) • Visual Editors (VE) provide mental metaphore for constructing GUIs • Constructed GUIs stored as resource • persistent • application independent • usually contain no code • separate development/enhancement (modular) The Genamics Project
Context & motivation (4) • Support for GUIs requires VE • Functional features to offer: • Static and dynamic typing • Higher-order functions • Abstraction (generic programming) • The Genamics project The Genamics Project
The Genamics project • Genamic = generic & dynamic • Dynamic types: serialise GUI resources • Generic functions: manipulate GUI resources • Results: • generic functions can manipulate labelled state systems. • generic functions strengthen dynamics The Genamics Project
Labelled state transition systems • Systems S1, S2, S3. • Generic functions eval, param. • Polykinded types approach by Hinze. The Genamics Project
System S1: actions • Behaviours are actions: *World *World • Equivalent with Haskell Object I/O: • state in MVars • monadic actions: IO (). The Genamics Project
S1 – DSL data Obj obj = Obj Int (Id (W ())) obj type Id x = x x type W st = (st, *World) instance S1 () instance (S1 s) S1 (Obj s) instance (S1 s1,S1 s2) S1 (s1,s2) The Genamics Project
S1 – eval Eval k:: :: k Eval t = t Int Id (W ()) Eval k1k2 t = x . Eval k1x Eval k2 (t x) eval t::k :: Eval k t eval 1 () _ = id eval ea eb (a,b) nr = eb b nr ea a nr eval + ea eb (Inl a) nr = ea a nr eval + ea eb (Inr b) nr = eb b nr eval Obj ea (Obj nr’ io a) nr = if nr’==nr then io else ea a nr The Genamics Project
S1 – example: actions • Example program: Start :: *World -> *World Start w = case readDynamic “obj.dyn” w of (True,obj :: (eval t) t, w) eval obj 1 w _ w • Dynamic object in “obj.dyn”: dynamic ( Obj 0 (print “Hi there.”) () , Obj 2 (print “Goodbye”) ( Obj 1 (print “Hello world”) ()) ) :: (Obj (), Obj (Obj ())) The Genamics Project
System S2: global state • System manages public state ps • Behaviours: (ps,*World) (ps,*World) • Objects: data Obj obj ps = Obj Int (Id (W ps)) (obj ps) • Polykinded type scheme fails: Eval k1k2 t = x . Eval k1x Eval k2 (t x) • Solution: lift kind level of equations = (k1k2) = (k1) (k2) The Genamics Project
S2 – DSL data Obj obj ps = Obj Int (Id (W ps)) (obj ps) infixr 9 :~: data :~: a b ps = (a ps) :~: (b ps) data NilCS ps = NilCS instance S2NilCS instance (S2 s) S2 (Obj s) instance (S2 s1,S2 s2) S2 (:~: s1 s2) The Genamics Project
S2 – eval Evalpsk:: :: k Evalps t = t ps Int Id (W ps) Evalps(k1k2 ) t = x . Evalpsk1x Evalpsk2 (t x) eval t :: k :: ps . Evalps k t eval NilCSNilCS _ = id eval :~: ea eb (a :~: b) nr = eb b nr ea a nr eval + ea eb (InlCS a) nr = ea a nr eval + ea eb (InrCS b) nr = eb b nr eval Obj ea (Obj nr’ io a) nr = if nr’==nr then io else ea a nr The Genamics Project
S2 – example: global counter • Example program: Start :: *World -> *World Start w = case readDynamic “obj.dyn” w of (True,(st,obj) :: (eval t) (ps,t ps), w) snd (eval obj 1eval obj 0 eval obj 1 (st,w)) _ w • Dynamic object in “obj.dyn”: dynamic ( 1000, Obj 0 (l(c,w) (c+1,w)) () :~: Obj 2 (l(c,w) (c-1,w)) ( Obj 1 (l(c,w) (c, print (show c) w)) ()) ) :: (Int, :~: (Obj ()) (Obj (Obj ()) Int) The Genamics Project
System S3: local & global state • System manages local and public state • Equivalent with Clean Object I/O • Objects: data Obj obj ls ps = Obj Int (Id (W (ls,ps))) (obj ls ps) • Lift kind level of equations once more = (k1k2) = (k1) (k2) • Hierarchy of stateful objects The Genamics Project
S3 – DSL data Obj obj ls ps = Obj Int (Id (W (ls,ps))) (obj ls ps) data NewLS obj ls ps = new . NewLS new (obj new ps) data AddLS obj ls ps = add . AddLS add (obj (add,ls) ps) infixr 9 :+: data :+: a b ls ps = (a ls ps) :+: (b ls ps) data NilLS ls ps = NilLS instance S3 NilLS instance (S3 s) S3 (Obj s) instance (S3 s1,S3 s2) S3 (:+: s1 s2 ) instance (S3 s) S3 (NewLS s) instance (S3 s) S3 (AddLS s) The Genamics Project
S3 – eval eval :: (S3 obj) Int Id (W (ps,obj () ps)) eval nr ((ps, obj), w) = let (obj’, ((_,ps’), w’)) = eval’ obj nr (((),ps),w) in ((ps’,obj’),w’) Eval’(ls,ps)k:: :: k Eval’(ls,ps) t = t ls ps Int W (ls,ps) (t ls ps,W (ls,ps)) Eval’(ls,ps)(k1k2 ) t = x . Eval’(ls,ps)k1x Eval’(ls,ps)k2 (t x) eval’ t :: k :: ls . ps . Eval’(ls,ps) k t The Genamics Project
S3 – eval (2) Eval’(ls,ps) t = t ls ps Int W (ls,ps) (t ls ps,W (ls,ps)) eval’ t :: k :: ls . ps . Eval’(ls,ps) k t eval’ NilLS NilLS _ wst = (NilLS,wst) eval’ :+: ea eb (a :+: b) nr wst = let (a',wst') = ea a nr wst (b',wst'') = eb b nr wst in (a' :+: b', wst'') eval’ + ea eb (InlLS a) nr wst = let (a',wst') = ea a nr wst in (InlLS a',wst') eval’ + ea eb (InrLS b) nr wst = let (b',wst') = eb b nr wst in (InrLS b',wst') The Genamics Project
S3 – eval (3) Eval’(ls,ps) t = t ls ps Int W (ls,ps) (t ls ps,W (ls,ps)) eval’ t :: k :: ls . ps . Eval’(ls,ps) k t eval’ Obj ea (Obj nr’ io a) nr ((ls,ps),w) = if nr’==nr thenlet ((ls’,ps’),w’) = io ((ls,ps),w) in (((ls’,ps’),Obj nr’ io a), w’) elselet (a’,((ls’,ps’),w’)) = ea a nr ((ls,ps),w) in (((ls’,ps’),Obj nr’ io a’), w’) eval’ NewLS ea (NewLS new a) nr ((ls,ps),w) = let (a’,((new’,ps’),w’)) = ea a nr ((new,ps),w) in (((ls,ps’),NewLS new’ a’), w’) eval’ AddLS ea (AddLS add a) nr ((ls,ps),w) = let (a’,(((add’,ls’),ps’),w’)) = ea a nr (((add,ls),ps),w) in (((ls’,ps’),AddLS add’ a’), w’) The Genamics Project
S3 – example: local counter • Example program: Start :: *World -> *World Start w = case readDynamic “obj.dyn” w of (True,obj :: (eval’ t) t ls ps, w) snd (eval 1eval 0 eval 1 (((),obj),w) _ w • Dynamic object in “obj.dyn”: dynamic ( NewLS 1000 (Obj 0 (l(c,w) (c+1,w)) () :+: Obj 2 (l(c,w) (c-1,w)) ( Obj 1 (l(c,w) (c, print (show c) w)) ()) ) ::NewLS (:+: (Obj ()) (Obj (Obj ()))) ls ps The Genamics Project
Labelled state transition systems • Conclusions: • Generic functions can be written for data structures equivalent with Clean Object I/O • Requires kind lifting in polykinded equations The Genamics Project
Dynamic generics • Generic function is defined for all types • Instances resolved at compile-time • For dynamic values resolve at run-time The Genamics Project
Dynamic generics (2) Module M, options O, paths P, scope S: unwrap :: Dynamic t' unwrap ( dyn :: (F a) t) = expr Suppose offered type t. • Unify t with t, yields substitution *. • Derive kind of a* = k. • Generate f a* :: k :: F k a*. • Create module M' with name(M') = name(M)name(f)name(a*), content f a* :: k :: F k a*, and scope S. • Compile M' with options O and paths P M'.abc, M'.obj. • Dynamically link name(M')._name(f) for occurences of f in expr. The Genamics Project
Dynamic generics (3) Module M, options O, paths P, scope S: wrap :: Dynamic wrap = dynamic g :: G k t Suppose demanded type t. • Unify t with G t, yields substitution * (or ()()). • Derive kind of t* = k. • Generate g t* :: k :: G kt*. • Create module M'' with name(M'') = name(M)name(g)name(t*), content g t* :: k :: G kt*, and scope S. • Compile M'' with options O and paths P M''.abc, M''.obj. • Dynamically link name(M'')._name(g) for occurences of g in expr. The Genamics Project
Dynamic generics (4) • Advantages: • reuse compiler components (kind inference, generic instantiation, modular compilation, dynamic linking) • Disadvantages: • many temporary files • duplicate code, different scopes • inefficient The Genamics Project
Conclusions (work to do) • Generic functions can be written for Object I/O-like data structures (should be tested) • For this we need kind lifting (should be generalised) • Run-time creation of generic instances for dynamic values seems feasible (build prototype) The Genamics Project