Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
FP vs. OOP
InVoid-Safety Context
@STeplyakov & @AntyaDev
С чего все началось?
• Интервью с Бертраном Мейером (http://bit.ly/IntervewWithMeyer)
• Борьба с «нулевыми» ссылками в C# ...
Ошибка на миллиард долларов
«Я называю это своей ошибкой на миллиард долларов. Речь идет о
изобретении нулевых ссылок (nul...
[CanBeNull]
public static IClrTypeName GetCallSiteTypeNaive(IInvocationExpression invocationExpression)
{
Contract.Require...
Void-Safety. Подходы
• ОО-подходы
• Not-nullable reference types: Eiffel, Swift (*), Spec#, C++ (**)
• Contracts
• ФП-подх...
Void-Safety в C#
• Not-nullable reference types in C# (*)
• null-propagating operator (C# 6.0)
• Code Contracts
• Explicit...
Not-nullable reference types
// Где-то в идеальном мире
// s – not-nullable переменная
public void Foo(string s)
{
// Ника...
No non-nullable reference types in C# 
In theory, theory and practice are the same, but in practice, they’re
different.Th...
Альтернатива по Липперту?
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...
В чем проблема с Maybe<T>?
• Оптимизация на corner case
• Lack of DogFooding!
• Какую проблему мы решаем?
• Void-safety ил...
Оптимизация на corner case-е!
• Источники:
• “Declaring and Checking Non-nullTypes” by Manuel Fahndrich, K. Rustan M. Lein...
Так какую проблему мы решаем?
• 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)
{
re...
Семантика NRE?
I don't need Maybe,
I need non-nullable reference
types!
Мой подход?
Code Contracts + Annotations + Extension methods for reference types!
(+ R# plugin - https://resharper-
plugin...
Контракты? Нет, не слышали!
• Assert-ы на стероидах!
• Выражают смысл (семантику) кода
• Выразительность, бла, бла, бла…
•...
var contractFunction = GetContractFunction();
if (contractFunction == null)
{
AddContractClass();
contractFunction = GetCo...
Maybe + Contracts?
[CanBeNull]
public static IClrTypeName GetCallSiteTypeNaive(IInvocationExpression invocationExpression)
{
Contract.Require...
Implicit monads
[CanBeNull]
public static IClrTypeName GetCallSiteType(this IInvocationExpression invocationExpression)
{...
Caveats!
var hashCode = invocationExpression
.With(x => x.InvokedExpression)
.With(x => x as IReferenceExpression)
.With(x...
Null-propagating operator ?. (C# 6.0)
https://roslyn.codeplex.com/discussions/540883
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Void safety on Kiev ALT.NET
Upcoming SlideShare
Loading in …5
×

Void safety on Kiev ALT.NET

1,198 views

Published on

Slides from my talk at Kiev ALT.NET from 7/29.
Sources: https://gist.github.com/SergeyTeplyakov/a1fbd8b2bb192009b650

Published in: Software
  • Be the first to comment

Void safety on Kiev ALT.NET

  1. 1. FP vs. OOP InVoid-Safety Context @STeplyakov & @AntyaDev
  2. 2. С чего все началось? • Интервью с Бертраном Мейером (http://bit.ly/IntervewWithMeyer) • Борьба с «нулевыми» ссылками в C# (http://bit.ly/VoidSafetyCSharp)
  3. 3. Ошибка на миллиард долларов «Я называю это своей ошибкой на миллиард долларов. Речь идет о изобретении нулевых ссылок (null reference) в 1965 году.» http://bit.ly/BillionDollarMistake
  4. 4. [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; }
  5. 5. Void-Safety. Подходы • ОО-подходы • Not-nullable reference types: Eiffel, Swift (*), Spec#, C++ (**) • Contracts • ФП-подходы • Maybe<T> • Отсутствие литерала null (***)
  6. 6. 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
  7. 7. 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); }
  8. 8. 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/
  9. 9. Альтернатива по Липперту? Code Contracts!
  10. 10. Let the fight begin
  11. 11. Как функциональные программисты заменяют лампочки? Они не заменяют лампочки, а покупают новую розетку, новую электропроводку и новую лампочку. Бертран Мейер
  12. 12. NoException?! Let’s review this: http://ericlippert.com/2013/03/21/monads-part-nine/
  13. 13. А что Эрик думает по этому поводу? [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/
  14. 14. В чем проблема с Maybe<T>? • Оптимизация на corner case • Lack of DogFooding! • Какую проблему мы решаем? • Void-safety или упрощение control flow? • Дополнительные затраты на обучение • Отсутствие паттерн-матчинга • Подход не универсален! (*) • Чем не подходит implicit monads + CanBeNull/Postconditions?
  15. 15. Оптимизация на 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
  16. 16. Так какую проблему мы решаем? • Void Safety vs. Control Flow simplification • Как выразить non-nullable с помощью Monad?
  17. 17. 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(); } }
  18. 18. Семантика NRE?
  19. 19. I don't need Maybe, I need non-nullable reference types!
  20. 20. Мой подход? Code Contracts + Annotations + Extension methods for reference types! (+ R# plugin - https://resharper- plugins.jetbrains.com/packages/ReSharper.ContractExtensions/)
  21. 21. Контракты? Нет, не слышали! • Assert-ы на стероидах! • Выражают смысл (семантику) кода • Выразительность, бла, бла, бла… • Pet Project: https://github.com/SergeyTeplyakov/ReSharperContractExtensions
  22. 22. 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(); }
  23. 23. Maybe + Contracts?
  24. 24. [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; }
  25. 25. 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; }
  26. 26. 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?
  27. 27. Null-propagating operator ?. (C# 6.0) https://roslyn.codeplex.com/discussions/540883

×