Ornaments in ML. Thomas Williams, Didier Rémy. April 18, Inria - Gallium

Similar documents
GADTs meet Subtyping

Ornaments in Practice

Tracing Ambiguity in GADT Type Inference

Combining Programming with Theorem Proving

Ornaments in Practice

Programming Languages Lecture 15: Recursive Types & Subtyping

COS 320. Compiling Techniques

Programming Languages Lecture 14: Sum, Product, Recursive Types

IA014: Advanced Functional Programming

On the Logical Foundations of Staged Computation

Simple Unification-based Type Inference for GADTs

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

TYPE INFERENCE. François Pottier. The Programming Languages Mentoring ICFP August 30, 2015

GADTs. Alejandro Serrano. AFP Summer School. [Faculty of Science Information and Computing Sciences]

Subtyping. Lecture 13 CS 565 3/27/06

λ calculus is inconsistent

Adding GADTs to OCaml the direct approach

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

COMP 4161 NICTA Advanced Course. Advanced Topics in Software Verification. Toby Murray, June Andronick, Gerwin Klein

Introduction to Functional Programming in Haskell 1 / 56

Programming Languages Assignment #7

Introduction to OCaml

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

CMSC 336: Type Systems for Programming Languages Lecture 5: Simply Typed Lambda Calculus Acar & Ahmed January 24, 2008

Introduction to System F. Lecture 18 CS 565 4/20/09

Flang typechecker Due: February 27, 2015

Programming Languages

Lists. Michael P. Fourman. February 2, 2010

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

TRELLYS and Beyond: Type Systems for Advanced Functional Programming

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Recap: ML s Holy Trinity

Types and Programming Languages. Lecture 5. Extensions of simple types

Programming Languages. Datatypes

Programming Languages. Next: Building datatypes. Suppose I wanted. Next: Building datatypes 10/4/2017. Review so far. Datatypes.

Goal. CS152: Programming Languages. Lecture 15 Parametric Polymorphism. What the Library Likes. What The Client Likes. Start simpler.

Generic polymorphism on steroids

Type Systems. Pierce Ch. 3, 8, 11, 15 CSE

Where is ML type inference headed?

Programming with C Library Functions Safely

4.5 Pure Linear Functional Programming

Dependent types and program equivalence. Stephanie Weirich, University of Pennsylvania with Limin Jia, Jianzhou Zhao, and Vilhelm Sjöberg

Type Checking and Type Inference

Inductive datatypes in HOL. lessons learned in Formal-Logic Engineering

CS 320: Concepts of Programming Languages

The Worker/Wrapper Transformation

Exercise 1 (2+2+2 points)

ATS: a language to make typeful programming real and fun

Recap: ML s Holy Trinity. Story So Far... CSE 130 Programming Languages. Datatypes. A function is a value! Next: functions, but remember.

CSE 130, Fall 2006: Final Examination

CSE 130 Programming Languages. Datatypes. Ranjit Jhala UC San Diego

Structural polymorphism in Generic Haskell

Type assignment for intersections and unions in call-by-value languages

Type structure is a syntactic discipline for maintaining levels of abstraction John Reynolds, Types, Abstraction and Parametric Polymorphism

The design of a programming language for provably correct programs: success and failure

L3 Programming September 19, OCaml Cheatsheet

Typed Lambda Calculus and Exception Handling

CSE 130, Fall 2005: Final Examination

Typed Racket: Racket with Static Types

Programming Languages

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Introduction to ML. Based on materials by Vitaly Shmatikov. General-purpose, non-c-like, non-oo language. Related languages: Haskell, Ocaml, F#,

Lecture #23: Conversion and Type Inference

CSCI-GA Scripting Languages

Theorem Proving Principles, Techniques, Applications Recursion

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

CSE-321 Programming Languages 2012 Midterm

CSE 130 Programming Languages. Lecture 3: Datatypes. Ranjit Jhala UC San Diego

GADTs gone mild. Code at Gabriel RADANNE 23 Mars 2017

Functional Programming and Modeling

Hard deadline: 3/28/15 1:00pm. Using software development tools like source control. Understanding the environment model and type inference.

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Polymorphism. Lecture 19 CS 565 4/17/08

CSE-321 Programming Languages 2011 Final

News. Programming Languages. Recap. Recap: Environments. Functions. of functions: Closures. CSE 130 : Fall Lecture 5: Functions and Datatypes

Exercise 1 ( = 24 points)

Lecture 15 CIS 341: COMPILERS

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Agenda. CS301 Session 11. Common type constructors. Things we could add to Impcore. Discussion: midterm exam - take-home or inclass?

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Exercise 1 ( = 22 points)

CSE-321 Programming Languages 2010 Final

Homework 3 COSE212, Fall 2018

Symmetry in Type Theory

Pattern Matching and Abstract Data Types

An introduction introduction to functional functional programming programming using usin Haskell

Embedding logics in Dedukti

The Typed Racket Guide

CIS 500 Software Foundations. Midterm I. (Standard and advanced versions together) October 1, 2013 Answer key

ML 4 Unification Algorithm

Programming Languages Fall 2014

l e t print_name r = p r i n t _ e n d l i n e ( Name : ^ r. name)

CSE505, Fall 2012, Midterm Examination October 30, 2012

A Simple Supercompiler Formally Verified in Coq

Transformation and Analysis of Haskell Source Code

CS558 Programming Languages

Recap from last time. Programming Languages. CSE 130 : Fall Lecture 3: Data Types. Put it together: a filter function

Programming Languages and Compilers (CS 421)

Design Principles of Programming Languages. Recursive Types. Zhenjiang Hu, Haiyan Zhao, Yingfei Xiong Peking University, Spring Term, 2014

Transcription:

Ornaments in ML Thomas Williams, Didier Rémy Inria - Gallium April 18, 2017 1

Motivation Two very similar functions let rec add m n = match m with Z n S m S (add m n) let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(x,append ml nl) 2

Motivation Two very similar functions let rec add m n = match m with Z n S m S (add m n) let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(x,append ml nl) Coherent add (length ml) (length nl) = length (append ml nl) 2

Naturals and lists Similar types type nat = Z S of nat type α list = Nil Cons of α α list S ( S ( S ( Z ))) Cons(1, Cons(2, Cons(3, Nil))) Projection function let rec length = function Nil Z Cons(x, xs) S(length xs) The relation between nat and α list defines an ornament. 3

Lifting a function let rec add m n = match m with Z n S m S (add m n) 4

Lifting a function let rec add m n = match m with Z n S m S (add m n) let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(x,append ml nl) 4

Lifting a function let rec add m n = match m with Z n S m S (add m n) let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(x,append ml nl) add (length ml) (length nl) = length (append ml nl) 4

Lifting a function let rec add m n = match m with Z n S m S (add m n) let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(x,append ml nl) add (length ml) (length nl) = length (append ml nl) Syntactic lifting: we follow the structure of the original function. 4

Outline Some examples Encoding lifting A meta-language for ornamentation Encoding ornaments in mml 5

add/append again type nat = Z S of nat type α list = Nil Cons of α α list 6

add/append again type nat = Z S of nat type α list = Nil Cons of α α list type ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) 6

add/append again type nat = Z S of nat type α list = Nil Cons of α α list type ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) let rec add m n = match m with Z n S m S (add m n) 6

add/append again type nat = Z S of nat type α list = Nil Cons of α α list type ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) let rec add m n = match m with Z n S m S (add m n) let append = lifting add : _ natlist _ natlist _ natlist 6

add/append again type nat = Z S of nat type α list = Nil Cons of α α list type ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) let rec add m n = match m with Z n S m S (add m n) let append = lifting add : _ natlist _ natlist _ natlist let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(#1, append ml nl) 6

add/append again type nat = Z S of nat type α list = Nil Cons of α α list type ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) let rec add m n = match m with Z n S m S (add m n) let append = lifting add : _ natlist _ natlist _ natlist let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(#1, append ml nl) 6

add/append again type nat = Z S of nat type α list = Nil Cons of α α list type ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) let rec add m n = match m with Z n S m S (add m n) let append = lifting add : _ natlist _ natlist _ natlist with #1 <- (match ml with Cons(x,_) x) let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(#1, append ml nl) 6

add/append again type nat = Z S of nat type α list = Nil Cons of α α list type ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) let rec add m n = match m with Z n S m S (add m n) let append = lifting add : _ natlist _ natlist _ natlist with #1 <- (match ml with Cons(x,_) x) let rec append ml nl = match ml with Nil nl Cons(x,ml ) Cons(x, append ml nl) 6

Refactoring type expr = Const of int Add of expr expr Mul of expr expr type binop = Add Mul type expr = Const of int Binop of binop expr expr 7

Refactoring type expr = Const of int Add of expr expr Mul of expr expr type binop = Add Mul type expr = Const of int Binop of binop expr expr type ornament oexpr : expr expr with Const i Const i Add(u, v) Binop (Add, u, v) Mul(u, v) Binop (Mul, u, v) 7

Refactoring let rec eval e = match e with Const i i Add ( u, v ) add (eval u) (eval v) Mul ( u, v ) mul (eval u) (eval v) 8

Refactoring let rec eval e = match e with Const i i Add ( u, v ) add (eval u) (eval v) Mul ( u, v ) mul (eval u) (eval v) let eval = lifting eval : oexpr int 8

Refactoring let rec eval e = match e with Const i i Add ( u, v ) add (eval u) (eval v) Mul ( u, v ) mul (eval u) (eval v) let eval = lifting eval : oexpr int let rec eval e = match e with Const x x Binop (Add, x, x ) add (eval x) (eval x ) Binop (Mul, x, x ) mul (eval x) (eval x ) 8

Why not use the typechecker for refactoring? We do automatically what the programmer must do manually. We can guarantee that the program obtained is related to the original program. The typechecker misses some places where a change is necessary. 9

Why not use the typechecker for refactoring? We do automatically what the programmer must do manually. We can guarantee that the program obtained is related to the original program. The typechecker misses some places where a change is necessary. Permuting values type bool = False True We can safely exchange True and False in some places: 9

Why not use the typechecker for refactoring? We do automatically what the programmer must do manually. We can guarantee that the program obtained is related to the original program. The typechecker misses some places where a change is necessary. Permuting values type bool = False True We can safely exchange True and False in some places: type ornament not : bool bool with True False False True The relations between bare and ornamented values are tracked through the program (by ornament inference). 9

Ornament inference The ornamentation constraints are propagated as with type inference. let rec add_gen m n = match (orn-match #3) m with Z_skel n S_skel x (orn-cons #1) (S_skel (add_gen x n)) #2 val add_gen : (α < nat)(β < nat). α β β 10

Specialization type α map = Node of α map key α α map Leaf 11

Specialization type α map = Node of α map key α α map Leaf Instead of unit map, we could use a more compact representation: type set = SNode of set key set SLeaf 11

Specialization type α map = Node of α map key α α map Leaf Instead of unit map, we could use a more compact representation: type set = SNode of set key set SLeaf type ornament mapset : unit map set with Node(l,k,(),r) SNode(l,k,r) Leaf SLeaf 11

Specialization: unboxing type α option = None Some of α type booloption = NoneBool SomeTrue SomeFalse 12

Specialization: unboxing type α option = None Some of α type booloption = NoneBool SomeTrue SomeFalse type ornament boolopt : bool option booloption with None NoneBool Some(true) SomeTrue Some(false) SomeFalse 12

And also... Specialization: removing cases Future work: adding invariants using GADTs 13

Outline Some examples Encoding lifting A meta-language for ornamentation Encoding ornaments in mml 14

From add to append Idea: insert some conversion code in add to obtain append. First attempt: let rec append m n = match list2nat m with Z n S m nat2list (S (append m n)) 15

From add to append Idea: insert some conversion code in add to obtain append. First attempt: let rec append m n = match list2nat m with Z n S m nat2list (S (append m n)) let rec list2nat a = match a with Nil Z Cons(_,xs) S (list2nat xs) 15

From add to append Idea: insert some conversion code in add to obtain append. First attempt: let rec append m n = match list2nat m with Z n S m nat2list (S (append m n)) let rec list2nat a = match a with Nil Z Cons(_,xs) S (list2nat xs) let rec nat2list n = match n with Z Nil S xs Cons(?, nat2list xs) 15

From add to append Idea: insert some conversion code in add to obtain append. First attempt: let rec append m n = match list2nat m with Z n S m nat2list (S (list2nat (append (nat2list m ) n)) let rec list2nat a = match a with Nil Z Cons(_,xs) S (list2nat xs) let rec nat2list n = match n with Z Nil S xs Cons(?, nat2list xs) 16

Opening the recursion Ignoring for the moment the missing argument to Cons, we can solve our problems by incrementalizing. type α nat_skel = Z S of α let list2nat a = match a with Nil Z Cons(_,xs) S xs let nat 2 list n = match n with Z Nil S xs Cons(?, xs) 17

Opening the recursion Ignoring for the moment the missing argument to Cons, we can solve our problems by incrementalizing. type α nat_skel = Z S of α let list2nat a = match a with Nil Z Cons(_,xs) S xs let nat 2 list n = match n with Z Nil S xs Cons(?, xs) let rec append m n = match list2nat m with Z n S m nat 2list (S (append m n)) 17

Opening the recursion Now the extra information can simply be passed as argument to nat 2 list. type α nat_skel = Z S of α let list2nat a = match a with Nil Z Cons(_,xs) S xs let nat 2 list n x = match n with Z Nil S xs Cons(x, xs) let rec append m n = match list2nat m with Z n S m nat 2list (S (append m n)) (List.hd m) 17

Marking the encoding The encoding introduces a lot of function calls that we would like to eliminate. We separate normal function calls from calls to ornamentation functions: meta-abstraction and application are noted #. type α nat_skel = Z S of α let list2nat = fun l / match l with Nil Z Cons(_,xs) S xs let nat 2 list = fun n x / match n with Z Nil S xs Cons(x, xs) let rec append m n = match list2nat # m with Z n S m nat 2list # (S (append m n)) # (List.hd m) 18

Marking the encoding The encoding introduces a lot of function calls that we would like to eliminate. We separate normal function calls from calls to ornamentation functions: meta-abstraction and application are noted #. type α nat_skel = Z S of α let list2nat = fun l / match l with Nil Z Cons(_,xs) S xs let nat 2 list = fun n x / match n with Z Nil S xs Cons(x, xs) let rec append m n = match list2nat # m with Z n S m nat 2list # (S (append m n)) # (List.hd m) They can then be reduced without affecting the rest of the code. 18

Eliminating ornamentation calls They can then be reduced without affecting the rest of the code: let rec append m n = match list2nat # m with Z n S m nat 2list # (S (append m n)) # (List.hd m) There remains two redundant pattern matchings, decoding lists to nat_skel and encoding nat_skel to lists. 19

Eliminating ornamentation calls They can then be reduced without affecting the rest of the code: let rec append m n = match (match m with Nil Z Cons(_, xs) S xs) with Z n S m (match S (append m n) with Z Nil S zs Cons(List.hd m, zs)) 20

Eliminating ornamentation calls They can then be reduced without affecting the rest of the code: let rec append m n = match (match m with Nil Z Cons(_, xs) S xs) with Z n S m (match S (append m n) with Z Nil S zs Cons(List.hd m, zs)) There remains two redundant pattern matchings, decoding lists to nat_skel and encoding nat_skel to lists. 20

Eliminating the encoding There remains two redundant pattern matchings, decoding lists to nat_skel and encoding nat_skel to lists. We can eliminate them by reduction: let rec append m n = match (match m with Nil Z Cons(_, xs) S xs) with Z n S m Cons(List.hd m, append m n) 21

There remains two redundant pattern matchings, decoding lists to nat_skel and encoding nat_skel to lists. We can eliminate them by reduction, and by extruding the nested pattern matching: let rec append m n = match m with Nil (match Z with Z n S m Cons(List.hd m, append m n)) Cons(_, xs) (match S xs with Z n S m Cons(List.hd m, append m n)) 22

There remains two redundant pattern matchings, decoding lists to nat_skel and encoding nat_skel to lists. We can eliminate them by reduction, and by extruding the nested pattern matching, and reducing again: let rec append m n = match m with Nil n Cons(_, xs) Cons(List.hd m, append m n)... and we obtain the code for append. 23

add, generalized let add_gen = fun m2nat nat 2m n2nat nat 2n patch / let rec add m n = match m2nat # m with Z n S m nat 2n # S (add m n) # patch m n in add 24

add, generalized let add_gen = fun m2nat nat 2m n2nat nat 2n patch / let rec add m n = match m2nat # m with Z n S m nat 2n # S (add m n) # patch m n in add let append = add_gen # list2nat # nat 2 list # list2nat # nat 2 list # (fun m _ match m with Cons(x,_) x) 24

add, generalized let add_gen = fun m2nat nat 2m n2nat nat 2n patch / let rec add m n = match m2nat # m with Z n S m nat 2n # S (add m n) # patch m n in add let append = add_gen # list2nat # nat 2 list # list2nat # nat 2 list # (fun m _ match m with Cons(x,_) x) let add = add_gen # nat2nat # nat 2nat # nat2nat # nat 2nat # (fun ()) 24

Why generalize? We need to be able to represent partially-instantiated terms to display it to the user. A completely uninstantiated is a natural output for ornament inference in the absence of any annotation. The completely uninstantiated term can be instantiated by the identity to give back the original term. This will be useful for proving correctness. 25

Summarizing the process 1. Generalize the base code 2. Instanciate with specific ornaments and patches 3. Reduce to eliminate the meta code 4. Simplify the pattern matching 26

The case for dependent types What if we add data to the Z constructor too? type α stream = End Continued More of α α stream ornament α natstream : nat α stream with Z (End Continued) S n More(_, n) 27

The case for dependent types What if we add data to the Z constructor too? type α stream = End Continued More of α α stream ornament α natstream : nat α stream with Z (End Continued) S n More(_, n) let nat 2stream n x = match n with Z (match x with true Continued false End) S n More(x,n ) 27

The case for dependent types What if we add data to the Z constructor too? type α stream = End Continued More of α α stream ornament α natstream : nat α stream with Z (End Continued) S n More(_, n) let nat 2stream n x = match n with Z (match x with true Continued false End) S n More(x,n ) What is the type of x? 27

The case for dependent types What if we add data to the Z constructor too? type α stream = End Continued More of α α stream ornament α natstream : nat α stream with Z (End Continued) S n More(_, n) let nat 2stream n x = match n with Z (match x with true Continued false End) S n More(x,n ) What is the type of x? match n with Z bool S _ α 27

The case for dependent types The type may depend on more than the constructor. type α list01 = Nil01 Cons0 of α list01 Cons1 of α α list01 ornament α olist01 : bool list α list01 with Nil Nil01 Cons(False, xs) Cons0(xs) Cons(True, xs) Cons1(_, xs) 28

The case for dependent types The type may depend on more than the constructor. type α list01 = Nil01 Cons0 of α list01 Cons1 of α α list01 ornament α olist01 : bool list α list01 with Nil Nil01 Cons(False, xs) Cons0(xs) Cons(True, xs) Cons1(_, xs) match m with Nil unit Cons (False, _) unit Cons (True, _) α 28

Outline Some examples Encoding lifting A meta-language for ornamentation Encoding ornaments in mml 29

Starting from ML τ, σ ::= α τ τ ζ τ (α : Typ) τ a, b ::= x let x = a in a fix (x : τ) x. a a a Λ(α : Typ). u a τ d τ a match a with P a P ::= d τ x 30

Starting from ML E ::= [] E a v E d(v,.. v, E, a,.. a) Λ(α : Typ). E E τ match E with P a let x = E in a (fix (x : τ) y. a) v h β a[x fix (x : τ) y. a, y v] (Λ(α : Typ). v) τ h β v[α τ] let x = v in a h β a[x v] match d j τ j (v i ) i with (d j τ j (x ji ) i a j ) j h β a j[x ij v i ] i Context-Beta a h β b E[a] β E[b] 31

From ML to mml eml: add type-level pattern matching and equalities. mml: add dependent, meta-abstraction and application. Reduction (under some typing conditions): From mml, reduce meta-application and get a term in eml From eml, eliminate type-level pattern matching and get a term in ML 32

eml eml is obtained by extending the type system of ML. 33

eml eml is obtained by extending the type system of ML. Γ = α : Typ, m : nat (list α), x : match m with Z unit S _ α match m with Z Nil S m Cons (x, m ) 33

eml eml is obtained by extending the type system of ML. Γ = α : Typ, m : nat (list α), x : match m with Z unit S _ α match m with Z Nil S m Cons (x, m ) In the S branch: we know m = S m. Thus: x : match m with Z unit S _ α = match S m with Z unit S _ α = α 33

Introducing equalities We extend the typing environment with equalities: Γ ::=... Γ, a = τ b 34

Introducing equalities We extend the typing environment with equalities: Γ ::=... Γ, a = τ b Equalities are introduced on pattern matching: Γ τ : Sch (Γ, (x ij : τ ij [α k τ k ] k ) j, a = ζ (τk ) k (d i : (α k : Typ) k (τ ij ) j ζ (α k ) k ) i Γ a : ζ (τ k ) k d i(τ ij ) k (x ij ) j b i : τ) i Γ match a with (d i (τ ik ) k (x ij ) j b i ) i : τ 34

Eliminating equalities The equalities in the context are used to prove type equalities: Γ τ 1 τ 2. This type equalities can be used to convert (implicitly) in typing derivations: Γ τ 1 τ 2 Γ a : τ 1 Γ a : τ 2 35

Elimination of equalities We restrict reduction in equalities so that they stay decidable. Suppose we have a term a in eml such that Γ a : τ, where Γ and τ are in ML. Then, we can transform a into a well-typed ML term by: Using an equality to substitute in a term Extruding a nested pattern matching Reduding pattern matching Thus it makes sense to use eml as an intermediate language for ornamentation. 36

Meta-programming in mml We want to be able to eliminate all abstractions and applications marked with #. We introduce a separate type for meta-functions, so that they can only be applied using meta-application. (λ (x : τ). a) u h a[x u] We restrict the types so meta-constructions can not be manipulated by the ML fragment. 37

Meta-reduction If there are no meta-typed variables in the context, the meta-reduction will eliminate all meta constructions and give an eml term. But the meta-reduction also commutes with the ML reduction. We thus have two dynamic semantics for the same term: For reasoning, we can consider that meta and ML reduction are interleaved. We can use the meta reduction in the first stage to compile an mml term down to an eml term. 38

Dependent functions Since meta-abstraction and meta-application will be eliminated, we enrich them with some features that could not exist in ML or eml and that we need to encode ornaments. We need dependent types for the encoding function: nat _to_list : Π(x : nat (list α)). Π(y : match x with Z unit S list α _ α). 39

Dependent functions Since meta-abstraction and meta-application will be eliminated, we enrich them with some features that could not exist in ML or eml and that we need to encode ornaments. We need dependent types for the encoding function: nat _to_list : Π(x : nat (list α)). Π(y : match x with Z unit S list α _ α). For the encoding of ornaments to type correctly, we also add: Type-level functions to represent the type of the extra information. The ability to abstract on equalities so they can be passed to patches. 39

Outline Some examples Encoding lifting A meta-language for ornamentation Encoding ornaments in mml 40

Semantics of ornament specifications let append = lifting add : α natlist α natlist α natlist What we mean: If ml is a lifting of m (for natlist ) and nl is a lifting of n then append ml nl is a lifting of add m n 41

Semantics of ornament specifications let append = lifting add : α natlist α natlist α natlist What we mean: If ml is a lifting of m (for natlist ) and nl is a lifting of n then append ml nl is a lifting of add m n We build a step-indexed binary logical relation on mml, and add an interpretation for datatype ornaments. Then, the interpretation of a functional lifting is exactly the interpretation of function types (replace is a lifting of by is related to ). 41

Datatype ornaments A datatype ornament naturally gives a relation: ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) 42

Datatype ornaments A datatype ornament naturally gives a relation: ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) (Z, Nil) V k [natlist τ] (u, v) V k [natlist τ] (S u, Cons (a, v)) V k [natlist τ] 42

Datatype ornaments A datatype ornament naturally gives a relation: ornament α natlist : nat α list with Z Nil S xs Cons(_, xs) (Z, Nil) V k [natlist τ] (u, v) V k [natlist τ] (S u, Cons (a, v)) V k [natlist τ] We prove that the ornamentation functions are correct relatively to this definition: if we construct a natural number and a list from the same skeleton, they are related; if we destruct related values, we obtain the same skeleton. 42

Correctness Consider a term a. Generalize it into a. By the fundamental lemma, a is related to itself. Construct an instanciation γ + and the identity instanciation γ. γ (a) and γ + (a) are related. γ (a) reduces to a, preserving the relation. Simplify γ + (a) into a + (an ML term), preserving the relation a and a + are related. 43

In practice We have a prototype implementation, that follows the process outlined here. User interace issues: specifying the instantiation. We take labelled patches and ornaments. To build the generic lifting, we have to transform the code: transform deep pattern matching into shallow pattern matching. We also expand local polymorphic lets (but this is a user interface problem). We try to recover the shape of the original program in a post-processing phase. Available online: http://gallium.inria.fr/~remy/ornaments/ 44

Conclusion Ornaments can be used to lift functions in ML. Going through the intermediate language allows a cleaner presentation. We proved the lifting is correct. Future work Can we write robust patches? A formal result about effects Non-regular types, GADTs? Should we give the user access to mml? Can we use mml for something else? 45