SlideShare a Scribd company logo
1 of 36
FP vs. OOP
InVoid-Safety Context
@STeplyakov & @AntyaDev
С чего все началось?
• Интервью с Бертраном Мейером (http://bit.ly/IntervewWithMeyer)
• Борьба с «нулевыми» ссылками в C# (http://bit.ly/VoidSafetyCSharp)
Ошибка на миллиард долларов
«Я называю это своей ошибкой на миллиард долларов. Речь идет о
изобретении нулевых ссылок (null reference) в 1965 году.»
http://bit.ly/BillionDollarMistake
[CanBeNull]
public static IClrTypeName GetCallSiteTypeNaive(IInvocationExpression invocationExpression)
{
Contract.Requires(invocationExpression != null);
if (invocationExpression.InvokedExpression != null)
{
var referenceExpression = invocationExpression.InvokedExpression as IReferenceExpression;
if (referenceExpression != null)
{
var resolved = referenceExpression.Reference.Resolve();
if (resolved.DeclaredElement != null)
{
var declared = resolved.DeclaredElement as IClrDeclaredElement;
if (declared != null)
{
var containingType = declared.GetContainingType();
if (containingType != null)
{
return containingType.GetClrName();
}
}
}
}
}
return null;
}
Void-Safety. Подходы
• ОО-подходы
• Not-nullable reference types: Eiffel, Swift (*), Spec#, C++ (**)
• Contracts
• ФП-подходы
• Maybe<T>
• Отсутствие литерала null (***)
Void-Safety в C#
• Not-nullable reference types in C# (*)
• null-propagating operator (C# 6.0)
• Code Contracts
• Explicit Maybe types
• Implicit maybe type + extension methods
http://bit.ly/VoidSafetyCSharp
Not-nullable reference types
// Где-то в идеальном мире
// s – not-nullable переменная
public void Foo(string s)
{
// Никакие проверки, контркты, атрибуты не нужны
Console.WriteLine(s.Length);
}
// str – nullable (detached) переменная.
//string! аналогичен типу Option<string>
public void Boo(string! str)
{
// Ошибка компиляции!
// Нельзя обращаться к членам "detached" строки!
// Console.WriteLine(str.Length);
str.IfAttached((string s) => Console.WriteLine(s));
// Или
if (str != null)
Console.WriteLine(str.Length);
}
public void Doo(string! str)
{
Contract.Requires(str != null);
// Наличие предусловия позволяет безопасным образом
// обращаться к объекте string через ссылку str!
Console.WriteLine(str.Length);
}
No non-nullable reference types in C# 
In theory, theory and practice are the same, but in practice, they’re
different.This is no exception.There are many pragmatic objections to
adding non-nullable reference types now.
Eric Lippert
http://blog.coverity.com/2013/11/20/c-non-nullable-reference-types/
Альтернатива по Липперту?
Code Contracts!
Let the fight begin
Как функциональные программисты заменяют лампочки?
Они не заменяют лампочки, а покупают новую розетку,
новую электропроводку и новую лампочку.
Бертран Мейер
NoException?!
Let’s review this: http://ericlippert.com/2013/03/21/monads-part-nine/
А что Эрик думает по этому поводу?
[1.This technique can be dangerous, in that it can delay the production of an
exception until long after the exception handlers designed to deal with it are
no longer on the stack.Worse, it can delay the production of an exception
indefinitely, leading to programs that should have crashed continuing to
corrupt user data. Use with extreme caution.]
http://ericlippert.com/2013/03/21/monads-part-nine/
В чем проблема с Maybe<T>?
• Оптимизация на corner case
• Lack of DogFooding!
• Какую проблему мы решаем?
• Void-safety или упрощение control flow?
• Дополнительные затраты на обучение
• Отсутствие паттерн-матчинга
• Подход не универсален! (*)
• Чем не подходит implicit monads + CanBeNull/Postconditions?
Оптимизация на corner case-е!
• Источники:
• “Declaring and Checking Non-nullTypes” by Manuel Fahndrich, K. Rustan M. Leino,
Microsoft Research
• “Avoid aVoid:The eradication of null dereferencing” by Bertrand Meyer et al
Так какую проблему мы решаем?
• Void Safety vs. Control Flow simplification
• Как выразить non-nullable с помощью Monad?
public static class MaybeExtensions
{
public static A Match<T, A>(this Maybe<T> maybe, Func<A> none, Func<T, A> some)
{
return maybe == null || maybe.IsNone ? none() : some(maybe.Value);
}
public static Maybe<A> Bind<T, A>(this Maybe<T> maybe, Func<T, A> func)
{
return func == null || maybe == null || maybe.IsNone
? new Maybe<A>()
: func(maybe.Value).ToMaybe();
}
}
Семантика NRE?
I don't need Maybe,
I need non-nullable reference
types!
Мой подход?
Code Contracts + Annotations + Extension methods for reference types!
(+ R# plugin - https://resharper-
plugins.jetbrains.com/packages/ReSharper.ContractExtensions/)
Контракты? Нет, не слышали!
• Assert-ы на стероидах!
• Выражают смысл (семантику) кода
• Выразительность, бла, бла, бла…
• Pet Project: https://github.com/SergeyTeplyakov/ReSharperContractExtensions
var contractFunction = GetContractFunction();
if (contractFunction == null)
{
AddContractClass();
contractFunction = GetContractFunction();
Contract.Assert(contractFunction != null);
}
AddRequiresTo(contractFunction);
...
[CanBeNull, System.Diagnostics.Contracts.Pure]
private ICSharpFunctionDeclaration GetContractFunction()
{
return _availability.SelectedFunction.GetContractFunction();
}
Maybe + Contracts?
[CanBeNull]
public static IClrTypeName GetCallSiteTypeNaive(IInvocationExpression invocationExpression)
{
Contract.Requires(invocationExpression != null);
if (invocationExpression.InvokedExpression != null)
{
var referenceExpression = invocationExpression.InvokedExpression as IReferenceExpression;
if (referenceExpression != null)
{
var resolved = referenceExpression.Reference.Resolve();
if (resolved.DeclaredElement != null)
{
var declared = resolved.DeclaredElement as IClrDeclaredElement;
if (declared != null)
{
var containingType = declared.GetContainingType();
if (containingType != null)
{
return containingType.GetClrName();
}
}
}
}
}
return null;
}
Implicit monads
[CanBeNull]
public static IClrTypeName GetCallSiteType(this IInvocationExpression invocationExpression)
{
Contract.Requires(invocationExpression != null);
var type = invocationExpression
.With(x => x.InvokedExpression)
.With(x => x as IReferenceExpression)
.With(x => x.Reference)
.With(x => x.Resolve())
.With(x => x.DeclaredElement)
.With(x => x as IClrDeclaredElement)
.With(x => x.GetContainingType())
.Return(x => x.GetClrName());
return type;
}
Caveats!
var hashCode = invocationExpression
.With(x => x.InvokedExpression)
.With(x => x as IReferenceExpression)
.With(x => x.Reference)
.With(x => x.Resolve())
.With(x => x.GetHashCode());
var hashCode = invocationExpression
.With(x => x.InvokedExpression)
.With(x => x as IReferenceExpression)
.With(x => x.Reference)
.With(x => x.Resolve())
.ReturnStruct(x => x.GetHashCode());
Compile-time error!
hachCode – это int?
Null-propagating operator ?. (C# 6.0)
https://roslyn.codeplex.com/discussions/540883
Void safety on Kiev ALT.NET

More Related Content

Similar to Void safety on Kiev ALT.NET

Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0akrakovetsky
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#Andrey Karpov
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?Tatyanazaxarova
 
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выраженияTatyanazaxarova
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
Константин Книжник: статический анализ, взгляд со стороны
Константин Книжник: статический анализ, взгляд со стороныКонстантин Книжник: статический анализ, взгляд со стороны
Константин Книжник: статический анализ, взгляд со стороныTatyanazaxarova
 
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruYandex
 
Viacheslav Eremin about DOT NET (rus lang)
Viacheslav Eremin about DOT NET (rus lang)Viacheslav Eremin about DOT NET (rus lang)
Viacheslav Eremin about DOT NET (rus lang)Viacheslav Eremin
 
Разработка сетевых приложений с gevent
Разработка сетевых приложений с geventРазработка сетевых приложений с gevent
Разработка сетевых приложений с geventAndrey Popp
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияRuslan Shevchenko
 
Архитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьАрхитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьAndrey Bibichev
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeTatyanazaxarova
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй этоRoman Dvornov
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!Roman Dvornov
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаAndrey Karpov
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаcorehard_by
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Yandex
 

Similar to Void safety on Kiev ALT.NET (20)

Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0Что нового в Visual Studio 2010 и .Net 4.0
Что нового в Visual Studio 2010 и .Net 4.0
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?О сложностях программирования, или C# нас не спасет?
О сложностях программирования, или C# нас не спасет?
 
Статический анализ и регулярные выражения
Статический анализ и регулярные выраженияСтатический анализ и регулярные выражения
Статический анализ и регулярные выражения
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
Константин Книжник: статический анализ, взгляд со стороны
Константин Книжник: статический анализ, взгляд со стороныКонстантин Книжник: статический анализ, взгляд со стороны
Константин Книжник: статический анализ, взгляд со стороны
 
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ruБаба-Яга против! — Роман Дворнов, Ostrovok.ru
Баба-Яга против! — Роман Дворнов, Ostrovok.ru
 
Viacheslav Eremin about DOT NET (rus lang)
Viacheslav Eremin about DOT NET (rus lang)Viacheslav Eremin about DOT NET (rus lang)
Viacheslav Eremin about DOT NET (rus lang)
 
Invisible
InvisibleInvisible
Invisible
 
Regular expressions
Regular expressionsRegular expressions
Regular expressions
 
Разработка сетевых приложений с gevent
Разработка сетевых приложений с geventРазработка сетевых приложений с gevent
Разработка сетевых приложений с gevent
 
анализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестированияанализ кода: от проверки стиля до автоматического тестирования
анализ кода: от проверки стиля до автоматического тестирования
 
Архитектура в Agile: слабая связность
Архитектура в Agile: слабая связностьАрхитектура в Agile: слабая связность
Архитектура в Agile: слабая связность
 
Статический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMergeСтатический анализ исходного кода на примере WinMerge
Статический анализ исходного кода на примере WinMerge
 
Инструментируй это
Инструментируй этоИнструментируй это
Инструментируй это
 
Баба Яга против!
Баба Яга против!Баба Яга против!
Баба Яга против!
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Поиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кодаПоиск уязвимостей с использованием статического анализа кода
Поиск уязвимостей с использованием статического анализа кода
 
Transpile it.pdf
Transpile it.pdfTranspile it.pdf
Transpile it.pdf
 
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
Алексей Куканов — Параллелизм в C++: управляйте приложением, а не потоками!
 

More from Sergey Teplyakov

More from Sergey Teplyakov (6)

C sharp deep dive
C sharp deep diveC sharp deep dive
C sharp deep dive
 
MS SWIT 2013 Design for Testability
MS SWIT 2013 Design for TestabilityMS SWIT 2013 Design for Testability
MS SWIT 2013 Design for Testability
 
Design by Contract basics
Design by Contract basicsDesign by Contract basics
Design by Contract basics
 
Visual studio toolbox
Visual studio toolboxVisual studio toolbox
Visual studio toolbox
 
Luxoft async.net
Luxoft async.netLuxoft async.net
Luxoft async.net
 
Reactive extensions
Reactive extensionsReactive extensions
Reactive extensions
 

Void safety on Kiev ALT.NET

  • 1. FP vs. OOP InVoid-Safety Context @STeplyakov & @AntyaDev
  • 2. С чего все началось? • Интервью с Бертраном Мейером (http://bit.ly/IntervewWithMeyer) • Борьба с «нулевыми» ссылками в C# (http://bit.ly/VoidSafetyCSharp)
  • 3.
  • 4. Ошибка на миллиард долларов «Я называю это своей ошибкой на миллиард долларов. Речь идет о изобретении нулевых ссылок (null reference) в 1965 году.» http://bit.ly/BillionDollarMistake
  • 5.
  • 6.
  • 7. [CanBeNull] public static IClrTypeName GetCallSiteTypeNaive(IInvocationExpression invocationExpression) { Contract.Requires(invocationExpression != null); if (invocationExpression.InvokedExpression != null) { var referenceExpression = invocationExpression.InvokedExpression as IReferenceExpression; if (referenceExpression != null) { var resolved = referenceExpression.Reference.Resolve(); if (resolved.DeclaredElement != null) { var declared = resolved.DeclaredElement as IClrDeclaredElement; if (declared != null) { var containingType = declared.GetContainingType(); if (containingType != null) { return containingType.GetClrName(); } } } } } return null; }
  • 8.
  • 9. Void-Safety. Подходы • ОО-подходы • Not-nullable reference types: Eiffel, Swift (*), Spec#, C++ (**) • Contracts • ФП-подходы • Maybe<T> • Отсутствие литерала null (***)
  • 10. Void-Safety в C# • Not-nullable reference types in C# (*) • null-propagating operator (C# 6.0) • Code Contracts • Explicit Maybe types • Implicit maybe type + extension methods http://bit.ly/VoidSafetyCSharp
  • 11. Not-nullable reference types // Где-то в идеальном мире // s – not-nullable переменная public void Foo(string s) { // Никакие проверки, контркты, атрибуты не нужны Console.WriteLine(s.Length); } // str – nullable (detached) переменная. //string! аналогичен типу Option<string> public void Boo(string! str) { // Ошибка компиляции! // Нельзя обращаться к членам "detached" строки! // Console.WriteLine(str.Length); str.IfAttached((string s) => Console.WriteLine(s)); // Или if (str != null) Console.WriteLine(str.Length); } public void Doo(string! str) { Contract.Requires(str != null); // Наличие предусловия позволяет безопасным образом // обращаться к объекте string через ссылку str! Console.WriteLine(str.Length); }
  • 12. No non-nullable reference types in C#  In theory, theory and practice are the same, but in practice, they’re different.This is no exception.There are many pragmatic objections to adding non-nullable reference types now. Eric Lippert http://blog.coverity.com/2013/11/20/c-non-nullable-reference-types/
  • 14. Let the fight begin
  • 15. Как функциональные программисты заменяют лампочки? Они не заменяют лампочки, а покупают новую розетку, новую электропроводку и новую лампочку. Бертран Мейер
  • 16. NoException?! Let’s review this: http://ericlippert.com/2013/03/21/monads-part-nine/
  • 17.
  • 18. А что Эрик думает по этому поводу? [1.This technique can be dangerous, in that it can delay the production of an exception until long after the exception handlers designed to deal with it are no longer on the stack.Worse, it can delay the production of an exception indefinitely, leading to programs that should have crashed continuing to corrupt user data. Use with extreme caution.] http://ericlippert.com/2013/03/21/monads-part-nine/
  • 19. В чем проблема с Maybe<T>? • Оптимизация на corner case • Lack of DogFooding! • Какую проблему мы решаем? • Void-safety или упрощение control flow? • Дополнительные затраты на обучение • Отсутствие паттерн-матчинга • Подход не универсален! (*) • Чем не подходит implicit monads + CanBeNull/Postconditions?
  • 20. Оптимизация на corner case-е! • Источники: • “Declaring and Checking Non-nullTypes” by Manuel Fahndrich, K. Rustan M. Leino, Microsoft Research • “Avoid aVoid:The eradication of null dereferencing” by Bertrand Meyer et al
  • 21. Так какую проблему мы решаем? • Void Safety vs. Control Flow simplification • Как выразить non-nullable с помощью Monad?
  • 22. public static class MaybeExtensions { public static A Match<T, A>(this Maybe<T> maybe, Func<A> none, Func<T, A> some) { return maybe == null || maybe.IsNone ? none() : some(maybe.Value); } public static Maybe<A> Bind<T, A>(this Maybe<T> maybe, Func<T, A> func) { return func == null || maybe == null || maybe.IsNone ? new Maybe<A>() : func(maybe.Value).ToMaybe(); } }
  • 24. I don't need Maybe, I need non-nullable reference types!
  • 25. Мой подход? Code Contracts + Annotations + Extension methods for reference types! (+ R# plugin - https://resharper- plugins.jetbrains.com/packages/ReSharper.ContractExtensions/)
  • 26. Контракты? Нет, не слышали! • Assert-ы на стероидах! • Выражают смысл (семантику) кода • Выразительность, бла, бла, бла… • Pet Project: https://github.com/SergeyTeplyakov/ReSharperContractExtensions
  • 27. var contractFunction = GetContractFunction(); if (contractFunction == null) { AddContractClass(); contractFunction = GetContractFunction(); Contract.Assert(contractFunction != null); } AddRequiresTo(contractFunction); ... [CanBeNull, System.Diagnostics.Contracts.Pure] private ICSharpFunctionDeclaration GetContractFunction() { return _availability.SelectedFunction.GetContractFunction(); }
  • 28.
  • 30. [CanBeNull] public static IClrTypeName GetCallSiteTypeNaive(IInvocationExpression invocationExpression) { Contract.Requires(invocationExpression != null); if (invocationExpression.InvokedExpression != null) { var referenceExpression = invocationExpression.InvokedExpression as IReferenceExpression; if (referenceExpression != null) { var resolved = referenceExpression.Reference.Resolve(); if (resolved.DeclaredElement != null) { var declared = resolved.DeclaredElement as IClrDeclaredElement; if (declared != null) { var containingType = declared.GetContainingType(); if (containingType != null) { return containingType.GetClrName(); } } } } } return null; }
  • 31. Implicit monads [CanBeNull] public static IClrTypeName GetCallSiteType(this IInvocationExpression invocationExpression) { Contract.Requires(invocationExpression != null); var type = invocationExpression .With(x => x.InvokedExpression) .With(x => x as IReferenceExpression) .With(x => x.Reference) .With(x => x.Resolve()) .With(x => x.DeclaredElement) .With(x => x as IClrDeclaredElement) .With(x => x.GetContainingType()) .Return(x => x.GetClrName()); return type; }
  • 32. Caveats! var hashCode = invocationExpression .With(x => x.InvokedExpression) .With(x => x as IReferenceExpression) .With(x => x.Reference) .With(x => x.Resolve()) .With(x => x.GetHashCode()); var hashCode = invocationExpression .With(x => x.InvokedExpression) .With(x => x as IReferenceExpression) .With(x => x.Reference) .With(x => x.Resolve()) .ReturnStruct(x => x.GetHashCode()); Compile-time error! hachCode – это int?
  • 33.
  • 34.
  • 35. Null-propagating operator ?. (C# 6.0) https://roslyn.codeplex.com/discussions/540883

Editor's Notes

  1. (*) Подходит все же для control flow, но не для ловли багов!