Dissect the syntax through an example • A casual discussion about the type system 2. Introducing Universal Class Morphing • A walk through the idea via examples, examples, examples 3. Research challenges University of Athens 2 5/7/2015
is checked for errors at compile time. modular: the meta-program is parameterized. Will it work for any class? meta-programming: generate class declarations University of Athens 4 5/7/2015
<R, Y*>[meth] for (R meth (Y) : X.methods) R meth (Y a) { R r = super.meth(a); print("Returned: " + r); return r; } } University of Athens 5 5/7/2015 generate methods with this body
orderItemsInCart (Cart cart) { Order r = super.meth(cart); print("Returned: " + r); return r; } public Order orderItems (List<Items> items) { Order r = super.meth(items); print("Returned: " + r); return r; } } generated University of Athens 7 5/7/2015
reflective declaration may produce conflicting declarations • Identify references to members that may exist reflectively University of Athens 8 5/7/2015
for (T n(int) : Y.methods) T n (int s) { print (“number arg: " + s); return loggedY.n(s); } } class Logging<class X> extends X { <R, Y*>[meth] for (R meth (Y) : X.methods) R meth (Y a) { … } } will this method lookup succeed? <T>[n] for (T n(int) : Y.methods) <R, Y*>[meth] for (R meth (Y) : X.methods) University of Athens 9 5/7/2015
methods/fields only? • Introducing pattern-matching over types. E.g., • for all classes of a module, create new classes that morph over the original ones • for all supertypes of a class, create new ones that… • for all nested classes of a class that support a certain interface, create subclasses that… • (mixin layers++) • for all classes in a set, add a new supertype to them • All with modular type safety! University of Athens 12 5/7/2015
fields) <T>[n] for (public T n(String) : Y.methods ) public T n (String s) • jUCM aims to introduce patterns over classes <C, S> for (C extends S : L.classes) static class C { … } University of Athens 13 5/7/2015
a hierarchy? class Library { static class Vector { boolean isEmpty() {} } static class Stack extends Vector { } } class Library { static class Vector { boolean isEmpty() {} } static class Stack { Vector subobject; boolean isEmpty() { subobject.isEmpty(); } } } we have this we want to generate this University of Athens 14 5/7/2015
a hierarchy? class Delegate<class L> { <C, S> for (C extends S : L.classes) static class C { S subobject#S; <R, A*> [m] for(public R m(A) : S.methods) R m(A a) { return subobject#S.m(a); } } } for all classes in any L introduce a class with the same name delegate calls University of Athens 15 5/7/2015 /w a sub field
<class X> { [N] for (N : X.classes) static class N extends X.N implements Alert { [m] for(public void m () : X.N.methods) public void m() { alert(); super.m(); } void alert() { print("Alerted!"); } } } introduce a new interface for all classes in any class X make all classes implement this interface call alert in all void methods University of Athens 16 5/7/2015
al., SYB paper) data Company = C [Dept] data Dept = D Name Manager [SubUnit] data SubUnit = PU Employee | DU Dept data Employee = E Person Salary data Person = P Name Address data Salary = S Float type Manager = Employee type Name = String type Address = String University of Athens 17 5/7/2015
class Hierarchy { abstract class Company {} static class C extends Company { List<Dept> departments; } abstract class Dept {} static class D extends Dept { String name; Employee manager; List<SubUnit> subUnits; } abstract class SubUnit {} static class PU extends SubUnit { Employee employee; } static class DU extends SubUnit { Dept department; } abstract class Employee {} static class E extends Employee { Person person; Salary salary; } abstract class Person {} static class P extends Person { Name name; Address address; } abstract class Salary {} static class S extends Salary { Float data; } } University of Athens 18 5/7/2015
• An interface CompanyVisitor that contains all visit* variants • The same classes implementing the corresponding interface + the appropriate accept methods. class Hierarchy { abstract class Company {} static class C extends Company { List<Dept> departments; } abstract class Dept {} static class D extends Dept { String name; Employee manager; List<SubUnit> subUnits; } abstract class SubUnit {} static class PU extends SubUnit { Employee employee; } static class DU extends SubUnit { Dept department; } abstract class Employee {} static class E extends Employee { Person person; Salary salary; } abstract class Person {} static class P extends Person { Name name; Address address; } abstract class Salary {} static class S extends Salary { Float data; } } interface CompanyElement { <R> void accept(CompanyVisitor<R> visitor); } interface CompanyVisitor<R> { R visitC(C c); R visitD(D d); R visitPU(PU pu); R visitDU(DU du); R visitE(E e); R visitP(P p); R visitS(S s); } abstract static class Company implements CompanyElement { } static class C extends Company { List<Dept> departments; public <R> void accept(CompanyVisitor<R> visitor) { visitor.visitC(this); } } abstract static class Dept implements CompanyElement { } static class D extends Dept { String name; Employee manager; List<SubUnit> subUnits; public <R> void accept(CompanyVisitor<R> visitor) { visitor.visitD(this); } } abstract static class SubUnit implements CompanyElement { } static class PU extends SubUnit { Employee employee; public <R> void accept(CompanyVisitor<R> visitor) { visitor.visitPU(this); } } static class DU extends SubUnit { Dept department; public <R> void accept(CompanyVisitor<R> visitor) { visitor.visitDU(this); } } abstract static class Employee implements CompanyElement { } static class E extends Employee { Person person; Salary salary; public <R> void accept(CompanyVisitor<R> visitor) { visitor.visitE(this); } } abstract static class Person implements CompanyElement { } static class P extends Person { Name name; Address address; public <R> void accept(CompanyVisitor<R> visitor) { visitor.visitP(this); } } abstract static class Salary implements CompanyElement { } static class S extends Salary { float data; public <R> void accept(CompanyVisitor<R> visitor) { visitor.visitS(this); } } clean hierarchy with traversable code University of Athens 19 5/7/2015
definitions class VisitableHierarchy { [N] for(abstract static N : Hierarchy.classes) abstract static class N implements CompanyElement { } <T> [N] for(static N extends T : Hierarchy.classes) static class N extends Hierarchy.N { public <R> void accept(CompanyVisitor<R> visitor){ visitor.visit#E(this); } } } interface CompanyVisitor<R> { <M extends Object> [C] for (C extends M : Hierarchy.classes) R visit#C(C e); } 1) 2) University of Athens 20 5/7/2015
• Will type checking stay sound? • Are the semantics of morphJ really pluggable with jUCM? • Separate compilation? • Worth exploring related work: • F# static generics • TASTY-like format introduced for serialization of typed information for metaclasses. University of Athens 21 5/7/2015
position paper: http://arxiv.org/abs/1506.05270 • Original paper for Morphing: Structurally shaping a class by reflecting on others University of Athens 22 5/7/2015
generation ranges of declarations or references • Set-theoretic reasoning • Disjoint ranges mean non-conflicting declarations • Containing ranges mean that a reference is valid University of Athens 24 5/7/2015
class DisjointDecs<class X> { <R>[m] for(R m (int) : X.methods) R m (int i) { ... } <S> [n] for(S n (int) : X.methods) S n (int i, String s) { ... } } University of Athens 25 5/7/2015
are employed to check the reflection conditions for exclusivity class StillUnique<class X> { <A1>[m]for(String m (A1) : X.methods) void m (A1 a) { ... } <A2>[n]for(int n (A2) : X.methods) void n (A2 a) { ... } } University of Athens 26 5/7/2015