Quotient Lenses Nate Foster (Penn) Benjamin C. Pierce (Penn) - - PowerPoint PPT Presentation

quotient lenses
SMART_READER_LITE
LIVE PREVIEW

Quotient Lenses Nate Foster (Penn) Benjamin C. Pierce (Penn) - - PowerPoint PPT Presentation

Quotient Lenses Nate Foster (Penn) Benjamin C. Pierce (Penn) Alexandre Pilkiewicz (Polytechnique/INRIA) ICFP 08 Bidirectional Transformations S T Updated Updated S T Bidirectional Programming Language lens Eliminates Redundancy:


slide-1
SLIDE 1

Quotient Lenses

Nate Foster (Penn) Benjamin C. Pierce (Penn) Alexandre Pilkiewicz (Polytechnique/INRIA) ICFP ’08

slide-2
SLIDE 2

Bidirectional Transformations

S T

Updated

T

Updated

S

slide-3
SLIDE 3

Bidirectional Programming Language

lens

Eliminates Redundancy: programs describes two functions Ensures Correctness: type system guarantees well-behavedness

slide-4
SLIDE 4

Semantics

A lens l from S to T is a triple of functions l.get ∈ S → T l.put ∈ T → S → S l.create ∈ T → S

  • beying three “round-tripping” laws:

l.put (l.get s) s = s (GetPut) l.get (l.put t s) = t (PutGet) l.get (l.create t) = t (CreateGet)

slide-5
SLIDE 5

Boomerang [POPL ’08]

slide-6
SLIDE 6

Boomerang [POPL ’08]

strings

slide-7
SLIDE 7

Boomerang [POPL ’08]

finite-state transducer

slide-8
SLIDE 8

Boomerang [POPL ’08]

Lenses: addresses books, bibliographies, CSV, documents, scientific data, XML Applications: converters, synchronizers, structure editors

slide-9
SLIDE 9

Example: MediaWiki (Get)

<html> <body> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> <h2>Justices</h2> <ul> <li>Arthur Goldberg</li> </ul> </body> </html> ==Chefs== * Julia Child ==Justices== * Arthur Goldberg

slide-10
SLIDE 10

Example: MediaWiki (Update)

<html> <body> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> <h2>Justices</h2> <ul> <li>Arthur Goldberg</li> </ul> </body> </html> <html> <body> <h2>Chefs</h2> <ul> <li>Julia Child</li> <li>Jacques Pepin</li> </ul> <h2>Justices</h2> <ul> <li>Warren Burger</li> <li>Arthur Goldberg</li> </ul> </body> </html> ==Chefs== * Julia Child ==Justices== * Arthur Goldberg

slide-11
SLIDE 11

Example: MediaWiki (Put)

<html> <body> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> <h2>Justices</h2> <ul> <li>Arthur Goldberg</li> </ul> </body> </html> <html> <body> <h2>Chefs</h2> <ul> <li>Julia Child</li> <li>Jacques Pepin</li> </ul> <h2>Justices</h2> <ul> <li>Warren Burger</li> <li>Arthur Goldberg</li> </ul> </body> </html> ==Chefs== * Julia Child ==Justices== * Arthur Goldberg ==Chefs== * Julia Child * Jacques Pepin ==Justices== * Warren Burger * Arthur Goldberg

slide-12
SLIDE 12

Example: MediaWiki (Lens)

(* helpers *) let mk_elt (ws:string) (tag:string) (body:lens) = ... let mk_simple_elt (ws:string) (tag:string) (body:lens) = ins ws . ins ("<" . tag . ">") . body . ins ("</" . tag . ">") (* main lenses *) let p : lens = mk_simple_elt nl4 "p" ((text . nl)* . (text . del nl)) let li : lens = mk_simple_elt nl6 "li" (del "* " . text) let ul : lens = mk_elt nl4 "ul" (li . del nl)+ let h2 : lens = mk_simple_elt nl4 "h2" (del "==" . text . del "==") let s : lens = (del nl . (p | ul))* let html : lens = mk_outer_elt nl0 "html" (mk_elt nl2 "body" s* )

slide-13
SLIDE 13

This Talk: Lenses for... ?

slide-14
SLIDE 14

This Talk: Lenses for Whitespace!

Many data formats contain inessential information: <html>\n __<body>\n ____<h2>Famous Chefs</h2>\n ____<ul>\n ______<li>Julia Child</li>\n ____</ul>\n ____<h2>Supreme Court Justices</h2>\n ____<ul>\n ______<li>Arthur Goldberg</li>\n ____</ul>\n __</body>\n </html>\n

slide-15
SLIDE 15

This Talk: Lenses for Whitespace!

Many data formats contain inessential information: <html>\n <body>\n <h2>Famous Chefs</h2>\n <ul>\n <li>Julia Child</li>\n </ul>\n <h2>Supreme Court Justices</h2>\n <ul>\n <li>Arthur Goldberg</li>\n </ul>\n </body>\n </html>\n

slide-16
SLIDE 16

This Talk: Lenses for Whitespace!

Many data formats contain inessential information: <html><body>\n __<h2>Famous Chefs</h2>\n __<ul><li>Julia Child</li></ul>\n __<h2>Supreme Court Justices</h2>\n __<ul><li>Arthur Goldberg</li></ul>\n </body></html>\n Want the put function to treat these targets equivalently but l.get (l.put t s) = t (PutGet) implies they must map to different sources!

slide-17
SLIDE 17

Dealing With Ignorable Data

Approach #1: No laws. Transformations not required to obey any formal properties. But clearly intended to be “essentially” bidirectional. Backed up by intuitive understanding of implementation. Examples:

◮ biXid [Kawanaka and Hosoya ’06] ◮ PADS [AT&T / Princeton]

slide-18
SLIDE 18

Dealing With Ignorable Data

Approach #2: Weaker laws. Replace round-trip laws with round-trip-and-a-half versions. Allows transformations that normalize data in the target... ...and also many ill-behaved transformations. Examples:

◮ Inv [Mu,Hu,Takeichi ’04] ◮ X [Hu,Mu,Takeichi ’04] ◮ Bi-XQuery [Liu, Hu, Takeichi ’07]

slide-19
SLIDE 19

Dealing With Ignorable Data

Approach #3: Viewers.

parse pretty print lens viewer

Examples:

◮ Focal [POPL ’05] ◮ XSugar [Brabrand, Møller, Schwartzbach ’05]

slide-20
SLIDE 20

Dealing With Ignorable Data

Or... develop a theory of lenses that are well-behaved modulo equivalence relations on the source (∼S) and target (∼T).

slide-21
SLIDE 21

Dealing With Ignorable Data

Or... develop a theory of lenses that are well-behaved modulo equivalence relations on the source (∼S) and target (∼T). A quotient lens l satisfies the following laws l.put (l.get s) s ∼S s (GetPut) l.get (l.put t s) ∼T t (PutGet) l.get (l.create t) ∼T t (CreateGet) (Plus laws ensuring that l’s components respect ∼S and ∼T.)

slide-22
SLIDE 22

Syntax for Quotient Lenses

S T

  • riginal lens
slide-23
SLIDE 23

Syntax for Quotient Lenses

S V canonize choose T

  • riginal lens

canonizer

slide-24
SLIDE 24

Syntax for Quotient Lenses

S V / ~V canonize choose T

  • riginal lens

quotiented lens canonizer

slide-25
SLIDE 25

Syntax for Quotient Lenses

slide-26
SLIDE 26

Syntax for Quotient Lenses

slide-27
SLIDE 27

Syntax for Quotient Lenses

slide-28
SLIDE 28

Syntax for Quotient Lenses

;

slide-29
SLIDE 29

Syntax for Quotient Lenses

*

slide-30
SLIDE 30

Example: MediaWiki (Lens)

(* helpers *) let mk_elt (ws:string) (tag:string) (body:lens) = ... let mk_simple_elt (ws:string) (tag:string) (body:lens) = ins ws . ins ("<" . tag . ">") . body . ins ("</" . tag . ">") (* main lenses *) let p : lens = mk_simple_elt nl4 "p" ((text . nl)* . (text . del nl)) let li : lens = mk_simple_elt nl6 "li" (del "* " . text) let ul : lens = mk_elt nl4 "ul" (li . del nl)+ let h2 : lens = mk_simple_elt nl4 "h2" (del "==" . text . del "==") let s : lens = (del nl . (p | ul))* let html : lens = mk_outer_elt nl0 "html" (mk_elt nl2 "body" s* )

slide-31
SLIDE 31

Example: MediaWiki (Lens)

(* helpers *) let mk_elt (ws:string) (tag:string) (body:lens) = ... let mk_simple_elt (ws:string) (tag:string) (body:lens) = ins ws . ins ("<" . tag . ">") . body . ins ("</" . tag . ">") (* main lenses *) let p : lens = mk_simple_elt nl4 "p" ((text . nl)* . (text . del nl)) let li : lens = mk_simple_elt nl6 "li" (del "* " . text) let ul : lens = mk_elt nl4 "ul" (li . del nl)+ let h2 : lens = mk_simple_elt nl4 "h2" (del "==" . text . del "==") let s : lens = (del nl . (p | ul))* let html : lens = mk_outer_elt nl0 "html" (mk_elt nl2 "body" s* )

slide-32
SLIDE 32

Example: MediaWiki (Lens)

(* helpers *) let mk_elt (ws:string) (tag:string) (body:lens) = ... let mk_simple_elt (ws:string) (tag:string) (body:lens) = qins WS ws . ins ("<" . tag . ">") . body . ins ("</" . tag . ">") (* main lenses *) let p : lens = mk_simple_elt nl4 "p" ((text . nl)* . (text . del nl)) let li : lens = mk_simple_elt nl6 "li" (del "* " . text) let ul : lens = mk_elt nl4 "ul" (li . del nl)+ let h2 : lens = mk_simple_elt nl4 "h2" (del "==" . text . del "==") let s : lens = (del nl . (p | ul))* let html : lens = mk_outer_elt nl0 "html" (mk_elt nl2 "body" s* )

slide-33
SLIDE 33

Canonizers

A canonizer q from V to T is a pair of functions q.canonize ∈ V → T q.choose ∈ T → V

  • beying just one law:

l.canonize (l.choose t) t = t (ReCanonize)

slide-34
SLIDE 34

Syntax for Canonizers

Every lens l from V to T can be converted to a canonizer: q.canonize

  • l.get

q.choose

  • l.create

The CreateGet law for l implies ReCanonize. Additionally, the relaxed canonizer law enable primitives that are not valid as lenses.

slide-35
SLIDE 35

An Unexpected Side Benefit...

The increased flexibility of quotient lenses can be exploited to simplify the types of complicated transformations.

slide-36
SLIDE 36

Example: Table of Contents (Get)

<html> <body> <ul> <li>Chefs</li> <li>Justices</li> </ul> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> <h2>Justices</h2> <ul> <li>Arthur Goldberg</li> </ul> </body> </html> ==Chefs== * Julia Child ==Justices== * Arthur Goldberg

slide-37
SLIDE 37

Example: Table of Contents (Update)

<html> <body> <ul> <li>Chefs</li> <li>Justices</li> </ul> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> <h2>Justices</h2> <ul> <li>Arthur Goldberg</li> </ul> </body> </html> <html> <body> <ul> <li>Chefs</li> <li>Justices</li> </ul> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> </body> </html> ==Chefs== * Julia Child ==Justices== * Arthur Goldberg

slide-38
SLIDE 38

Example: Table of Contents (Put)

<html> <body> <ul> <li>Chefs</li> <li>Justices</li> </ul> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> <h2>Justices</h2> <ul> <li>Arthur Goldberg</li> </ul> </body> </html> <html> <body> <ul> <li>Chefs</li> <li>Justices</li> </ul> <h2>Chefs</h2> <ul> <li>Julia Child</li> </ul> </body> </html> ==Chefs== * Julia Child ==Justices== * Arthur Goldberg

?

slide-39
SLIDE 39

Flexibility with Quotient Lenses

To satisfy PutGet the duplication lens needs a type that demands equality for the copied data. But enriching types with equality constraints makes type checking awkward.

slide-40
SLIDE 40

Flexibility with Quotient Lenses

To satisfy PutGet the duplication lens needs a type that demands equality for the copied data. But enriching types with equality constraints makes type checking awkward. As a quotient lens, we can assign the duplication lens a simpler (regular) type.

◮ Using a total equivalence on the second copy of the data

in the targt. This flexiblity also simplifies the types of primitives for

◮ sorting ◮ wrapping lines of text

slide-41
SLIDE 41

Conclusion

◮ The need to handle inessential data arises in many

real-world applications built using lenses.

◮ Quotient lenses are a critical piece of technology that

helps bridge the gap between the theory and practice of bidirectional programming languages.

◮ Canonizers lead to elegant syntax for quotient lenses.

slide-42
SLIDE 42

Thank You!

Collaborators: Benjamin Pierce, Alexandre Pilkiewcz. Other Boomerang contributors: Aaron Bohannon, Michael Greenberg, and Alan Schmitt. Want to play? Boomerang is available for download:

◮ Source code (LGPL) ◮ Binaries for OS X, Linux ◮ Research papers ◮ Tutorial and growing collection of demos

http://www.seas.upenn.edu/∼harmony/

slide-43
SLIDE 43

Type Checking Quotient Lenses

;

l ∈ S/∼S ⇐ ⇒ T/∼T k ∈ T/∼T ⇐ ⇒ V /∼V l; k ∈ S/∼S ⇐ ⇒ V /∼V