Extensibility Didier Verna Introduction Extensibility for DSL design and Example implementation Step 1 Step 2 A case study in Common Lisp Step 3 Step 4 Wrap Up Didier Verna Conclusion Discussion didier@lrde.epita.fr http://www.lrde.epita.fr/˜didier DSLDI 2013 – Monday, July 1st 1/37
Taxonomy of DSLs [Fowler, 2005, Tratt, 2008] Extensibility Didier Verna Introduction Example Step 1 Step 2 Step 3 Step 4 Wrap Up Conclusion Discussion 3/37
Example Command-line options highlighting Extensibility Didier Verna Introduction Example Step 1 Step 2 Step 3 Step 4 Wrap Up Conclusion Properties (bold, underline, foreground color. . . ) Discussion Faces (localized property set) Themes (face trees) 5/37
Example Underlying implementation Extensibility The face class Didier Verna ( defclass face ( ) Introduction ( ( name : i n i t a r g :name) Example ; ; Properties : Step 1 ( foreground : i n i t a r g : foreground ) Step 2 ( background : i n i t a r g : background ) Step 3 ( boldp : i n i t a r g : bold ) Step 4 ; ; etc . Wrap Up ( subfaces : i n i t a r g : subfaces ) ) ) Conclusion Discussion 6/37
Example A DSL for theme customization Extensibility How do we go from this. . . Didier Verna ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Introduction Example : background black : face { option : foreground white Step 1 : face { syntax : bold t : foreground cyan } : face { usage : foreground yellow } Step 2 } Step 3 Step 4 . . . to that? Wrap Up Conclusion ( setq default − theme ( make − instance ’ face :name ’ t o p l e v e l Discussion : background ’ black : subfaces ( l i s t ( make − instance ’ face :name ’ option : foreground ’ white : subfaces ( l i s t ( make − instance ’ face :name ’ syntax : bold t : foreground ’ cyan ) ( make − instance ’ face :name ’ usage : foreground ’ yellow ) ) ) ) ) ) 7/37
Step 1 Hook into the Lisp parser: reader macros Extensibility readtable : currently active syntax extensions table Didier Verna macro character : special syntactic meaning Introduction reader macro : implements macro character behavior Example Step 1 Let’s do it! Step 2 Make the {} characters active Step 3 Step 4 Read a list of tokens until the closing brace Wrap Up Push the symbol define-face on top of that list Conclusion Discussion Note: RTMP (Read-Time Meta-Programming) 9/37
Step 1 Hook into the Lisp reader Extensibility This is how we go from this. . . Didier Verna ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Introduction Example : background black : face { option : foreground white Step 1 : face { syntax : bold t : foreground cyan } : face { usage : foreground yellow } Step 2 } Step 3 Step 4 . . . to that: Wrap Up Conclusion ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Discussion : background black : face ( define − face option : foreground white : face ( define − face syntax : bold t : foreground cyan ) : face ( define − face usage : foreground yellow ) ) 10/37
Step 2 Hook into the Lisp compiler: macros Extensibility Ordinary Lisp functions Didier Verna Work on chunks of code (as data) Introduction Transform expressions into new expressions Example Control over evaluation Step 1 Step 2 Let’s make define-face a macro! Step 3 Step 4 Quoting its key arguments, except for the :face ones Wrap Up Generating a call to make-face Conclusion Discussion Note: CTMP (Compile-Time Meta-Programming) 12/37
Step 2 Hook into the Lisp compiler: macros Extensibility This is how we go from this. . . Didier Verna ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Introduction Example : background black : face ( define − face option : foreground white Step 1 : face ( define − face syntax : bold t : foreground cyan ) : face ( define − face usage : foreground yellow ) ) Step 2 Step 3 Step 4 . . . to that: Wrap Up ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Conclusion : background ’ black Discussion : face ( make − face ’ option : foreground ’ white : face ( make − face ’ syntax : bold t : foreground ’ cyan ) : face ( make − face ’ usage : foreground ’ yellow ) ) 13/37
Step 3 A couple of wrappers Extensibility Lambda-list manipulation / 1st class functions Didier Verna ( defun make − face (name & rest args &key &allow − other − keys ) Introduction ( apply # ’ make − instance ’ face :name name args ) ) Example ( defun make − theme (& rest args ) Step 1 ( apply # ’make − face ’ t o p l e v e l args ) ) Step 2 Step 3 And while we’re at it. . . Step 4 Wrap Up ( defmacro define − theme (& rest args ) Conclusion ‘ ( define − face t o p l e v e l ,@args ) ) Discussion 15/37
Step 3 A couple of wrappers Extensibility This is how we go from this. . . Didier Verna ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Introduction Example : background ’ black : face ( make − face ’ option : foreground ’ white Step 1 : face ( make − face ’ syntax : bold t : foreground ’ cyan ) : face ( make − face ’ usage : foreground ’ yellow ) ) Step 2 Step 3 Step 4 . . . to that: Wrap Up ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Conclusion : background ’ black Discussion : face ( make − instance ’ face :name ’ option : foreground ’ white : face ( make − instance ’ face :name ’ syntax : bold t : foreground ’ cyan ) : face ( make − instance ’ face :name ’ usage : foreground ’ yellow ) ) 16/37
Step 4 Hook into the object system: the MOP Extensibility The C LOS Meta-Object Protocol ( MOP ) Didier Verna C LOS itself is object-oriented Introduction ◮ The C LOS MOP : a de facto implementation standard Example ◮ The C LOS components (classes, methods etc. ) are Step 1 (meta-)objects of some (meta-)classes Step 2 Step 3 Step 4 Generic functions, methods Wrap Up ( defmethod func ( ( arg1 class1 ) arg2 . . . ) Conclusion body ) Discussion Methods are outside the classes (ordinary function calls) Multiple dispatch (multi-methods) 18/37
Step 4 Hook into the object system: the MOP Extensibility Object instantiation ( make-instance ) is a protocol Didier Verna Slot initialization ( initialize-instance ) is a Introduction generic function Example Step 1 Let’s extend it! Step 2 Provide our own method for the face class Step 3 Step 4 Collect all :face arguments Wrap Up call the next (standard) method with a new :subfaces Conclusion initarg Discussion 19/37
Step 4 Hook into the object system: the MOP Extensibility This is how we go from this. . . Didier Verna ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Introduction Example : background ’ black : face ( make − instance ’ face :name ’ option : foreground ’ white Step 1 : face ( make − instance ’ face :name ’ syntax : bold t : foreground ’ cyan ) : face ( make − instance ’ face :name ’ usage : foreground ’ yellow ) ) Step 2 Step 3 Step 4 . . . to that: Wrap Up ; ; ; d ef a u lt . cth −−− Personal d ef a u lt theme f o r Clon Conclusion : background ’ black Discussion : subfaces ( l i s t ( make − instance ’ face :name ’ option : foreground ’ white : subfaces ( l i s t ( make − instance ’ face :name ’ syntax : bold t : foreground ’ cyan ) ( make − instance ’ face :name ’ usage : foreground ’ yellow ) ) ) ) 20/37
Wrap Up Using the DSL externally Extensibility Mostly a matter of read , compile etc. Didier Verna ( defun read − user − theme ( ) Introduction ( with − open − file ( stream ( merge − pathnames ".faces" ( user − homedir − pathname ) ) ) Example ( read ( make − concatenated − stream ( make − string − input − stream "(define-theme " ) stream Step 1 ( make − string − input − stream ")" ) ) ) ) ) Step 2 ( defmacro make − user − theme (& optional compile ) ( i f compile Step 3 ‘ ( funcall ( compile n i l ( lambda ( ) ,( read − user − theme ) ) ) ) Step 4 ( read − user − theme ) ) ) Wrap Up Conclusion Discussion 22/37
Wrap Up Using the DSL internally Extensibility Mostly a matter of. . . Just-Do-It TM Didier Verna Introduction ( setq default − theme ( define − theme Example : background black : face { option : foreground white Step 1 : face { syntax : bold t : foreground cyan } : face { usage : foreground yellow } Step 2 } ) ) Step 3 Step 4 Wrap Up Conclusion Discussion 23/37
Conclusion Extensibility Impact of GPL on DSL design and implementation Didier Verna Key GPL aspect: extensibility Introduction Embedded homogeneous approach Example ◮ A single language Step 1 ◮ DSL infrastructure smaller Step 2 ◮ DSL both internal and external Step 3 Common Lisp Step 4 ◮ Functional, Imperative, Object-Oriented Wrap Up ◮ MOP Conclusion ◮ CTMP (macros) Discussion ◮ RTMP (reader macros) ◮ read , eval , compile 25/37
Recommend
More recommend