1 / 82

.NET Programming Language Research @ MSR Cambridge

.NET Programming Language Research @ MSR Cambridge. Nick Benton Microsoft Research Cambridge. MSR Cambridge Programming Principles and Tools Group. Luca Cardelli Nick Benton Cedric Fournet Andy Gordon Tony Hoare Andrew Kennedy Simon Peyton Jones Don Syme Simon Marlow Claudio Russo

Jims
Download Presentation

.NET Programming Language Research @ MSR Cambridge

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. .NET Programming Language Research @ MSR Cambridge Nick Benton Microsoft Research Cambridge

  2. MSR Cambridge Programming Principles and Tools Group • Luca Cardelli • Nick Benton • Cedric Fournet • Andy Gordon • Tony Hoare • Andrew Kennedy • Simon Peyton Jones • Don Syme • Simon Marlow • Claudio Russo • Mark Shields • + visitors, PhD students, interns,… MS.NET days March 2002

  3. .NET in MSR Programming Principles and Tools Group • Verifier spec (POPL) • CLR design feedback • Project 7 (Babel) • SML.NET(ICFP,ICFP,HOOTS) • Generics for C# and .NET(PLDI) • Extended IL (Babel) • Polyphonic C#(FOOL, ECOOP) • Stack-Walking Security analysis (POPL) • Assertions MS.NET days March 2002

  4. Part 1SML.NET Nick Benton, Andrew Kennedy and Claudio Russo

  5. Advanced Programming Languages on the CLR • .NET and the CLR provide a great opportunity for programming language designers and implementers: • The runtime provides services (execution engine, garbage collection,…) which make producing a good implementation of your language easier • The frameworks & libraries mean you can actually do useful things with your new language (graphics, networking, database access, web services,…) • Multi-language component-based programming makes it much more practical for other people to use your language in their own projects MS.NET days March 2002

  6. Our favourite language: Standard ML • A safe, modular, strict, higher-order, functional, polymorphic programming language with compile-time type checking and type inference, garbage collection, exception handling, immutable data types, pattern-matching and updatable references, abstract data types, and parametric modules. • with several efficient implementations • and a formal definition with a proof of soundness. • (Scheme+types+real syntax, Haskell with call by value evaluation) MS.NET days March 2002

  7. Some SML datatype order = LESS | GREATER | EQUAL datatype 'a Tree = Empty | Node of 'a * ('a Tree) * ('a Tree) fun contains compare (x, Empty) = false | contains compare (x, Node(v, left, right)) = (case compare (x,v) of LESS => contains compare (x,left) | GREATER => contains compare (x, right) | EQUAL => true ) contains : ('a * 'a -> order) -> ('a * 'a Tree) -> bool MS.NET days March 2002

  8. What is SML.NET? • Compiler for SML that targets verifiable CIL • Research Issues: • Can we compile a polymorphic functional language to a monomorphic, object-oriented runtime? • Yes • How can we make it produce fast, compact code? • Whole-program optimising compiler. Monomorphisation. Representation tricks. Novel typed intermediate language using monads to track side-effects. • How can we make cross-language working easy? • We extend SML to support all of the .NET CLS (Common Language Specification), providing smooth bidirectional interoperability with .NET framework libraries & other .NET languages MS.NET days March 2002

  9. Previous approaches to interop • Bilateral interface with marshalling and explicit calling conventions (e.g. JNI, O’Caml interface for C). • Awkward, ugly, tied to one implementation, only for experts • Multilateral interface with IDL (e.g. COM, CORBA) together with particular language mappings (e.g. H/Direct, Caml COM, MCORBA). • Have to write IDL and use tools, tend to be lowest-common denominator, memory management often tricky MS.NET days March 2002

  10. Interop in .NET • Languages share a common higher-level infrastructure (CLR): • shared heap means no tricky cross-heap pointers (cf reference counting in COM) • shared type system means no marshalling (cf string<->char* marshalling for Java<->C) • shared exception model supports cross-language exception handling MS.NET days March 2002

  11. SML.NET interop • Sounds great, but SML is not object-oriented • So we are going to have to do some work… • Possible approaches to interop: • do not extend language; instead provide wrappers that give a functional view of a CLS library (Haskell, Mercury). • Powerful functional type systems can go a very long way towards modelling OO type systems • redesign the language (OO-SML?) • Our approach – a middle way: • re-use existing features where appropriate (non-object-oriented subset) • extend language for convenient interop when “fit” is bad (object-oriented features) • live with the CLS at boundaries: don’t try to export complex ML types to other languages (what would they do with them?) MS.NET days March 2002

  12. Re-use SML features multiple args tuple void unit null NONE static field val binding SML static method fun binding CLS namespace structure delegate first-class function mutability ref using open private fields local decls MS.NET days March 2002

  13. Extend language type test cast patterns class definitions classtype instance method invocation obj.#meth instance field access obj.#fld custom attributes attributes in classtype casts exp :> ty CLS SML MS.NET days March 2002

  14. Extract from WinForms interop open System.Windows.Forms System.Drawing System.ComponentModelfun selectXML () = let val fileDialog = OpenFileDialog() in fileDialog.#set_DefaultExt("XML"); fileDialog.#set_Filter("XML files (*.xml) |*.xml"); if fileDialog.#ShowDialog() = DialogResult.OK then case fileDialog.#get_FileName() of NONE => () | SOME name => replaceTree (ReadXML.make name, "XML file '" ^ name ^ "'") else () end no args = ML unit value CLS Namespace = ML structure static method = ML function static constant field = ML value instance method invocation CLS string = ML string null value = NONE And note that there are no explicit types in this code MS.NET days March 2002

  15. Ray tracing in ML • ICFP programming competition: build a ray tracer in under 3 days • 39 entries in all kinds of languages: • C, C++, Clean, Dylan, Eiffel, Haskell, Java, Mercury, ML, Perl, Python, Scheme, Smalltalk • ML (Caml) was in 1st and 2nd place MS.NET days March 2002

  16. Ray tracing in SML.NET • Translate winning entry to SML • Add WinForms interop • Run on .NET CLR • Performance on this example twice as good as popular optimizing native compiler for SML • (though on others we’re twice as bad) MS.NET days March 2002

  17. Visual Studio Integration • Bootstrap the compiler to produce a .NET component for parsing, typechecking, etc. of SML • Use interlanguage working extensions to expose that as a COM component which can be glued into Visual Studio • Write new ML code to handle syntax highlighting, tooltips, error reporting, etc. MS.NET days March 2002

  18. Part 2Generics in the CLR and C# Andrew Kennedy and Don Syme

  19. Note: This is not in V1 of the CLR It will be in V2    MS.NET days March 2002

  20. Part 1: Introduction MS.NET days March 2002

  21. What are generics? • Types which are parameterized by other types, e.g. Stack<int>, Stack<string> • Generics, templates, parametric polymorphism • Ada, Eiffel, C++, ML, Haskell, Mercury, Component Pascal,… • Promote code reuse, increase type safety, better performance • Good for collections, higher-order programming and generally building higher-level, reusable abstractions MS.NET days March 2002

  22. Generic code in C# today (1) class Stack { private Object[] items; private int nitems; Stack() { nitems = 0; items = new Object[50]; }Object Pop() { if (nitems == 0) throw new EmptyException(); return items[--nitems]; } void Push(Object item) {... return items[nitems++]; }} MS.NET days March 2002

  23. Generic code in C# today (2) Stack s = new Stack(); s.Push(1); s.Push(2); int n = (int)(s.Pop()) + (int)(s.Pop()); • What’s wrong with that? • It’s inexpressive. Type system doesn’t document what should be in a particular stack. • It’s unsafe. Type errors (s.Push(“2”); ) lead to runtime exceptions instead of being caught by compiler • It’s ugly. Casts everywhere. • It’s slow. Casts are slow, and converting base types (e.g. ints) to Objects involves expensive boxing. MS.NET days March 2002

  24. Generic code in C# tomorrow (1) class Stack<T> { private T[] items; private int nitems; Stack() { nitems = 0; items = new T[50]; }T Pop() { if (nitems == 0) throw new EmptyException(); return items[--nitems]; } void Push(T item) { if (items.Length == nitems) {T[] temp = items; items = new T[nitems*2]; Array.Copy<T>(temp, items, nitems); } items[nitems++] = item; }} MS.NET days March 2002

  25. Generics: large design space But can type instantiations can be non-reference? Set<int> List<float> • Parameterized classes, interfaces, and methods e.g. Do you erase types at runtime? // two-parameter class class Dict<K,D> { ... } // parameterized interface interface IComparable<T> { ... } // parameterized struct struct Pair<A,B> { ... } // generic method T[] Slice<T>(T[] arr, int start, int count) Do we have exact runtime type information?if (x is Set<int>) .... Do you share code? Constraints? class C<T: IFoo, IBar> { ... } What goes in the CLR? What goes in the compilers? MS.NET days March 2002

  26. Generic interfaces interface IDictionary<K,D> { D Lookup(K); ... } class Dictionary<K,D> : IDictionary<K,D> { D Lookup(K); ... } Dictionary<String,String> MS.NET days March 2002

  27. Generic methods A generic method is just a family of methods, indexed by type. static void Sort<T> (T[]) { ... } int[] x = { 5,4,3,2 }; Sort(x); MS.NET days March 2002

  28. Explicit Constraints interface IComparable<T> { static int Compare(T,T); } class BinaryTree<T : IComparable<T> >{ void insert(T x) { switch (x.Compare(y)) { ... } } T y; Tree<T> left; Tree<T> right;} Static constraints are available via interfaces. MS.NET days March 2002

  29. Part 2: Implementing Generics for the .NET CLR MS.NET days March 2002

  30. Generics: Our design • Parameterized classes, interfaces, structs, methods, delegates Yes • Exact runtime types: Yes if (x is Set<string>) { ... } • Instantiations at value types: Yes Set<String> Set<int> List<float> • Constraints: Yes (by interfaces) class C<T: IComponent> • Variance: No Set<String> is not subtype-related to Set<Object> MS.NET days March 2002

  31. How does it work? 1a. Look for Stack<int>1b. Nothing exists yet, so create structures for Stack<int> Stack<int> si = new Stack<int>();Stack<int> si2 = new Stack<int>();Stack<string> ss = new Stack<string>();Stack<object> so = new Stack<object>();si.Push(5);ss.Push(“Generics”);so.Push(myObj); 2a. Look for Stack<int>2b. Type already loaded! 3a. Look for Stack<string>3b. <string> not compatible with <int>, so create structures for Stack<string> 4a. Look for Stack<object>4b. <object> compatible with <string>, so re-use Stack<string> MS.NET days March 2002

  32. How does it work? Stack<int> si = new Stack<int>();Stack<int> si2 = new Stack<int>();Stack<string> ss = new Stack<string>();Stack<object> so = new Stack<object>();si.Push(5);ss.Push(“Generics”);so.Push(myObj); Compile code for Stack<int>.Push Compile code for Stack<string>.Push Re-use code from Stack<string>.Push MS.NET days March 2002

  33. Implementing Generics (0) • Dynamic loading & JIT compilation change many fundamental assumptions • Can consider code generation at runtime • Can use more dynamic data structures • The current challenge is to implement all of: • exact runtime types + code sharing + dynamic loading + non-uniform instantiations MS.NET days March 2002

  34. Implementing Generics (1) • Our implementation: 1. Dynamic code expansion and sharing • Instantiating generic classes and methods is handled by the CLR. • Generate/compile code as necessary • Use JIT compiler • Share code for “compatible” instantiations • Compatibility is determined by the implementation MS.NET days March 2002

  35. Implementing Generics (2) • Our implementation: 1. Dynamic code expansion and sharing 2. Pass and store runtime type information • Objects carry runtime type information • We record this information by duplicating vtables. • Other options are possible. • Generic methods take an extra parameter • The active type context is always recoverable MS.NET days March 2002

  36. Implementing Generics (3) • Our implementation: 1. Dynamic code expansion and sharing 2. Pass and store runtime type information 3. Optimized use of runtime type information MS.NET days March 2002

  37. Generics: Performance • 1. Instantiations at value types • Stack with repeated push and pops of 0...N elements (a) List_int (b) List (i.e. existing collection class) (c) List<int> • 5X speedup (c) v. (b) • 2. No casts • 20% speed on similar micro-benchmarks • 3. Runtime type computations • Generic allocation ~10% slower in generic code MS.NET days March 2002

  38. Generics: Design Comparison MS.NET days March 2002

  39. Comparison with C++ templates • What C++ gets wrong: • Modularity • need to see the template at link time • Efficiency • nearly all implementations code-expand • Safety • not checked at declaration & use, but at link time • Simplicity • very complicated MS.NET days March 2002

  40. Comparison with C++ templates • What we get right: • Modularity: • no need to see the generic IL until runtime • Efficiency: • code expansion managed by the VM • Safety: • check at declaration & use • Simplicity: • there are some corners, but the mechanism is simple to explain & use MS.NET days March 2002

  41. Summary • A world first: cross-language generics. • A world first: generics in a high-level virtual machine design. • Implementation: • The virtual machine (runtime) level is the right place to implement generics for .NET • Potential for: • Other implementation techniques (more aggressive sharing, some boxing, etc.) • Further extensions (type functions, variance, more expressive constraints) • Good performance MS.NET days March 2002

  42. Part 3Polyphonic C# Nick Benton, Luca Cardelli and Cedric Fournet

  43. Introduction MS.NET days March 2002

  44. Programming in a networked world • Developers now have to work in a • Concurrent • Distributed • High latency • (& low reliability, security sensitive, multi-everything) environment. • Which is hard • And they’re mostly not very good at it • Try using Outlook over dialup  MS.NET days March 2002

  45. Asynchronous communication • Distribution => concurrency + latency => asynchrony => more concurrency • Message-passing, event-based programming, dataflow models • For programming languages, coordination (orchestration) languages & frameworks, workflow MS.NET days March 2002

  46. Language support for concurrency • Make invariants and intentions more apparent (part of the interface) • Good software engineering • Allows the compiler much more freedom to choose different implementations • Also helps other tools MS.NET days March 2002

  47. .NET Today • Multithreaded execution environment with lock per object • C# has “lock” keyword, libraries include traditional shared-memory synchronization primitives (mutexes, monitors, r/w locks) • Delegate-based asynchronous calling model, events, messaging • Higher level frameworks built on that • Hard to understand, use and get right • Different models at different scales • Support for asynchrony all on the caller side – little help building code to handle messages (must be thread-safe, reactive, and deadlock-free) MS.NET days March 2002

  48. Polyphonic C# • An extension of the C# language with new concurrency constructs • Based on the join calculus • A foundational process calculus like the p-calculus but better suited to asynchronous, distributed systems • A single model which works both for • local concurrency (multiple threads on a single machine) • distributed concurrency (asynchronous messaging over LAN or WAN) MS.NET days March 2002

  49. The Language MS.NET days March 2002

  50. In one slide: • Objects have both synchronous and asynchronous methods. • Values are passed by ordinary method calls: • If the method is synchronous, the caller blocksuntil the method returns some result (as usual). • If the method is async, the call completes at once and returns void. • A class defines a collection of synchronization patterns (chords), which define what happens once a particular set of methods have been invoked on an object: • When pending method calls match a pattern, its body runs. • If there is no match, the invocations are queued up. • If there are several matches, an unspecified pattern is selected. • If a pattern containing only async methods fires, the body runs in a new thread. MS.NET days March 2002

More Related