SlideShare a Scribd company logo
1 of 90
Download to read offline
C# Light
A proposal for a new C# syntax
Inspired by a post by PhilTrelford
UPGRADE
YOUR MONITOR
Read these slides
and you might get a free
triple height monitor*
*or visual equivalent
Why change something that works?
Why change something that works?
Because...
Why not compete with scripting languages?
Lightweight, but keep the power of static typing.
Why change something that works?
Because...
Why not compete with scripting languages?
Lightweight, but keep the power of static typing.
Because...
Times are changing. Defaults should change too.
Make immutability the new default.
Why change something that works?
Because...
Why not compete with scripting languages?
Lightweight, but keep the power of static typing.
Because...
Times are changing. Defaults should change too.
Make immutability the new default.
Because...
Many common patterns are too hard.
Make good practices easy (but allow deviations).
! HEALTH WARNING !
These slides are for consumption
by open-minded programmers
ONLY.
When taken with pre-existing
closed-mindedness, can cause
shock, high blood pressure,
anxiety, nausea, confusion and
panic.
You must be at least this
open minded to read
these slides
How open minded are you?
Slime mould
Bony fishes
People who
don't use LINQ
People who don't
use generics
Opposable
thumbs
People who
want C# v6
People who
use lambdas
Vision for C# Light
Clean and lightweight code.
Immutability by default.
Common scenarios are easy.
We make mutability a special case,
rather than the other way around.
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// <summary>
/// Full name
/// </summary>
public string Name
{
get { return _name; }
}
/// <summary>
/// Birthday
/// </summary>
public DateTime Birthday
{
get { return _birthday; }
}
}
Here is a typical
immutable class in C#
which we'll use as an
example throughout.
Here is a typical
immutable class in C#
which we'll use as an
example throughout.
27 lines of code.
Can we do better?
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// <summary>
/// Full name
/// </summary>
public string Name
{
get { return _name; }
}
/// <summary>
/// Birthday
/// </summary>
public DateTime Birthday
{
get { return _birthday; }
}
}
Here is a typical
immutable class in C#
which we'll use as an
example throughout.
27 lines of code.
Can we do better?
Why not remove the lines
that don't contain useful
information?
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// <summary>
/// Full name
/// </summary>
public string Name
{
get { return _name; }
}
/// <summary>
/// Birthday
/// </summary>
public DateTime Birthday
{
get { return _birthday; }
}
}
In a typical C# project
less than 50% of the
lines contain useful
information!
Surely we can do better?
Proposal 1:
Simplify doc strings
We can start by
simplifying the doc
strings.
Let's make "summary"
the default.
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// <summary>
/// Full name
/// </summary>
public string Name
{
get { return _name; }
}
/// <summary>
/// Birthday
/// </summary>
public DateTime Birthday
{
get { return _birthday; }
}
}
We can start by
simplifying the doc
strings.
Let's make "summary"
the default.
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// <summary>
/// Full name
/// </summary>
public string Name
{
get { return _name; }
}
/// <summary>
/// Birthday
/// </summary>
public DateTime Birthday
{
get { return _birthday; }
}
}
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// Full name
public string Name
{
get { return _name; }
}
/// Birthday
public DateTime Birthday
{
get { return _birthday; }
}
}
We can start by
simplifying the doc
strings.
Let's make "summary"
the default.
4 lines saved!
Proposal 2:
Automatically create
backing fields from
constructor parameters
Yes, I know C# 6 has something
similar. Keep reading...
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// Full name
public string Name
{
get { return _name; }
}
/// Birthday
public DateTime Birthday
{
get { return _birthday; }
}
}
Because immutability is
the default, we can
simplify further.
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// Full name
public string Name
{
get { return _name; }
}
/// Birthday
public DateTime Birthday
{
get { return _birthday; }
}
}
Why not automatically
define and initialize read-
only backing fields from
the constructor
parameters?
public class Person
{
public Person(string name, DateTime birthday)
{
}
/// Full name
public string Name
{
get { return name; }
}
/// Birthday
public DateTime Birthday
{
get { return birthday; }
}
}
Of course, you can still define mutable
private fields in the usual way.
Unlike C# 6, you don't need to in the
immutable case.
4 lines saved!
Why not automatically
define and initialize
read-only backing fields
from the constructor
parameters?
Proposal 3:
Merge the primary constructor
with the class definition
C# 6 has this too.
public class Person
{
public Person(string name, DateTime birthday)
{
}
/// Full name
public string Name
{
get { return name; }
}
/// Birthday
public DateTime Birthday
{
get { return birthday; }
}
}
How often do you have
more than one
constructor?
public class Person
{
public Person(string name, DateTime birthday)
{
}
/// Full name
public string Name
{
get { return name; }
}
/// Birthday
public DateTime Birthday
{
get { return birthday; }
}
}
How often do you have
more than one
constructor?
Why not merge the
constructor with the class
definition?
public class Person(string name, DateTime birthday)
{
/// Full name
public string Name
{
get { return name; }
}
/// Birthday
public DateTime Birthday
{
get { return birthday; }
}
}
How often do you have
more than one
constructor?
4 more lines saved!
Why not merge the
constructor with the class
definition?
You can still define secondary
constructors separately if you
need to.
Proposal 4:
(this one is controversial)
Proposal 4:
Use indentation instead
of curly braces
public class Person(string name, DateTime birthday)
{
/// Full name
public string Name
{
get { return name; }
}
/// Birthday
public DateTime Birthday
{
get { return birthday; }
}
}
Do we really need the
braces?
The indentation already
gives us all the clues we
need.
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime Birthday =
get { return birthday; }
Do we really need the
braces?
The indentation already
gives us all the clues we
need.
6 more lines saved!
You can still have explicit
begin/end markers for blocks if
you need to.
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime Birthday =
get { return birthday; }
Add "equals" as an indicator to
start a new block.
People who
complain about
using a language
with syntactic
whitespace
People who
have spent time
using a language
with syntactic
whitespace
"Oddly enough, Python's use of whitespace stopped feeling unnatural
after about twenty minutes. I just indented code, pretty much as I
would have done in a C program anyway, and it worked."
- Eric Raymond
Helpful Venn Diagram
Overlap
Observation
With these 4 proposals:
27 lines of code has shrunk
to 9 lines!
C#
Because
"C# Light"
means you see
3x more code
on your screen!
Why use "C# light"?
Reason 1
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// <summary>
/// Full name
/// </summary>
public string Name
{
get { return _name; }
}
/// <summary>
/// Birthday
/// </summary>
public DateTime Birthday
{
get { return _birthday; }
}
}
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime Birthday =
get { return birthday; }
Why use "C# light"?
C#
C# Light
Reason 2 Because
"C# Light"
means you write
1/3 as much
code.
Proposal 5:
Eliminate syntax noise
There is a lot of syntax "noise"
that is not needed, IMO.
Proposal 5a:
Eliminate "get" keyword for
immutable properties
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime Birthday =
get { return birthday; }
The class is immutable.
Every property is "get"
only.
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime Birthday =
get { return birthday; }
The class is immutable.
Every property is "get"
only.
So why bother with the
"get" keyword?
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
return name;
/// Birthday
public DateTime Birthday =
return birthday;
The class is immutable.
Every property is "get"
only.
So why bother with the
"get" keyword?
A bit cleaner, IMO.
Proposal 5b:
Eliminate "return"
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
return name;
/// Birthday
public DateTime Birthday =
return birthday;
Why not take a leaf out of
other languages and
make the return implicit
for the last line in a
block?
This is the
"expression-based"
approach.
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
name;
/// Birthday
public DateTime Birthday =
birthday;
Why not take a leaf out of
other languages and
make the return implicit
for the last line in a
block?
Proposal 5c:
Make immutable properties
public by default
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
name;
/// Birthday
public DateTime Birthday =
birthday;
The properties are
immutable.
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
name;
/// Birthday
public DateTime Birthday =
birthday;
The properties are
immutable.
Why not make them
public by default. There's
no way a client of the
object can corrupt it!
class Person(string name, DateTime birthday) =
/// Full name
string Name =
name;
/// Birthday
DateTime Birthday =
birthday;
The properties are
immutable.
Why not make them
public by default. There's
no way a client of the
object can corrupt it!
You can still use the "private"
keyword if you need to.
Only the default has changed.
Proposal 5d:
Make semicolons optional
class Person(string name, DateTime birthday) =
/// Full name
string Name =
name;
/// Birthday
DateTime Birthday =
birthday;
How often do you have
more than one semicolon
on a line?
Excepting for loops, of course.
class Person(string name, DateTime birthday) =
/// Full name
string Name =
name
/// Birthday
DateTime Birthday =
birthday
How often do you have
more than one semicolon
on a line?
So why bother?
Observation:
Removing syntax noise opens up
more opportunities to save space.
class Person(string name, DateTime birthday) =
/// Full name
string Name =
name
/// Birthday
DateTime Birthday =
birthday
Why not move short code
fragments on to the same
line?
class Person(string name, DateTime birthday) =
/// Full name
string Name = name
/// Birthday
DateTime Birthday = birthday
Why not move short code
fragments on to the same
line?
C# 6 plans to have "expression-
bodied members" too.
Proposal 6:
Use type inference for properties
class Person(string name, DateTime birthday) =
/// Full name
string Name = name
/// Birthday
DateTime Birthday = birthday
Why do we have to
repeat the type?
Can't the compiler
figure it out for us?
class Person(string name, DateTime birthday) =
/// Full name
Name = name
/// Birthday
Birthday = birthday
Why do we have to
repeat the type?
Can't the compiler
figure it out for us?
Cleaner, but now we can't tell
that it's a property!
class Person(string name, DateTime birthday) =
/// Full name
member Name = name
/// Birthday
member Birthday = birthday
We need some way to indicate properties.
Let's use the word "member".
class Person(string name, DateTime birthday) =
/// Full name
member Name = name
/// Birthday
member Birthday = birthday
/// Age
member Age() =
DateTime.Today.Subtract(birthday).Days / 365
We can define methods the same way.
class Person(string name, DateTime birthday)
{
/// Full name
public string Name { get; } = name;
/// Birthday
public DateTime Birthday { get; } = birthday;
/// Age
public int Age() =>
DateTime.Today.Subtract(birthday).Days / 365;
}
Here is the C# 6
equivalent with
auto-properties and
expression-bodied
members
This is nice and compact too.
Still need explicit types and
"public" keyword, though.
Review
Let's review the proposals:
1) Make doc strings more compact
2) Move backing fields into constructor (because immutable)
3) Move constructor into class definition
4) Remove curly braces
5) Remove syntax noise
- Remove "get" keyword from immutable properties
- Return last value in a block automatically
- Make immutable properties public by default
- Make semicolons optional
6) Allow types of properties to be inferred from constructor
class Person(string name, DateTime birthday) =
/// Full name
member Name = name
/// Birthday
member Birthday = birthday
public class Person
{
public Person(string name, DateTime birthday)
{
_name = name;
_birthday = birthday;
}
private readonly string _name;
private readonly DateTime _birthday;
/// <summary>
/// Full name
/// </summary>
public string Name
{
get { return _name; }
}
/// <summary>
/// Birthday
/// </summary>
public DateTime Birthday
{
get { return _birthday; }
}
}
Normal C#
Before and After
C# Light
27 lines before.
7 lines after.
What about the goal
"make common scenarios easy"?
The next set of proposals aims to do
exactly this.
Proposal 7:
Automatically generate
code for equality
class Person(string name, DateTime birthday) : IEquatable<Person> =
/// Full name
member Name = name
/// Birthday
member Birthday = birthday
override Equals(Person obj) =
if (obj == null)
return false
Person p = obj as Person
if ((Person)p == null)
{
return false
}
// Return true if the fields match:
(name == p.Name) && (birthday == p.Birthday)
override Equals(Person p) =
if ((object)p == null)
return false
// Return true if the fields match:
(name == p.Name) && (birthday == p.Birthday)
override GetHashCode() =
name.GetHashCode ^ birthday.GetHashCode
How often do you have to
write all this equality
code?
[StructuralEquality]
class Person(string name, DateTime birthday) =
/// Full name
member Name = name
/// Birthday
member Birthday = birthday
Why not let the compiler
write it for you!
You just need to use a
special attribute.
How often do you have to
write all this equality
code?
Proposal 8:
Compact syntax for DTOs
[StructuralEquality]
class Person(string name, DateTime birthday) =
/// Full name
member Name = name
/// Birthday
member Birthday = birthday
"Dumb" objects with no
methods (aka DTOs) are
very common.
Since they have no
methods, can we make
the syntax even simpler?
[StructuralEquality]
class Person(string name, DateTime birthday) =
/// Full name
member Name = name
/// Birthday
member Birthday = birthday
"Dumb" objects with no
methods (aka DTOs) are
very common.
Since they have no
methods, can we make
the syntax even simpler?
class Person = {string name, DateTime birthday}
var person = {name="Alice", birthday=Today}
Yes, we can. Just define a
named class in the same
way as an anonymous
type.
Proposal 9:
Create non-nullable reference types
class Person = {string name, DateTime birthday}
// ok
var person = {name="Alice", birthday=Today}
// error
person = null
This one is a no-brainer.
If a class is defined with:
• the [StructuralEquality] attribute
• the anonymous type syntax
then it is automatically non-nullable
No more null testing
needed!
Proposal 10:
Allow anonymous types
to implement interfaces
public class TempDisposable: IDisposable
{
public void Dispose()
{
Console.Write("Disposed");
}
}
var tempDisposable = new TempDisposable();
Sometimes you don't
want to have to create a
whole class just to
implement an interface
temporarily.
var tempDisposable =
{new IDisposable with
member this.Dispose() = Console.Write("Disposed") }
Sometimes you don't
want to have to create a
whole class just to
implement an interface
temporarily.
Why not use the
"anonymous type" syntax
to create an object
without having to create
a class explicitly?
Proposal 11:
Allow subclasses to be merged into a
single "case" class
Requirement: We accept three forms of payment:
Cash. Check or Card.
For Cash we don't need any extra information
For Checks we need a check number
For Cards we need a card type and card number
This one needs a bit of background.
Say that you have a requirement for taking
payments, as shown below:
How would you implement this?
interface IPaymentMethod
{..}
class Cash() : IPaymentMethod
{..}
class Check(int checkNo): IPaymentMethod
{..}
class Card(string cardType, string cardNo) : IPaymentMethod
{..}
You would probably implement it as an
interface and a set of subclasses, like this:
interface IPaymentMethod
{..}
class Cash() : IPaymentMethod
{..}
class Check(int checkNo): IPaymentMethod
{..}
class Card(string cardType, string cardNo) : IPaymentMethod
{..}
But that is a lot of code for such a common scenario. Also...
(a) The implementation and data is
probably scattered around
four separate files.
(b) The requirements are hard to
reconstruct from the classes.
(c) The subclasses are not "closed".
Any class that implemented the interface would work.
This might not be what you want!
class PaymentMethod =
| Cash
| Check(int checkNo)
| Card(string cardType, string cardNo)
Answer: Create a "case" or "choice" class that encapsulates all
three payment methods in one class, in one place.
There are three different constructors, each
with different data.
class PaymentMethod =
| Cash
| Check(int checkNo)
| Card(string cardType, string cardNo)
Answer: Create a "case" or "choice" class that encapsulates all
three payment methods in one class, in one place.
There are three different constructors, each
with different data.
PaymentMethod cash = Cash();
PaymentMethod check = Check(123);
PaymentMethod card = Card("Visa", "4012888888881881");
The compiler keeps track of which constructor
was used to create the instance.
Answer: Create a "case" or "choice" class that encapsulates all
three payment methods in one class, in one place.
void PrintPayment(payment) =
switch (payment)
{
case Cash : // print cash
case Check(checkNo) : // print check info
case Card(cardType,cardNo) // print card info
}
A case statement is then used to match the
subclass that was created, and at the same
time extract the relevant data.
class PaymentMethod =
| Cash
| Check(int checkNo)
| Card(string cardType, string cardNo)
PaymentMethod cash = Cash()
PaymentMethod check = Check(123);
PaymentMethod card = Card("Visa", "4012888888881881");
There are three different constructors, each
with different data.
The compiler keeps track of which constructor
was used to create the instance.
Proposal 12:
Require all properties to be
initialized in the constructor
Avoid initialization errors.
Require all properties to
be initialized in the
constructor.
No more properties
left as null by mistake!
public class Person(string name, DateTime birthday) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime Birthday =
get { return birthday; }
For example: Compiler error.
"birthday" is missing.
public class Person(string name) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime Birthday =
get { return birthday; }
Avoid initialization errors.
Require all properties to
be initialized in the
constructor.
No more properties
left as null by mistake!
If they don't have to be initialized,
you must make them optional.
public class Person(string name, DateTime? birthday) =
/// Full name
public string Name =
get { return name; }
/// Birthday
public DateTime? Birthday =
get { return birthday; }
Avoid initialization errors.
Require all properties to
be initialized in the
constructor.
No more properties
left as null by mistake!
Excited by C# Light?
Want it now?
But C# Light is available for
download right now*
C# v6 is not yet available
*syntax not identical to that shown in this proposal.
Will C# Light work with legacy C# code?
C# Light will be integrated with Visual Studio.
Syntax highlighting, debugging support, and more.
What tooling is available for C# Light?
Of course.
As with any .NET language, assemblies written in C# Light can be
mixed with normal C# assemblies, and you can make calls
between them.
How can I find out more
about C# Light?
Full details of C# light and how to download it, go to:
bit.ly/csharp-light

More Related Content

Viewers also liked

Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeScott Wlaschin
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Scott Wlaschin
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented ProgrammingScott Wlaschin
 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Scott Wlaschin
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Scott Wlaschin
 

Viewers also liked (7)

Enterprise Tic-Tac-Toe
Enterprise Tic-Tac-ToeEnterprise Tic-Tac-Toe
Enterprise Tic-Tac-Toe
 
F# for C# Programmers
F# for C# ProgrammersF# for C# Programmers
F# for C# Programmers
 
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014Domain Driven Design with the F# type System -- F#unctional Londoners 2014
Domain Driven Design with the F# type System -- F#unctional Londoners 2014
 
Swift vs. Language X
Swift vs. Language XSwift vs. Language X
Swift vs. Language X
 
Railway Oriented Programming
Railway Oriented ProgrammingRailway Oriented Programming
Railway Oriented Programming
 
Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)Functional Programming Patterns (NDC London 2014)
Functional Programming Patterns (NDC London 2014)
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 

More from Scott Wlaschin

Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Scott Wlaschin
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programmingScott Wlaschin
 
The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)Scott Wlaschin
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Scott Wlaschin
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsScott Wlaschin
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Scott Wlaschin
 
Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Scott Wlaschin
 
The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)Scott Wlaschin
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)Scott Wlaschin
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Scott Wlaschin
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)Scott Wlaschin
 
Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)Scott Wlaschin
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Scott Wlaschin
 
Four Languages From Forty Years Ago
Four Languages From Forty Years AgoFour Languages From Forty Years Ago
Four Languages From Forty Years AgoScott Wlaschin
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of CompositionScott Wlaschin
 

More from Scott Wlaschin (15)

Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programming
 
The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)The Power of Composition (NDC Oslo 2020)
The Power of Composition (NDC Oslo 2020)
 
Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...Building confidence in concurrent code with a model checker: TLA+ for program...
Building confidence in concurrent code with a model checker: TLA+ for program...
 
The lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of testsThe lazy programmer's guide to writing thousands of tests
The lazy programmer's guide to writing thousands of tests
 
Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)Domain Modeling with FP (DDD Europe 2020)
Domain Modeling with FP (DDD Europe 2020)
 
Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)
 
The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)The Functional Programmer's Toolkit (NDC London 2019)
The Functional Programmer's Toolkit (NDC London 2019)
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)
 
Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)Domain Modeling Made Functional (KanDDDinsky 2019)
Domain Modeling Made Functional (KanDDDinsky 2019)
 
The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)The Functional Programming Toolkit (NDC Oslo 2019)
The Functional Programming Toolkit (NDC Oslo 2019)
 
Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)Four Languages From Forty Years Ago (NewCrafts 2019)
Four Languages From Forty Years Ago (NewCrafts 2019)
 
Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)Functional Design Patterns (DevTernity 2018)
Functional Design Patterns (DevTernity 2018)
 
Four Languages From Forty Years Ago
Four Languages From Forty Years AgoFour Languages From Forty Years Ago
Four Languages From Forty Years Ago
 
The Power of Composition
The Power of CompositionThe Power of Composition
The Power of Composition
 

Recently uploaded

SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 

Recently uploaded (20)

SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 

C# Light - A proposal for a new C# syntax

  • 1. C# Light A proposal for a new C# syntax Inspired by a post by PhilTrelford UPGRADE YOUR MONITOR Read these slides and you might get a free triple height monitor* *or visual equivalent
  • 2. Why change something that works?
  • 3. Why change something that works? Because... Why not compete with scripting languages? Lightweight, but keep the power of static typing.
  • 4. Why change something that works? Because... Why not compete with scripting languages? Lightweight, but keep the power of static typing. Because... Times are changing. Defaults should change too. Make immutability the new default.
  • 5. Why change something that works? Because... Why not compete with scripting languages? Lightweight, but keep the power of static typing. Because... Times are changing. Defaults should change too. Make immutability the new default. Because... Many common patterns are too hard. Make good practices easy (but allow deviations).
  • 6. ! HEALTH WARNING ! These slides are for consumption by open-minded programmers ONLY. When taken with pre-existing closed-mindedness, can cause shock, high blood pressure, anxiety, nausea, confusion and panic.
  • 7. You must be at least this open minded to read these slides How open minded are you? Slime mould Bony fishes People who don't use LINQ People who don't use generics Opposable thumbs People who want C# v6 People who use lambdas
  • 8. Vision for C# Light Clean and lightweight code. Immutability by default. Common scenarios are easy. We make mutability a special case, rather than the other way around.
  • 9. public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// <summary> /// Full name /// </summary> public string Name { get { return _name; } } /// <summary> /// Birthday /// </summary> public DateTime Birthday { get { return _birthday; } } } Here is a typical immutable class in C# which we'll use as an example throughout.
  • 10. Here is a typical immutable class in C# which we'll use as an example throughout. 27 lines of code. Can we do better? public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// <summary> /// Full name /// </summary> public string Name { get { return _name; } } /// <summary> /// Birthday /// </summary> public DateTime Birthday { get { return _birthday; } } }
  • 11. Here is a typical immutable class in C# which we'll use as an example throughout. 27 lines of code. Can we do better? Why not remove the lines that don't contain useful information? public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// <summary> /// Full name /// </summary> public string Name { get { return _name; } } /// <summary> /// Birthday /// </summary> public DateTime Birthday { get { return _birthday; } } }
  • 12. In a typical C# project less than 50% of the lines contain useful information! Surely we can do better?
  • 14. We can start by simplifying the doc strings. Let's make "summary" the default. public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// <summary> /// Full name /// </summary> public string Name { get { return _name; } } /// <summary> /// Birthday /// </summary> public DateTime Birthday { get { return _birthday; } } }
  • 15. We can start by simplifying the doc strings. Let's make "summary" the default. public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// <summary> /// Full name /// </summary> public string Name { get { return _name; } } /// <summary> /// Birthday /// </summary> public DateTime Birthday { get { return _birthday; } } }
  • 16. public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// Full name public string Name { get { return _name; } } /// Birthday public DateTime Birthday { get { return _birthday; } } } We can start by simplifying the doc strings. Let's make "summary" the default. 4 lines saved!
  • 17. Proposal 2: Automatically create backing fields from constructor parameters Yes, I know C# 6 has something similar. Keep reading...
  • 18. public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// Full name public string Name { get { return _name; } } /// Birthday public DateTime Birthday { get { return _birthday; } } } Because immutability is the default, we can simplify further.
  • 19. public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// Full name public string Name { get { return _name; } } /// Birthday public DateTime Birthday { get { return _birthday; } } } Why not automatically define and initialize read- only backing fields from the constructor parameters?
  • 20. public class Person { public Person(string name, DateTime birthday) { } /// Full name public string Name { get { return name; } } /// Birthday public DateTime Birthday { get { return birthday; } } } Of course, you can still define mutable private fields in the usual way. Unlike C# 6, you don't need to in the immutable case. 4 lines saved! Why not automatically define and initialize read-only backing fields from the constructor parameters?
  • 21. Proposal 3: Merge the primary constructor with the class definition C# 6 has this too.
  • 22. public class Person { public Person(string name, DateTime birthday) { } /// Full name public string Name { get { return name; } } /// Birthday public DateTime Birthday { get { return birthday; } } } How often do you have more than one constructor?
  • 23. public class Person { public Person(string name, DateTime birthday) { } /// Full name public string Name { get { return name; } } /// Birthday public DateTime Birthday { get { return birthday; } } } How often do you have more than one constructor? Why not merge the constructor with the class definition?
  • 24. public class Person(string name, DateTime birthday) { /// Full name public string Name { get { return name; } } /// Birthday public DateTime Birthday { get { return birthday; } } } How often do you have more than one constructor? 4 more lines saved! Why not merge the constructor with the class definition? You can still define secondary constructors separately if you need to.
  • 25. Proposal 4: (this one is controversial)
  • 26. Proposal 4: Use indentation instead of curly braces
  • 27. public class Person(string name, DateTime birthday) { /// Full name public string Name { get { return name; } } /// Birthday public DateTime Birthday { get { return birthday; } } } Do we really need the braces? The indentation already gives us all the clues we need.
  • 28. public class Person(string name, DateTime birthday) = /// Full name public string Name = get { return name; } /// Birthday public DateTime Birthday = get { return birthday; } Do we really need the braces? The indentation already gives us all the clues we need. 6 more lines saved! You can still have explicit begin/end markers for blocks if you need to.
  • 29. public class Person(string name, DateTime birthday) = /// Full name public string Name = get { return name; } /// Birthday public DateTime Birthday = get { return birthday; } Add "equals" as an indicator to start a new block.
  • 30. People who complain about using a language with syntactic whitespace People who have spent time using a language with syntactic whitespace "Oddly enough, Python's use of whitespace stopped feeling unnatural after about twenty minutes. I just indented code, pretty much as I would have done in a C program anyway, and it worked." - Eric Raymond Helpful Venn Diagram Overlap
  • 31. Observation With these 4 proposals: 27 lines of code has shrunk to 9 lines!
  • 32. C# Because "C# Light" means you see 3x more code on your screen! Why use "C# light"? Reason 1
  • 33. public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// <summary> /// Full name /// </summary> public string Name { get { return _name; } } /// <summary> /// Birthday /// </summary> public DateTime Birthday { get { return _birthday; } } } public class Person(string name, DateTime birthday) = /// Full name public string Name = get { return name; } /// Birthday public DateTime Birthday = get { return birthday; } Why use "C# light"? C# C# Light Reason 2 Because "C# Light" means you write 1/3 as much code.
  • 34.
  • 35. Proposal 5: Eliminate syntax noise There is a lot of syntax "noise" that is not needed, IMO.
  • 36. Proposal 5a: Eliminate "get" keyword for immutable properties
  • 37. public class Person(string name, DateTime birthday) = /// Full name public string Name = get { return name; } /// Birthday public DateTime Birthday = get { return birthday; } The class is immutable. Every property is "get" only.
  • 38. public class Person(string name, DateTime birthday) = /// Full name public string Name = get { return name; } /// Birthday public DateTime Birthday = get { return birthday; } The class is immutable. Every property is "get" only. So why bother with the "get" keyword?
  • 39. public class Person(string name, DateTime birthday) = /// Full name public string Name = return name; /// Birthday public DateTime Birthday = return birthday; The class is immutable. Every property is "get" only. So why bother with the "get" keyword? A bit cleaner, IMO.
  • 41. public class Person(string name, DateTime birthday) = /// Full name public string Name = return name; /// Birthday public DateTime Birthday = return birthday; Why not take a leaf out of other languages and make the return implicit for the last line in a block? This is the "expression-based" approach.
  • 42. public class Person(string name, DateTime birthday) = /// Full name public string Name = name; /// Birthday public DateTime Birthday = birthday; Why not take a leaf out of other languages and make the return implicit for the last line in a block?
  • 43. Proposal 5c: Make immutable properties public by default
  • 44. public class Person(string name, DateTime birthday) = /// Full name public string Name = name; /// Birthday public DateTime Birthday = birthday; The properties are immutable.
  • 45. public class Person(string name, DateTime birthday) = /// Full name public string Name = name; /// Birthday public DateTime Birthday = birthday; The properties are immutable. Why not make them public by default. There's no way a client of the object can corrupt it!
  • 46. class Person(string name, DateTime birthday) = /// Full name string Name = name; /// Birthday DateTime Birthday = birthday; The properties are immutable. Why not make them public by default. There's no way a client of the object can corrupt it! You can still use the "private" keyword if you need to. Only the default has changed.
  • 48. class Person(string name, DateTime birthday) = /// Full name string Name = name; /// Birthday DateTime Birthday = birthday; How often do you have more than one semicolon on a line? Excepting for loops, of course.
  • 49. class Person(string name, DateTime birthday) = /// Full name string Name = name /// Birthday DateTime Birthday = birthday How often do you have more than one semicolon on a line? So why bother?
  • 50. Observation: Removing syntax noise opens up more opportunities to save space.
  • 51. class Person(string name, DateTime birthday) = /// Full name string Name = name /// Birthday DateTime Birthday = birthday Why not move short code fragments on to the same line?
  • 52. class Person(string name, DateTime birthday) = /// Full name string Name = name /// Birthday DateTime Birthday = birthday Why not move short code fragments on to the same line? C# 6 plans to have "expression- bodied members" too.
  • 53. Proposal 6: Use type inference for properties
  • 54. class Person(string name, DateTime birthday) = /// Full name string Name = name /// Birthday DateTime Birthday = birthday Why do we have to repeat the type? Can't the compiler figure it out for us?
  • 55. class Person(string name, DateTime birthday) = /// Full name Name = name /// Birthday Birthday = birthday Why do we have to repeat the type? Can't the compiler figure it out for us? Cleaner, but now we can't tell that it's a property!
  • 56. class Person(string name, DateTime birthday) = /// Full name member Name = name /// Birthday member Birthday = birthday We need some way to indicate properties. Let's use the word "member".
  • 57. class Person(string name, DateTime birthday) = /// Full name member Name = name /// Birthday member Birthday = birthday /// Age member Age() = DateTime.Today.Subtract(birthday).Days / 365 We can define methods the same way.
  • 58. class Person(string name, DateTime birthday) { /// Full name public string Name { get; } = name; /// Birthday public DateTime Birthday { get; } = birthday; /// Age public int Age() => DateTime.Today.Subtract(birthday).Days / 365; } Here is the C# 6 equivalent with auto-properties and expression-bodied members This is nice and compact too. Still need explicit types and "public" keyword, though.
  • 60. Let's review the proposals: 1) Make doc strings more compact 2) Move backing fields into constructor (because immutable) 3) Move constructor into class definition 4) Remove curly braces 5) Remove syntax noise - Remove "get" keyword from immutable properties - Return last value in a block automatically - Make immutable properties public by default - Make semicolons optional 6) Allow types of properties to be inferred from constructor
  • 61. class Person(string name, DateTime birthday) = /// Full name member Name = name /// Birthday member Birthday = birthday public class Person { public Person(string name, DateTime birthday) { _name = name; _birthday = birthday; } private readonly string _name; private readonly DateTime _birthday; /// <summary> /// Full name /// </summary> public string Name { get { return _name; } } /// <summary> /// Birthday /// </summary> public DateTime Birthday { get { return _birthday; } } } Normal C# Before and After C# Light 27 lines before. 7 lines after.
  • 62.
  • 63. What about the goal "make common scenarios easy"?
  • 64. The next set of proposals aims to do exactly this.
  • 66. class Person(string name, DateTime birthday) : IEquatable<Person> = /// Full name member Name = name /// Birthday member Birthday = birthday override Equals(Person obj) = if (obj == null) return false Person p = obj as Person if ((Person)p == null) { return false } // Return true if the fields match: (name == p.Name) && (birthday == p.Birthday) override Equals(Person p) = if ((object)p == null) return false // Return true if the fields match: (name == p.Name) && (birthday == p.Birthday) override GetHashCode() = name.GetHashCode ^ birthday.GetHashCode How often do you have to write all this equality code?
  • 67. [StructuralEquality] class Person(string name, DateTime birthday) = /// Full name member Name = name /// Birthday member Birthday = birthday Why not let the compiler write it for you! You just need to use a special attribute. How often do you have to write all this equality code?
  • 69. [StructuralEquality] class Person(string name, DateTime birthday) = /// Full name member Name = name /// Birthday member Birthday = birthday "Dumb" objects with no methods (aka DTOs) are very common. Since they have no methods, can we make the syntax even simpler?
  • 70. [StructuralEquality] class Person(string name, DateTime birthday) = /// Full name member Name = name /// Birthday member Birthday = birthday "Dumb" objects with no methods (aka DTOs) are very common. Since they have no methods, can we make the syntax even simpler? class Person = {string name, DateTime birthday} var person = {name="Alice", birthday=Today} Yes, we can. Just define a named class in the same way as an anonymous type.
  • 72. class Person = {string name, DateTime birthday} // ok var person = {name="Alice", birthday=Today} // error person = null This one is a no-brainer. If a class is defined with: • the [StructuralEquality] attribute • the anonymous type syntax then it is automatically non-nullable No more null testing needed!
  • 73. Proposal 10: Allow anonymous types to implement interfaces
  • 74. public class TempDisposable: IDisposable { public void Dispose() { Console.Write("Disposed"); } } var tempDisposable = new TempDisposable(); Sometimes you don't want to have to create a whole class just to implement an interface temporarily.
  • 75. var tempDisposable = {new IDisposable with member this.Dispose() = Console.Write("Disposed") } Sometimes you don't want to have to create a whole class just to implement an interface temporarily. Why not use the "anonymous type" syntax to create an object without having to create a class explicitly?
  • 76. Proposal 11: Allow subclasses to be merged into a single "case" class
  • 77. Requirement: We accept three forms of payment: Cash. Check or Card. For Cash we don't need any extra information For Checks we need a check number For Cards we need a card type and card number This one needs a bit of background. Say that you have a requirement for taking payments, as shown below: How would you implement this?
  • 78. interface IPaymentMethod {..} class Cash() : IPaymentMethod {..} class Check(int checkNo): IPaymentMethod {..} class Card(string cardType, string cardNo) : IPaymentMethod {..} You would probably implement it as an interface and a set of subclasses, like this:
  • 79. interface IPaymentMethod {..} class Cash() : IPaymentMethod {..} class Check(int checkNo): IPaymentMethod {..} class Card(string cardType, string cardNo) : IPaymentMethod {..} But that is a lot of code for such a common scenario. Also... (a) The implementation and data is probably scattered around four separate files. (b) The requirements are hard to reconstruct from the classes. (c) The subclasses are not "closed". Any class that implemented the interface would work. This might not be what you want!
  • 80. class PaymentMethod = | Cash | Check(int checkNo) | Card(string cardType, string cardNo) Answer: Create a "case" or "choice" class that encapsulates all three payment methods in one class, in one place. There are three different constructors, each with different data.
  • 81. class PaymentMethod = | Cash | Check(int checkNo) | Card(string cardType, string cardNo) Answer: Create a "case" or "choice" class that encapsulates all three payment methods in one class, in one place. There are three different constructors, each with different data. PaymentMethod cash = Cash(); PaymentMethod check = Check(123); PaymentMethod card = Card("Visa", "4012888888881881"); The compiler keeps track of which constructor was used to create the instance.
  • 82. Answer: Create a "case" or "choice" class that encapsulates all three payment methods in one class, in one place. void PrintPayment(payment) = switch (payment) { case Cash : // print cash case Check(checkNo) : // print check info case Card(cardType,cardNo) // print card info } A case statement is then used to match the subclass that was created, and at the same time extract the relevant data. class PaymentMethod = | Cash | Check(int checkNo) | Card(string cardType, string cardNo) PaymentMethod cash = Cash() PaymentMethod check = Check(123); PaymentMethod card = Card("Visa", "4012888888881881"); There are three different constructors, each with different data. The compiler keeps track of which constructor was used to create the instance.
  • 83. Proposal 12: Require all properties to be initialized in the constructor
  • 84. Avoid initialization errors. Require all properties to be initialized in the constructor. No more properties left as null by mistake! public class Person(string name, DateTime birthday) = /// Full name public string Name = get { return name; } /// Birthday public DateTime Birthday = get { return birthday; }
  • 85. For example: Compiler error. "birthday" is missing. public class Person(string name) = /// Full name public string Name = get { return name; } /// Birthday public DateTime Birthday = get { return birthday; } Avoid initialization errors. Require all properties to be initialized in the constructor. No more properties left as null by mistake!
  • 86. If they don't have to be initialized, you must make them optional. public class Person(string name, DateTime? birthday) = /// Full name public string Name = get { return name; } /// Birthday public DateTime? Birthday = get { return birthday; } Avoid initialization errors. Require all properties to be initialized in the constructor. No more properties left as null by mistake!
  • 87. Excited by C# Light? Want it now?
  • 88. But C# Light is available for download right now* C# v6 is not yet available *syntax not identical to that shown in this proposal.
  • 89. Will C# Light work with legacy C# code? C# Light will be integrated with Visual Studio. Syntax highlighting, debugging support, and more. What tooling is available for C# Light? Of course. As with any .NET language, assemblies written in C# Light can be mixed with normal C# assemblies, and you can make calls between them.
  • 90. How can I find out more about C# Light? Full details of C# light and how to download it, go to: bit.ly/csharp-light