View
215
Download
0
Tags:
Embed Size (px)
Citation preview
Extending Type Systems in a Library
Yuriy Solodkyy
Jaakko Järvi
Esam Mlaih
22 October 2006 Texas A&M University 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
22 October 2006 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
22 October 2006 Texas A&M University 4
Goal
Explore how far a pure library solution suffices to extending a type system
22 October 2006 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
22 October 2006 Texas A&M University 6
Example
// a is a positive valuedouble a = current_height();
// b is a positive valuedouble b = max_allowed_height();
// b-a may be negative though! Result is always positivedouble c = std::sqrt(b-a);
// b+a is assumed to be positive. Unless there is bug!double d = std::sqrt(b+a);
returns only positive numbers
upper bound for values from previous
call
difference is positive, but not for type
system
argument and result are always positive
22 October 2006 Texas A&M University 7
What do we need?
Typing rules
Evaluation rules
Subtyping rules
22 October 2006 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
22 October 2006 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!
22 October 2006 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)
22 October 2006 Texas A&M University 11
Example: Qualifiers’ Hello World
#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 xtlint 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!
}
Declare few qualifiers:Q is positive if T <: Q TQ is negative if Q T <: T
Define how different operations transfer
properties
Declare your variables with appropriate
properties
Multiplication carries nonnull & negativeness
on pos & neg arguments
Subtraction does not carry nonnull
Positive qualifiers can be added to
result type...
... but not dropped once they are there!
22 October 2006 Texas A&M University 12
Example// Example definition that accepts only positive doublestemplate<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 untaintedextern pos<untainted<int> > get_corridor_height();
untainted<pos<int> > a = get_corridor_height();descend(a); // no negative altitudes here!
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
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!
22 October 2006 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)
22 October 2006 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
22 October 2006 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:element name="name" type="xsd:string"/><xsd:element name="email" type="xsd:string"/><xsd:element name="icq" type="xsd:decimal"/>
<xsd:element name="contact"> <xsd:complexType> <xsd:choice> <xsd:element ref="email"/> <xsd:element ref="icq"/> </xsd:choice> </xsd:complexType></xsd:element>
<xsd:element name="person"> <xsd:complexType> <xsd:sequence> <xsd:element ref="name"/> <xsd:element ref="contact"/> </xsd:sequence> </xsd:complexType></xsd:element>
XML Schema’s choice is mapped to Boost
variant
back references are mapped to previous
typedefs
we map XML data types into C++ types
for each tag we create a dedicated tag-typeExample
XML Schema C++
for each tag we create a dedicated tag-type
we map XML data types into C++ typesback references are
mapped to previous typedefs
back references are mapped to previous
typedefs
XML Schema’s sequence is mapped to
Fusion’s tuple
XML Schema’s sequence is mapped to
Fusion’s tuple
XML Schema’s choice is mapped to Boost
variant
we use a dedicated type element to represent XML
elements
we use a dedicated type element to represent XML
elements
22 October 2006 Texas A&M University 16
Example// ...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}
Tel <: AnyContactICQ <: AnyContactName, Tel, ICQ <: Name, AnyContact,
AnyContactPerson <: PersonEx
Instantiate an XML snippet that
corresponds to Person type
Person <: PersonExAssignment involves subtype conversionPersonEx is not a subtype of Person
Parses only XML files that correspond to PersonEx schemaProduces XML source
on the screen
22 October 2006 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
22 October 2006 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
22 October 2006 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
22 October 2006 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.
22 October 2006 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
22 October 2006 Texas A&M University 22
Thank You!
Questions?