Whidbey Enhancements to C# Jeff Vaughan MSBuild Team July 21, 2004

Similar documents
CSCI-GA Scripting Languages

Topics Covered Thus Far. CMSC 330: Organization of Programming Languages. Language Features Covered Thus Far. Programming Languages Revisited

Topics Covered Thus Far CMSC 330: Organization of Programming Languages

Chapter 9. Subprograms

CMSC 330: Organization of Programming Languages

Programming Languages Third Edition. Chapter 7 Basic Semantics

Subprograms. Copyright 2015 Pearson. All rights reserved. 1-1

CS 330 Lecture 18. Symbol table. C scope rules. Declarations. Chapter 5 Louden Outline

Chapter 9. Subprograms

CS558 Programming Languages

Tail Calls. CMSC 330: Organization of Programming Languages. Tail Recursion. Tail Recursion (cont d) Names and Binding. Tail Recursion (cont d)

Pointers (continued), arrays and strings

G Programming Languages Spring 2010 Lecture 8. Robert Grimm, New York University

CS558 Programming Languages

Pointers (continued), arrays and strings

Weeks 6&7: Procedures and Parameter Passing

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

Introduce C# as Object Oriented programming language. Explain, tokens,

Java: introduction to object-oriented features

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

Lists. Michael P. Fourman. February 2, 2010

Topic 9: Type Checking

Topic 9: Type Checking

G Programming Languages - Fall 2012

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

Outline. Introduction Concepts and terminology The case for static typing. Implementing a static type system Basic typing relations Adding context

CS558 Programming Languages

CSCE 314 Programming Languages. Type System

September 10,

COS 320. Compiling Techniques

The Typed Racket Guide

PIC 10A Objects/Classes

CMSC 4023 Chapter 9. Fundamentals of Subprograms Introduction

The role of semantic analysis in a compiler

Lecture 12: Data Types (and Some Leftover ML)

Discussion. Type 08/12/2016. Language and Type. Type Checking Subtypes Type and Polymorphism Inheritance and Polymorphism

A Short Summary of Javali

G Programming Languages - Fall 2012

Static Semantics. Winter /3/ Hal Perkins & UW CSE I-1

Hacking in C. Pointers. Radboud University, Nijmegen, The Netherlands. Spring 2019

SML Style Guide. Last Revised: 31st August 2011

CMSC330. Objects, Functional Programming, and lambda calculus

JML Class Specifications The Java Modeling Language (Part 2) A Java Class

G Programming Languages Spring 2010 Lecture 6. Robert Grimm, New York University

Types and Type Inference

Structure of Programming Languages Lecture 10

CPS122 Lecture: From Python to Java last revised January 4, Objectives:

CMSC 132: Object-Oriented Programming II

(Refer Slide Time: 4:00)

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

CSE 341 Section 5. Winter 2018

Semantic Analysis. Outline. The role of semantic analysis in a compiler. Scope. Types. Where we are. The Compiler Front-End

9/21/17. Outline. Expression Evaluation and Control Flow. Arithmetic Expressions. Operators. Operators. Notation & Placement

CSci 4223 Lecture 12 March 4, 2013 Topics: Lexical scope, dynamic scope, closures

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

CSE 413 Languages & Implementation. Hal Perkins Winter 2019 Structs, Implementing Languages (credits: Dan Grossman, CSE 341)

Lecture Overview. [Scott, chapter 7] [Sebesta, chapter 6]

The Compiler So Far. CSC 4181 Compiler Construction. Semantic Analysis. Beyond Syntax. Goals of a Semantic Analyzer.

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

CS558 Programming Languages

Java Object Oriented Design. CSC207 Fall 2014

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 17: Types and Type-Checking 25 Feb 08

TYPES, VALUES AND DECLARATIONS

Agenda. Objects and classes Encapsulation and information hiding Documentation Packages

Scope. COMP 524: Programming Language Concepts Björn B. Brandenburg. The University of North Carolina at Chapel Hill

CSc 520 Principles of Programming Languages

C#: framework overview and in-the-small features

Data Types The ML Type System

Data Types. Every program uses data, either explicitly or implicitly to arrive at a result.

Closures. Mooly Sagiv. Michael Clarkson, Cornell CS 3110 Data Structures and Functional Programming

C++11: 10 Features You Should be Using. Gordon R&D Runtime Engineer Codeplay Software Ltd.

Design issues for objectoriented. languages. Objects-only "pure" language vs mixed. Are subclasses subtypes of the superclass?

CPS122 Lecture: From Python to Java

Java How to Program, 10/e. Copyright by Pearson Education, Inc. All Rights Reserved.

The Java Modeling Language (Part 2)

Learn C# Errata. 3-9 The Nullable Types The Assignment Operators

Design Issues. Subroutines and Control Abstraction. Subroutines and Control Abstraction. CSC 4101: Programming Languages 1. Textbook, Chapter 8

Some instance messages and methods

Constructors for classes

Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

Programming in Visual Basic with Microsoft Visual Studio 2010

CSE 341: Programming Languages

COEN244: Class & function templates

CS558 Programming Languages

Introduction to Programming Using Java (98-388)

Anatomy of a Compiler. Overview of Semantic Analysis. The Compiler So Far. Why a Separate Semantic Analysis?

CS558 Programming Languages

Some Notes on Generics in C#

G Programming Languages Spring 2010 Lecture 4. Robert Grimm, New York University

CSC 533: Organization of Programming Languages. Spring 2005

Hierarchical inheritance: Contains one base class and multiple derived classes of the same base class.

Flow-sensitive rewritings and Inliner improvements for the Graal JIT compiler

Using Scala for building DSL s

CS558 Programming Languages

PROGRAMMING IN VISUAL BASIC WITH MICROSOFT VISUAL STUDIO Course: 10550A; Duration: 5 Days; Instructor-led

JavaScript: Sort of a Big Deal,

Compilers. Type checking. Yannis Smaragdakis, U. Athens (original slides by Sam

The Design of Core C++ (Notes)

Control Flow Analysis

Motivation was to facilitate development of systems software, especially OS development.

Transcription:

Whidbey Enhancements to C# Jeff Vaughan MSBuild Team July 21, 2004

Outline Practical Partial types Static classes Extern and the namespace alias qualifier Cool (and practical too) Generics Nullable Types Anonymous Methods

Partial types simplify source management. Everett C# classes could not span multiple files. Very large files can be unwieldy to work with. Teams without source control can split classes and work concurrently without worrying about merging. Code generators and programmers could conflict when editing some classes In Whidbey we can split a class across files by using the partial keyword and avoid these problems.

Partial types are combined at compile time. File1.cs: public partial class Foo{ void MyHandwrittenFun(){ public partial class Foo{ void AnotherFun(){ Is equivalent to: public partial class Foo { void MyHandwrittenFun(){ void AnotherFun(){ void MyGeneratedFun(){ File2.cs: public partial class Foo{ void MyGeneratedFun(){

We can use static classes to enforce coding conventions. A common pattern is to write a class composed of only static members. (e.g. mathematical operators) Whidbey C# uses static class Foo to denote that Foo cannot have instance methods or members. The static modfier is checked at compile time. The Environment.HasShutDownStarted was (accidentally) an instance variable in the 1.0 framework and users couldn't access it; a static class declaration would have caught this.

Everett projects can t contain two entities with the same name. Generally this a good thing. Readers know which entity is being referred to. C# doesn t need to define shadowing semantics. Sometimes it s useful to allow conflicting names Different versions of a library can t be linked together. Common names may exist in different code bases.

Externs let us use libraries with name collisions. Compiling with csc /r:x=foo.dll roots foo s namespace hierarchy in alias X. Multiple libraries may be placed in the same alias. The command csc /r:bar.dll implicitly adds bar s members to the global namespace. The extern alias X command lets a source file treat X as a namespace root.

The namespace alias qualifier provides access to aliased names. The namespace alias qualifier specifies an which namespace to use to resolve a symbol. To access the MyPackage.Math.Add method in the OLD alias use OLD::MyPackage.Math.Add(a,b); To access the MyPackage.Math.Add method in global namespace use global::mypackage.math.add(a,b); or using MP = MyPackage; MP::Math.Add(a,b);

Generics are modern extension to traditional type systems. A generic structure is structure that is parameterized over a type or set of types. Generics are a fusion of bounded parametric polymorphism and subtyping. Parametric polymorphism: Type variables Bounded parametric polymorphism: Type variables with constraints Subtyping: Types can be swapped when signatures match

Consider a simple stack based evaluator in Everett public class Stack { object[] items; int count; public void Push(object item) {... public object Pop() {... public class Evaluator { public Stack s; //stack of ints public int step(token tok) { if(tok.isint()) push (s.push(tok.toint()); if(tok.isplus()) push ((int)(s.pop()) + (int)(s.pop()));...

and notice how things might break. We have two downcasts: (int)s.pop() Bad values could wind up in our stack Serialization / deserialization Pre-Processing If an other code breaks the stack we will get an exception from Evaluator and not from the responsible method.

Everret C# doesn t provide good ways to safeguard the stack. Wrap Stack using a specifically typed class or method set (define IntStack) Pollutes name space. Lots of redundant code if done frequently. Add lots of runtime checks You can change how gracefully you fail, but you can t stop from failing. We have better things to do with the CPU than run lots of checks.

With generics we can write code public class Stack<T> { T[] items; int count; public void Push(T item) {... public T Pop() {... public class Evaluator { public Stack<int> s; public int step(token tok) { if(tok.isint()) push (s.push(exp.toint()); if(tok.isplus()) push (s.pop() + s.pop());...

that is safer and faster. Now s.pop() returns int. Member s has type stack<int>. Code containing s.push(x) won t compile unless x is an int. The compiler enforces the class semantics. No execution time wasted on casts.

Sorting requires another construct. The following won t compile: public class SortableArray<T>{ T[] items; int count; public this[int i] {... public void Sort() {... items[i].compareto(x)... And this is not really safe: public void Sort() {... ((Comparable)items[i]).CompareTo(x)...

Using type constraints we can statically guarantee sort is safe. class SortableArray<T> where T: IComparable { T[] items; int count; public this[int i] {... public void Sort() {... items[i].compareto(x)... Type variable T is constrained to implement the IComparable interface. Constraints may include any number of interfaces. a base class. a default constructor.

We can gain expressive power by generalizing methods. Consider writing a function to merge two arrays: static void merge<t>(sortedarray<t> x, SortedArray<T> y) where T: Icomparable {... Note that we must constrain T in order for the SortedArray<T> to be a valid type. In some cases calls to merge may omit the explicit type parameter (type inference).

We can use generic interfaces and multiple type parameter. public interface Indexable<E> { E[] makeindex(); public class Map<K, V> : Indexable<K> where K: System.IComparable where V: new() { K item = default(k); public Map(){ public void Sort(){item.CompareTo(item); public K[] makeindex(){return null;

Modern languages have different levels of support for generics.

Implementation efficiencies vary between languages.

Nullable types provide a principled way of dealing with unknown data. Nullable type int? represents an integer that can be set to null. Nullable primitives correspond well to databases and xml readers. Nulls propagate through arithmetic operations. Type foo? and System.Nullable<foo> are completely interchangeable.

Nullable exposes few standard operations. Properties & Operations (n,m instances of T?) Property n.hasvalue is true if n contains a value. Property n.value is null or the contained value. The null coalescing operator (??) is defined such that n?? m is n if n.hasvalue, or m otherwise. Conversions Values of type T can implicitly convert to T?. Values of T? must be explicitly converted to T. Values of T?? and T? can convert implicitly in both directions.

Nullable can be conceptualized as characteristic of a type. Making a nullable type more nullable by adding many? s doesn t effect the derived types semantics. So int?, int??, and int??? all work the same. This provides flexibility when nulling type variables:

Nullable types behave predictably strangely. int? x = 40; int? t = (int)x+y; int y = 2; int?? u = 312; int? z = null; int?? v = z; Console.WriteLine(t); // 42 Console.WriteLine(z?? y); // 2 Console.WriteLine((z+y) == null); // True Console.WriteLine(u); // 312 Console.WriteLine(u.GetType().ToString()); //System.Nullable`1[System.Nullable`1[System.Int32]] Console.WriteLine(v.HasValue); // False

Corner cases make nullable types hard to work with. The compiler emits a warning when declaring nullable ref types (e.g. string?). Nullable ref types don t allow for reference equality comparisons (e.g. ==). For consistency with databases, logical operations on bool? are ternary. (e.g. null & false == false)

Nullable types appear to be one step toward more expressive types. Foo Sometype Foo! Nonnull Foo Foo? Nullable Foo Foo* Possibly empty stream of Foos Foo+ - Non-empty stream of Foos

Many languages make it easy to manipulate functions. First class functions can be passed around. Mixing anonymous and named functions increases code readability. (fn x => x+1) fun f(x) = x + 1 Closures provide a convenient way to build predicates. let val t =... in filter (fn v => v = t) [1, 2, 3] end Lisp, Scheme, SML, Haskell, and Python provide these features.

Everett C# delegates are hard to use. All methods needed to be named. Delegate use and definition are often separated by many lines. One time use delegates pollute the local name space and may confuse readers. Lack of variable capture means any delegate state needed must be declared as class members. Delegate use was too verbose.

Whidbey adds syntactic sugar for manipulating methods. Delegate object creation is now implicit. Everret: MyEvent += new delegatetype(mymethod); Whidbey: MyEvent += mymethod; Delegates can be anonymous. MyEvent += delegate(int foo) {return foo+1;

A logger using an Everett delegate is messy public delegate void Printer(string s); public class Logger { Printer logprinter; public Logger(Printer p){logprinter = p; public void LogString(string s){logprinter(s); string myprefix = ">>"; void MyPrinter(string s) {Console.WriteLine(myPrefix + s); public void Test() { Logger l = new Logger(new Printer(MyPrinter)); l.logstring("hello world");

but Whidbey helps us clean up. public delegate void Printer(string s); public class Logger { Printer logprinter; public Logger(Printer p){logprinter = p; public void LogString(string s){logprinter(s); public void Test() { string myprefix = ">>"; Logger l = new Logger(delegate (string s) {Console.WriteLine(myPrefix + s); ); l.logstring("hello world");

The Whidbey logger is significantly more readable. C# is lexical scoping, and, in the Whidbey code, it s immediately obvious that myprefix will not change during execution. Readers of the Whidbey code will not encounter MyPrinter at the top level. Delegate objects no longer need to be created using new. This works for named delegates too!

Useful Links CSharp Spec http://msdn.microsoft.com/vcsharp/team/language/ Eric Gunnerson's Blog http://weblogs.asp.net/ericgu/ Brandon Bray s Blog http://weblogs.asp.net/branbray/ Interview explaining C# design decisions http://www.artima.com/intv/generics.html Microsoft Research on types http://research.microsoft.com/~emeijer/papers/xs.pdf