SlideShare une entreprise Scribd logo
1  sur  19
.NET Conf
Herding Nulls
and other C# stories from the future
Mads Torgersen, C# Lead Designer
InfoQ.com: News & Community Site
• Over 1,000,000 software developers, architects and CTOs read the site world-
wide every month
• 250,000 senior developers subscribe to our weekly newsletter
• Published in 4 languages (English, Chinese, Japanese and Brazilian
Portuguese)
• Post content from our QCon conferences
• 2 dedicated podcast channels: The InfoQ Podcast, with a focus on
Architecture and The Engineering Culture Podcast, with a focus on building
• 96 deep dives on innovative topics packed as downloadable emags and
minibooks
• Over 40 new content items per week
Watch the video with slide
synchronization on InfoQ.com!
https://www.infoq.com/presentations/
c-sharp-future
Purpose of QCon
- to empower software development by facilitating the spread of
knowledge and innovation
Strategy
- practitioner-driven conference designed for YOU: influencers of
change and innovation in your teams
- speakers and topics driving the evolution and innovation
- connecting and catalyzing the influencers and innovators
Highlights
- attended by more than 12,000 delegates since 2007
- held in 9 cities worldwide
Presented at QCon San Francisco
www.qconsf.com
Stack Overflow - most popular technologies
stackoverflow.com/insights/survey/2017#most-popular-technologies
Stack Overflow - most loved technologies
stackoverflow.com/insights/survey/2017#most-loved-dreaded-and-wanted
Herding nulls – the problem
Every reference type allows null!
Code must be defensive about it
C# shares this with most object oriented languages
Not all languages have this problem
Differentiate between nullable and non-nullable
Use pattern matching or similar to conditionally “unpack” nullables
Components of a solution
Expression of intent (nullable or not?)
Enforcement of intent (regulate assignment and dereference)
Within an existing language!
There are billions of lines of C# code, many of them well-tested against null
Herding nulls – expression of intent
public class Person
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
}
Herding nulls – expression of intent
public class Person
{
public string! FirstName { get; set; }
public string? MiddleName { get; set; }
public string! LastName { get; set; }
}

Herding nulls – expression of intent
public class Person
{
public string FirstName { get; set; }
public string? MiddleName { get; set; }
public string LastName { get; set; }
}

Herding nulls – enforcement
Protect non-null types from nulls
Protect nulls from dereference
Must be optional
Turn it on when you’re ready to know
Can’t affect semantics - warnings, not errors
Must do a good job with existing code
Can’t force you to rewrite good code
Recognize existing ways of ensuring null safety (checks and assignments)
Can’t be exhaustive
Tradeoff between completeness and convenience
Extension everything – new members
extension Student extends Person
{
// static field
static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>();
// instance method
public void Enroll(Professor supervisor) { enrollees[this] = supervisor; }
// instance property
public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null;
// static property
public static ICollection<Person> Students => enrollees.Keys;
// instance constructor
public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); }
}
Extension everything – new members
extension Student extends Person
{
static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>();
public void Enroll(Professor supervisor) { enrollees[this] = supervisor; }
public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null;
public static ICollection<Person> Students => enrollees.Keys;
public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); }
}
Person mads = new Person("Mads Torgersen", tonyHoare);
WriteLine(mads.Supervisor);
var tonysStudents =
from s in Person.Students
where s.Supervisor == tonyHoare
select s.Name;
Extension everything – interfaces
extension Student extends Person
{
static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>();
public void Enroll(Professor supervisor) { enrollees[this] = supervisor; }
public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null;
public static ICollection<Person> Students => enrollees.Keys;
public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); }
}
class Professor { … }
interface IStudent
{
string Name { get; }
Professor? Supervisor { get; }
void Enroll(Professor supervisor);
}
Extension everything – interfaces
extension Student extends Person : IStudent
{
static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>();
public void Enroll(Professor supervisor) { enrollees[this] = supervisor; }
public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null;
public static ICollection<Person> Students => enrollees.Keys;
public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); }
}
class Professor { … }
interface IStudent
{
string Name { get; }
Professor? Supervisor { get; }
void Enroll(Professor supervisor);
}
Extension everything – interfaces as type classes
interface IGroup<T>
{
static T Zero { get; }
static T operator +(T t1, T t2);
}
extension IntGroup extends int : IGroup<int>
{
public static int T Zero => 0;
}
public static T AddAll<T>(T[] ts) where T : IGroup<T>
{
T result = T.Zero;
foreach (T t in ts) { result += t; }
return result;
}
int sixtyThree = AddAll(new [] { 1, 2, 4, 8, 16, 32 });
Async streams – getting rid of callbacks
Records
class Person : IEquatable<Person>
{
public string First { get; }
public string Last { get; }
public Person(string First, string Last) => (this.First, this.Last) = (First, Last);
public void Deconstruct(out string First, out string Last)
=> (First, Last) = (this.First, this.Last);
public bool Equals(Person other)
=> other != null && First == other.First && Last == other.Last;
public override bool Equals(object obj) => obj is Person other ? Equals(other) : false;
public override int GetHashCode() => GreatHashFunction(First, Last);
…
}
class Person(string First, string Last);
Resources
github.com/dotnet/csharplang
blogs.msdn.microsoft.com/dotnet
Watch the video with slide
synchronization on InfoQ.com!
https://www.infoq.com/presentations/
c-sharp-future

Contenu connexe

Plus de C4Media

Plus de C4Media (20)

Shifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CDShifting Left with Cloud Native CI/CD
Shifting Left with Cloud Native CI/CD
 
CI/CD for Machine Learning
CI/CD for Machine LearningCI/CD for Machine Learning
CI/CD for Machine Learning
 
Fault Tolerance at Speed
Fault Tolerance at SpeedFault Tolerance at Speed
Fault Tolerance at Speed
 
Architectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep SystemsArchitectures That Scale Deep - Regaining Control in Deep Systems
Architectures That Scale Deep - Regaining Control in Deep Systems
 
ML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.jsML in the Browser: Interactive Experiences with Tensorflow.js
ML in the Browser: Interactive Experiences with Tensorflow.js
 
Build Your Own WebAssembly Compiler
Build Your Own WebAssembly CompilerBuild Your Own WebAssembly Compiler
Build Your Own WebAssembly Compiler
 
User & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix ScaleUser & Device Identity for Microservices @ Netflix Scale
User & Device Identity for Microservices @ Netflix Scale
 
Scaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's EdgeScaling Patterns for Netflix's Edge
Scaling Patterns for Netflix's Edge
 
Make Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home EverywhereMake Your Electron App Feel at Home Everywhere
Make Your Electron App Feel at Home Everywhere
 
The Talk You've Been Await-ing For
The Talk You've Been Await-ing ForThe Talk You've Been Await-ing For
The Talk You've Been Await-ing For
 
Future of Data Engineering
Future of Data EngineeringFuture of Data Engineering
Future of Data Engineering
 
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and MoreAutomated Testing for Terraform, Docker, Packer, Kubernetes, and More
Automated Testing for Terraform, Docker, Packer, Kubernetes, and More
 
Navigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery TeamsNavigating Complexity: High-performance Delivery and Discovery Teams
Navigating Complexity: High-performance Delivery and Discovery Teams
 
High Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in AdtechHigh Performance Cooperative Distributed Systems in Adtech
High Performance Cooperative Distributed Systems in Adtech
 
Rust's Journey to Async/await
Rust's Journey to Async/awaitRust's Journey to Async/await
Rust's Journey to Async/await
 
Opportunities and Pitfalls of Event-Driven Utopia
Opportunities and Pitfalls of Event-Driven UtopiaOpportunities and Pitfalls of Event-Driven Utopia
Opportunities and Pitfalls of Event-Driven Utopia
 
Datadog: a Real-Time Metrics Database for One Quadrillion Points/Day
Datadog: a Real-Time Metrics Database for One Quadrillion Points/DayDatadog: a Real-Time Metrics Database for One Quadrillion Points/Day
Datadog: a Real-Time Metrics Database for One Quadrillion Points/Day
 
Are We Really Cloud-Native?
Are We Really Cloud-Native?Are We Really Cloud-Native?
Are We Really Cloud-Native?
 
CockroachDB: Architecture of a Geo-Distributed SQL Database
CockroachDB: Architecture of a Geo-Distributed SQL DatabaseCockroachDB: Architecture of a Geo-Distributed SQL Database
CockroachDB: Architecture of a Geo-Distributed SQL Database
 
A Dive into Streams @LinkedIn with Brooklin
A Dive into Streams @LinkedIn with BrooklinA Dive into Streams @LinkedIn with Brooklin
A Dive into Streams @LinkedIn with Brooklin
 

Dernier

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Dernier (20)

The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 

Herding Nulls and Other C# Stories from the Future

  • 1. .NET Conf Herding Nulls and other C# stories from the future Mads Torgersen, C# Lead Designer
  • 2. InfoQ.com: News & Community Site • Over 1,000,000 software developers, architects and CTOs read the site world- wide every month • 250,000 senior developers subscribe to our weekly newsletter • Published in 4 languages (English, Chinese, Japanese and Brazilian Portuguese) • Post content from our QCon conferences • 2 dedicated podcast channels: The InfoQ Podcast, with a focus on Architecture and The Engineering Culture Podcast, with a focus on building • 96 deep dives on innovative topics packed as downloadable emags and minibooks • Over 40 new content items per week Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ c-sharp-future
  • 3. Purpose of QCon - to empower software development by facilitating the spread of knowledge and innovation Strategy - practitioner-driven conference designed for YOU: influencers of change and innovation in your teams - speakers and topics driving the evolution and innovation - connecting and catalyzing the influencers and innovators Highlights - attended by more than 12,000 delegates since 2007 - held in 9 cities worldwide Presented at QCon San Francisco www.qconsf.com
  • 4. Stack Overflow - most popular technologies stackoverflow.com/insights/survey/2017#most-popular-technologies
  • 5. Stack Overflow - most loved technologies stackoverflow.com/insights/survey/2017#most-loved-dreaded-and-wanted
  • 6. Herding nulls – the problem Every reference type allows null! Code must be defensive about it C# shares this with most object oriented languages Not all languages have this problem Differentiate between nullable and non-nullable Use pattern matching or similar to conditionally “unpack” nullables Components of a solution Expression of intent (nullable or not?) Enforcement of intent (regulate assignment and dereference) Within an existing language! There are billions of lines of C# code, many of them well-tested against null
  • 7. Herding nulls – expression of intent public class Person { public string FirstName { get; set; } public string MiddleName { get; set; } public string LastName { get; set; } }
  • 8. Herding nulls – expression of intent public class Person { public string! FirstName { get; set; } public string? MiddleName { get; set; } public string! LastName { get; set; } } 
  • 9. Herding nulls – expression of intent public class Person { public string FirstName { get; set; } public string? MiddleName { get; set; } public string LastName { get; set; } } 
  • 10. Herding nulls – enforcement Protect non-null types from nulls Protect nulls from dereference Must be optional Turn it on when you’re ready to know Can’t affect semantics - warnings, not errors Must do a good job with existing code Can’t force you to rewrite good code Recognize existing ways of ensuring null safety (checks and assignments) Can’t be exhaustive Tradeoff between completeness and convenience
  • 11. Extension everything – new members extension Student extends Person { // static field static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>(); // instance method public void Enroll(Professor supervisor) { enrollees[this] = supervisor; } // instance property public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null; // static property public static ICollection<Person> Students => enrollees.Keys; // instance constructor public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); } }
  • 12. Extension everything – new members extension Student extends Person { static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>(); public void Enroll(Professor supervisor) { enrollees[this] = supervisor; } public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null; public static ICollection<Person> Students => enrollees.Keys; public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); } } Person mads = new Person("Mads Torgersen", tonyHoare); WriteLine(mads.Supervisor); var tonysStudents = from s in Person.Students where s.Supervisor == tonyHoare select s.Name;
  • 13. Extension everything – interfaces extension Student extends Person { static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>(); public void Enroll(Professor supervisor) { enrollees[this] = supervisor; } public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null; public static ICollection<Person> Students => enrollees.Keys; public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); } } class Professor { … } interface IStudent { string Name { get; } Professor? Supervisor { get; } void Enroll(Professor supervisor); }
  • 14. Extension everything – interfaces extension Student extends Person : IStudent { static Dictionary<Person, Professor> enrollees = new Dictionary<Person, Professor>(); public void Enroll(Professor supervisor) { enrollees[this] = supervisor; } public Professor? Supervisor => enrollees.TryGetValue(this, out var supervisor) ? supervisor : null; public static ICollection<Person> Students => enrollees.Keys; public Person(string name, Professor supervisor) : this(name) { this.Enroll(supervisor); } } class Professor { … } interface IStudent { string Name { get; } Professor? Supervisor { get; } void Enroll(Professor supervisor); }
  • 15. Extension everything – interfaces as type classes interface IGroup<T> { static T Zero { get; } static T operator +(T t1, T t2); } extension IntGroup extends int : IGroup<int> { public static int T Zero => 0; } public static T AddAll<T>(T[] ts) where T : IGroup<T> { T result = T.Zero; foreach (T t in ts) { result += t; } return result; } int sixtyThree = AddAll(new [] { 1, 2, 4, 8, 16, 32 });
  • 16. Async streams – getting rid of callbacks
  • 17. Records class Person : IEquatable<Person> { public string First { get; } public string Last { get; } public Person(string First, string Last) => (this.First, this.Last) = (First, Last); public void Deconstruct(out string First, out string Last) => (First, Last) = (this.First, this.Last); public bool Equals(Person other) => other != null && First == other.First && Last == other.Last; public override bool Equals(object obj) => obj is Person other ? Equals(other) : false; public override int GetHashCode() => GreatHashFunction(First, Last); … } class Person(string First, string Last);
  • 19. Watch the video with slide synchronization on InfoQ.com! https://www.infoq.com/presentations/ c-sharp-future