Language and Ontology Shriram Krishnamurthi Yan-David Erlich Matthias Felleisen Rice University Language and Perception Different programming styles influence the way we think about the world Therefore, programmers want to extend their languages to suit their problem domains Consequence: programmers define new languages all the time! Adaptive Programming: Overview BusRoute BusList BusStopList Bus BusStop PersonList Person Lieberherr, et al Adaptive Programming: Traversals Traversal: from BusRoute to Person through BusStop BusRoute BusList BusStopList Bus BusStop PersonList Person Software Patterns: Overview Concrete versions of design patterns Allow high-level descriptions of creational, behavioral and structural properties Map pattern instances to code (Definition and mapping should respect the inductive structure of patterns) Gamma, Helm, Johnson, Vlissides, and others Software Patterns: Example Adapter Pattern + = Adapter Software Patterns + Adaptive Programming Behaviors are described by the Visitor Pattern, but it has lots of syntactic overhead Visitor BusWaiterVisitor { BusRoute -> … BusStop -> … Person -> … } Scientific Computation: Matrices Overview Implementation uses C++ templates Two languages are involved: configuration (extensional) element type (float, complex, …) shape (upper triangular, symmetric, …) implementation specification (intensional) bounds checked (yes, no) optimize for (speed, size) Czarnecki, Eisenecker, et al Summary Examples of the growing influence of domain-specific languages (DSLs) DLSs are a way to institutionalize knowledge and make it common to all the programmers in an organization/domain Some DSLs are created afresh; many leverage existing languages Are DSLs APIs? begin_scope (); … create_scoped_variable (“x”); … … … access_scoped_variable (“x”); end_scope (); (This is a terrible language!) Similar examples in COM, etc Typical Needs New binding forms Different orders of evaluation (applicative vs normal, right-to-left, etc) Domain-specific notations, conventions Programmers use libraries because that’s all they have available! Roadmap Needs a combination of support from the programming language and environment Easy and powerful definitions Tight integration of language extensions Preservation of language abstractions Powerful implementation model Adaptive Programming: Recap BusRoute BusList BusStopList Bus BusStop Visitor BusWaiterVisitor { BusRoute -> … BusStop -> … Person -> … PersonList Person } Tool Support for Adaptive Programming Combining these specifications: The adaptive programming tool does not know about our pattern extensions Sometimes, there is no ordering of DSLs Result: users must choose between DSLs Requirement: Tight Integration External tools cannot be composed External tools may provide poor debugging support Integrated tools may require the environment to be re-built for every addition or change Important consideration: Easy prototyping The Middle Ground Start with macro systems a la Scheme A macro system is a rewriting engine that works on a term structured syntax The macro language is embedded into a host language Multiple extensions can co-exist Definition Facility (define-macro Adapter (rewrite (_ <aN> adapts <aT> to <dI> as <aV> (fields <fd> …) (methods <md> …)) (as (class <aN> implements <dI> (fields (<aT> <aV>) <fd> …) (methods <md> …)))) Macros as Transformers class Adapter aN aN methods fields methods dI md aT md fields fd dI fd aV aT aV Requirement: Preserve Abstractions Embedding languages would not be effective if the programmer did not get information in terms of what they wrote (Information = type errors, program slices, value flow graphs, etc) Why This Matters MultiplicationExpression<class LazyBinaryExpression<class AdditionExpression<class MatrixICCL::Matrix<class MatrixICCL::BoundsChecker<class MatrixICCL::ArrFormat<class MatrixICCL::StatExt<struct MatrixDSL::int_number<int,7>,struct MatrixDSL::int_number<int,7>>,class MatrixICCL::Rect<class MatrixICCL::StatExt<struct MatrixDSL::int_number<int,7>,struct MatrixDSL::int_number<int,7>>>,class MatrixICCL::Dyn2DCContainer<class MATRIX_ASSEMBLE_COMPONENTS<class MATRIX_DSL_ASSIGN_DEFAULTS<class MATRIX_DSL_PARSER<struct MatrixDSL::matrix<int,struct MatrixDSL::structure<struct MatrixDSL::rect<struct MatrixDSL::stat_val<struct MatrixDSL::int_number<int,7>>,struct MatrixDSL::stat_val<struct MatrixDSL::int_number<int,7>>,struct MatrixDSL::unspecified_DSL_feature>,struct MatrixDSL::dense<struct MatrixDSL::unspecified_DSL_feature>,struct MatrixDSL::dyn<struct MatrixDSL::unspecified_DSL_feature>>,struct MatrixDSL::speed<struct MatrixDSL::unspecified_DSL_feature>,struct MatrixDSL::unspecified_DSL_feature,struct MatrixDSL::unspecified_DSL_feature,struct MatrixDSL::unspecified_DSL_feature,struct MatrixDSL::unspecified_DSL_feature>>::DSLConfig>::DSLConfig>>>>>,class MatrixICCL::Matrix<class MatrixICCL::BoundsChecker<class MatrixICCL::ArrFormat<class MatrixICCL::StatExt<struct MatrixDSL::int_number<int,7>,struct MatrixDSL::int_number<int,7>>,class MatrixICCL::Rect<class MatrixICCL::StatExt<struct MatrixDSL::int_number<int,7>,struct MatrixDSL::int_number<int,7>>>,class MatrixICCL::Dyn2DCContainer<class MATRIX_ASSEMBLE_COMPONENTS<class MATRIX_DSL_ASSIGN_DEFAULTS<class MATRIX_DSL_PARSER<struct MatrixDSL::matrix<int,struct MatrixDSL::structure<struct MatrixDSL::rect<struct MatrixDSL::stat_val<struct MatrixDSL::int_number<int,7>>,struct MatrixDSL::stat_val<struct MatrixDSL::int_number<int,7>>,struct MatrixDSL::unspecified_DSL_feature>,struct MatrixDSL::dense<struct MatrixDSL::unspecified_DSL_feature>,struct Ma… Generated from (A + B) * C Alternative Maintaining Abstractions Source correlation Ability to track source information through expansions Helps programmers understand feedback in terms of original source Interacting Abstractions Elaboration tracking Keeps track of history of transformations on terms Helps designers (and programmers) debug in the presence of complex interactions Requirement: Generalize Domain Even common languages have lots of “little” languages in them Macros are often limited to the expression and definition language (define (factorial (int n) : int) …) Expansion uses a protocol to determine “latest version” of each language Requirement: Generalize Expansion Macros are traditionally source-to-source; generalize by giving control over expansion of subexpressions allowing intermediate stages to produce non-source output enriching with attribute specifications (both threaded and unthreaded) Recap What we have described is a generalization of macros to extend to full compilation: Macros Compilers We provide both mechanism and policy: several incremental stages common framework, so designers can combine these in a single specification Requirement: Modularize Languages Languages are defined as “vocabularies” These have abstract parent languages Designers can compose them to create complete languages (analogous to “mixins” for classes) This makes specifications much more coherent and reusable Languages as Layers DL2 DL3 DL1 DL3 DL1 Base Language 2 Base Language 1 Base Language 1 Summary Experience shows our system is practical and efficient Key features: definition conveniences (…, hygiene) source correlation macros-to-compilers continuum language mixins Conclusion We have made a case for extensible languages described several “challenge” features to demand of programming environments mentioned how we implement these features