1 / 22

Extending Type Systems in a Library

Extending Type Systems in a Library. Yuriy Solodkyy Jaakko Järvi Esam Mlaih. Motivation. Type systems are good for you! make sure certain bugs never appear better optimizations Type systems of a general purpose programming language are typically not extensible a fixed part of a compiler

naeva
Download Presentation

Extending Type Systems in a Library

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Extending Type Systems in a Library Yuriy Solodkyy Jaakko Järvi Esam Mlaih

  2. Motivation • Type systems are good for you! • make sure certain bugs never appear • better optimizations • Type systems of a general purpose programming language are typically not extensible • a fixed part of a compiler • There are many domain specific type systems Texas A&M University

  3. Use cases • Physical quantities • Types to track some semantic properties: • nullability, sign, oddity of a number • security vulnerability to format strings • usage of user pointers in kernel space • deadlocks and data races • Regular Expression Types Texas A&M University

  4. Goal • Explore how far a pure library solution suffices to extending a type system Texas A&M University

  5. Contributions • We report on implementing simple type qualifiers as a C++ library • We implement regular expression types (in a limited form) to check XML data • We provide a framework to help others in extending the C++ type system for their abstractions Texas A&M University

  6. Example returns only positive numbers // a is a positive value double a = current_height(); // b is a positive value double b = max_allowed_height(); // b-a may be negative though! Result is always positive double c = std::sqrt(b-a); // b+a is assumed to be positive. Unless there is bug! double d = std::sqrt(b+a); upper bound for values from previous call difference is positive, but not for type system argument and result are always positive Texas A&M University

  7. What do we need? • Typing rules • Evaluation rules • Subtyping rules Texas A&M University

  8. How do we achieve that in C++? • Typing rules • Type construction via class templates • Evaluation rules • Function templates and overloading • Subtyping rules • A dedicated meta-function Texas A&M University

  9. Useful building blocks • Typing rules • tuple, variant, optional • Evaluation rules • enable_if • Subtyping rules • MPL • Interoperability of the above libraries! Texas A&M University

  10. Type qualifiers • Allow tracking of semantic properties like: • immutability of a certain value (const) • sign of a number (pos, neg) • assumptions about pointers (optional, nonnull) • trustworthiness of a certain value (tainted, untainted) • oddity of a number (odd, even) • origin of a pointer (user, kernel) Texas A&M University

  11. Example: Qualifiers’ Hello World Declare few qualifiers: Q is positive if T <: Q T Q is negative if Q T <: T Define how different operations transfer properties #include <xtl/qualdecl.hpp> DECLARE_NEGATIVE_QUALIFIER(pos); DECLARE_POSITIVE_QUALIFIER(tainted); // ... Other qualifiers ... namespace xtl { template <> struct minus<pos, neg> { typedef qual<pos> type; }; template <> struct minus<neg, pos> { typedef qual<neg> type; }; template <> struct mul<pos, pos> { typedef qual<pos> type; }; template <> struct mul<pos, neg> { typedef qual<neg> type; }; template <> struct mul<nonnull, nonnull>{ typedef qual<nonnull> type;}; template <> struct div<nonnull, nonnull>{ typedef qual<nonnull> type;}; } // of namespace xtl int main() { untainted<nonnull<neg<int> > >a(-42); pos<untainted<nonnull<int> > >b(7); neg<nonnull<long> >c = a * b; // OK: drop negative qualifier untainted //nonnull<pos<double> > d = b - a; // Error: nonnull isn’t carried by - pos<tainted<double> >e = b + a*c; // OK to add positive qualifier //pos<double> f = e; // Error: ... but not OK to drop it! } Subtraction does not carry nonnull Positive qualifiers can be added to result type... Multiplication carries nonnull & negativeness on pos & neg arguments Declare your variables with appropriate properties ... but not dropped once they are there! Texas A&M University

  12. Example function descend accepts only positive numbers we achieve this by restricting its argument type to be a subtype of pos<double> we convert value of a subtype into a value of a supertype // Example definition that accepts only positive doubles template<class U> typename enable_if< typename is_subtype<U, pos<double> >::type, void >::type descend(const U& altitude) { pos<double>a = subtype_cast<pos<double> >(altitude); //... }; // Data coming from measurements is marked untainted extern pos<untainted<int> >get_corridor_height(); untainted<pos<int> >a = get_corridor_height(); descend(a); // no negative altitudes here! returns a value that is both: positive and untainted a can hold positive, untainted values. order of qualifiers is not important! no negative altitudes can appear here! Texas A&M University

  13. Qualifiers summary • Easy to define and use • Cannot handle flow-sensitive qualifiers • Cannot handle arbitrary reference qualifiers (e.g. aliasing related) Texas A&M University

  14. Type system for XML • Types can describe XML elements with certain structure • Subtyping describes structurally more powerful types • Compile-time assurance that only valid XML documents are produced • Value-preserving type conversions Texas A&M University

  15. typedef element<name, string> XMLname; typedef element<email,string> XMLemail; typedef element<icq, int>XMLicq; typedef element<contact, boost::variant< XMLemail, XMLicq > > XMLcontact; typedef element<person, fusion::tuple< XMLname, XMLcontact > > XMLperson; <xsd:elementname="name"type="xsd:string"/> <xsd:elementname="email"type="xsd:string"/> <xsd:elementname="icq"type="xsd:decimal"/> <xsd:elementname="contact"> <xsd:complexType> <xsd:choice> <xsd:elementref="email"/> <xsd:elementref="icq"/> </xsd:choice> </xsd:complexType> </xsd:element> <xsd:elementname="person"> <xsd:complexType> <xsd:sequence> <xsd:elementref="name"/> <xsd:elementref="contact"/> </xsd:sequence> </xsd:complexType> </xsd:element> Example we use a dedicated type element to represent XML elements we use a dedicated type element to represent XML elements for each tag we create a dedicated tag-type for each tag we create a dedicated tag-type we map XML data types into C++ types we map XML data types into C++ types back references are mapped to previous typedefs back references are mapped to previous typedefs back references are mapped to previous typedefs XML Schema’s choice is mapped to Boost variant XML Schema’s choice is mapped to Boost variant XML Schema C++ XML Schema’s sequence is mapped to Fusion’s tuple XML Schema’s sequence is mapped to Fusion’s tuple Texas A&M University

  16. Tel <: AnyContact ICQ <: AnyContact Name, Tel, ICQ <: Name, AnyContact, AnyContact Person <: PersonEx Example Instantiate an XML snippet that corresponds to Person type // ... typedef variant<Email,Tel,ICQ> AnyContact; typedef element<person, tuple<Name, Tel, ICQ> > Person; typedef element<person, tuple<Name, AnyContact, AnyContact> > PersonEx; int main() { Person p(make_tuple(Name("Yuriy"),Tel("555-4321"),ICQ(1234))); PersonEx x = p; // OK: Subtyping conversion // p = x; // ERROR: Not in subtyping relation ifstream xml("old-person.xml"); xml >> x; // read data from XML file. assumes file exist cout << x << endl; // show XML source on the screen } Person <: PersonEx Assignment involves subtype conversion PersonEx is not a subtype of Person Parses only XML files that correspond to PersonEx schema Produces XML source on the screen Texas A&M University

  17. XDuce • Type • set of sequences over a certain domain • Regular Expression Types • concatenation : A,B • alternation : A|B • repetition : A* • optional : A? • type construction : l[A] • recursion : X = A,X | ø • Subtyping • inclusion between the sets defined by types Texas A&M University

  18. C++ • Type • set of sequences over a certain domain • Regular Expression Types • concatenation : A,B tuple<A,B> • alternation : A|B variant<A,B> • repetition : A* vector<A> • optional : A? optional<A> • type construction: l[A] element<l,A> • recursion : X = A,X | ø– • Subtyping • is_subtype and subtype_cast Texas A&M University

  19. XTL – eXtensible Typing Library • Provides a common interface for defining custom subtyping relation • Provides a common interface for defining conversion from a subtype to a supertype • Provides some ready definitions that can be used in defining other type systems: • subtyping of array types • subtyping of function types • subtyping of sequences and union types • subtyping of qualified types Texas A&M University

  20. Limitations • Reflexivity of subtyping relation has to be stated manually for each new type. • No implicit transitivity of subtyping relation. • Meta-function join may return an arbitrary upper bound. Texas A&M University

  21. Future work • Look at applying our approach to ownership types • Look at alternative representations of type qualifiers • Extend subtyping of repetitions • Create a library of useful type qualifiers Texas A&M University

  22. Thank You! Questions? Texas A&M University

More Related