SlideShare a Scribd company logo
Functional Programming in C#
NCrafts 21-22 May, Paris 2015
@tjaskula
What is functional programming ?
• Functions as building blocks
• Function returns values only based on the passed input
• Recursion
• HOF (Higher Order Functions)
• Creation of anonymous functions, in-line, lambda expressions
• Closures
• Immutability
What REALY is FP ?
“Natural way of telling the computer what it should do, by
describing properties of a given problem in a concise language”
Programmers responsibility in FP ?
Specify functions to describe a given set of problems
Object Oriented Programming
• Encapsulation
• Combining data and behavior into classes and objects
• Modeling Real-World
Relationship FP to OOP
• No silver bullet
• Programmer needs to understand different techniques
Why to talk about ?
• Concurrency programming models
• Writing software it’s a complex process
• Managing side effects
Part 1 – Make it simple
Composing dependencies
The OOP way
IoC container granted from the start.
Developers argue about which framework to chose and not the
problem to solve.
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
try
{
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
catch (Exception e)
{
// log
}
}
New requirements
Log, Security, Audit, Cache…Cross Cutting Concerns
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
private readonly UnitOfWork _unitOfWork;
private readonly EnrollementNotificationService _notificationService;
private readonly ILogger _logger;
private readonly AuthorizationService _authorizationService;
private readonly CalendarService _calendarService;
private readonly ServiceFoo _serviceFoo;
private readonly ServiceBlah _serviceBlah;
private readonly FactoryFoo _facoFactoryFoo;
private readonly FactoryBlah _factoryBlah;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository,
UnitOfWork unitOfWork,
EnrollementNotificationService notificationService,
ILogger logger,
AuthorizationService authorizationService,
CalendarService calendarService,
ServiceFoo serviceFoo,
ServiceBlah serviceBlah,
FactoryFoo facoFactoryFoo,
FactoryBlah factoryBlah
)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
_unitOfWork = unitOfWork;
_notificationService = notificationService;
_logger = logger;
_authorizationService = authorizationService;
_calendarService = calendarService;
_serviceFoo = serviceFoo;
_serviceBlah = serviceBlah;
_facoFactoryFoo = facoFactoryFoo;
_factoryBlah = factoryBlah;
}
}
public void Handles(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
try
{
_unitOfWork.BeginTransaction();
student.TryEnrollIn(@class);
@class.TryEnroll(student);
…or better… AOP to the rescue
[Logable]
[Authorizable]
[Cachable]
[ExceptionPolicy]
[Blablable]
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Handles(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
try
{
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
catch (Exception e)
{
// log
}
}
Yes, but container can do more !
AOP with interception
var calculator = new Calculator();
var calculatorProxy = Intercept.ThroughProxy<ICalculator>(calculator,
new InterfaceInterceptor(), new[] { new LogBehavior() });
but one must :
• know Dynamic Proxy pattern
• know the difference of Instance and Type Interceptors
• know Interception behaviors
• not forget VIRTUAL keyword on methods
• wire up IoC container correctly
Really ?!!! Is this…
SIMPLE ?
Functional programming in C#
DI flavors
IoC with conventions...
Scan(x =>
{
x.TheCallingAssembly();
x.ExcludeNamespaceContainingType<IEvent>();
x.ExcludeNamespaceContainingType<SearchModel>();
x.ExcludeNamespaceContainingType<AuthenticationService>()
x.ExcludeNamespaceContainingType<DovetailController>();
x.AddAllTypesOf<IDomainMap>();
x.WithDefaultConventions();
DI flavors
IoC with conventions...
Scan(x =>
{
x.TheCallingAssembly();
x.ExcludeNamespaceContainingType<IEvent>();
x.ExcludeNamespaceContainingType<SearchModel>();
x.ExcludeNamespaceContainingType<AuthenticationService>()
x.ExcludeNamespaceContainingType<DovetailController>();
x.AddAllTypesOf<IDomainMap>();
x.WithDefaultConventions();
DI flavors
IoC with manual configuration...
var container = new UnityContainer();
container.RegisterType<IService, Service>(“Service”);
container.RegisterType<IService,ServiceDecorator>(
new InjectionConstructor(new ResolvedParameter(typeof(IS
Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne
c.Resolve<ISubServiceProvider();
));
container.AddNewExtension<DecoratorContainerExtension>();
container.RegisterType<IService, ServiceDecorator>();
DI flavors
IoC with manual configuration...
var container = new UnityContainer();
container.RegisterType<IService, Service>(“Service”);
container.RegisterType<IService,ServiceDecorator>(
new InjectionConstructor(new ResolvedParameter(typeof(IS
Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne
c.Resolve<ISubServiceProvider();
));
container.AddNewExtension<DecoratorContainerExtension>();
container.RegisterType<IService, ServiceDecorator>();
DI flavors
IoC with XML configuration...
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" />
<typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" />
<typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" />
<typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" />
<typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" />
<typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" />
</typeAliases>
<containers>
<container>
<types>
<type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/>
<type type="ILogger" mapTo="DebugLogger" name="debugLogger"/>
<type type="IContext" mapTo="UnityContext">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi
<constructor>
<param name="logger" parameterType="ILogger">
DI flavors
IoC with XML configuration...
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" />
<typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" />
<typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" />
<typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" />
<typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" />
<typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" />
</typeAliases>
<containers>
<container>
<types>
<type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/>
<type type="ILogger" mapTo="DebugLogger" name="debugLogger"/>
<type type="IContext" mapTo="UnityContext">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi
<constructor>
<param name="logger" parameterType="ILogger">
DI flavors
IoC with XML configuration...
<unity>
<typeAliases>
<typeAlias alias="string" type="System.String, mscorlib" />
<typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" />
<typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" />
<typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" />
<typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" />
<typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" />
<typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" />
</typeAliases>
<containers>
<container>
<types>
<type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/>
<type type="ILogger" mapTo="DebugLogger" name="debugLogger"/>
<type type="IContext" mapTo="UnityContext">
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi
<constructor>
<param name="logger" parameterType="ILogger">
What problem do we try to solve ?
• Decoupling ?
• Testing ?
• Modular Design ?
• Dependencies management ?
Dependencies are bad....
public class EnrollmentCommandHandler
{
public EnrollmentCommandHandler(StudentRepository studentReposit
ClassRepository classReposit
StudentArchiveRepository stu
UnitOfWork unitOfWork,
EnrollementNotificationServi
ILogger logger,
AuthorizationService authori
CalendarService calendarServ
ServiceFoo serviceFoo,
ServiceBlah serviceBlah,
FactoryFoo facoFactoryFoo,
FactoryBlah factoryBlah
Cyclic dependencies are evil....
public class EnrollmentCommandHandler
{
public EnrollmentCommandHandler(StudentRepository studentReposit
ClassRepository classReposit
StudentArchiveRepository stu
UnitOfWork unitOfWork,
EnrollementNotificationServi
ILogger logger,
AuthorizationService authori
CalendarService calendarServ
ServiceFoo serviceFoo,
ServiceBlah serviceBlah,
FactoryFoo facoFactoryFoo,
FactoryBlah factoryBlah
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
}
Code we have....
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
}
Code that matters…
The rest is Plumbing code
Functional way
int Multiply(int a, int b)
{
return a * b;
}
Partial application
Func<int, int> multiplyBy10 = b => Multiply(10, b);
Functional way int a = 3;
int b = a + 7;
int c = b * 10;
Composition
Func<int, int> calcCFromA = a => CalcC(CalcB(a));
int CalcCFromA(int a)
{
return (a + 7) * 10;
}
int CalcCFromA(int a)
{
return CalcC(CalcB(a));
}
let calcCFromA = calcB >> calcC
public class EnrollmentCommandHandler
{
private readonly StudentRepository _studentRepository;
private readonly ClassRepository _classRepository;
private readonly StudentArchiveRepository _studentArchiveRepository;
public EnrollmentCommandHandler(StudentRepository studentRepository,
ClassRepository classRepository,
StudentArchiveRepository studentArchiveRepository)
{
_studentRepository = studentRepository;
_classRepository = classRepository;
_studentArchiveRepository = studentArchiveRepository;
}
public void Enroll(StudentEnrollCommand command)
{
var student = _studentRepository.GetById(command.StudentId);
var @class = _classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
}
Refactor this…
public void Enroll(StudentRepository studentRepository,
ClassRepository classRepository,
StudentEnrollCommand command)
{
var student = studentRepository.GetById(command.StudentId);
var @class = classRepository.GetById(command.ClassId);
student.TryEnrollIn(@class);
@class.TryEnroll(student);
student.Enroll(@class);
@class.Enroll(student);
}
to this…
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
var pipeline = c =>
handlers.Enroll(studentRepository, classRepository, c);
Bootstrap in one place…
_handlers.Dispatch(new StudentEnrollCommand(1));
=
pipeline(new StudentEnrollCommand(1));
Handle in another…
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
var pipeline
= c =>
handlers.Log(c, c1 =>
handlers.Enroll(studentRepository, classRepository, c1));
Want to log ?
var studentRepository = new StudentRepository();
var classRepository = new ClassRepository();
var studentEnrollPipeline
= c =>
handlers.Audit(c, c1 =>
handlers.Log(c1, c2 =>
handlers.Enroll(studentRepository,classRepository, c2));
Audit ?
var lifeTime = new LifeTime();
var studentRepositoryFactory = () => new StudentRepository();
var classRepositoryFactory = () => new ClassRepository();
var studentEnrollPipeline
= c =>
handlers.Audit(c, c1 =>
handlers.Log(c1, c2 =>
handlers.Enroll(lifeTime.PerThread(studentRepositoryFactory),
lifeTime.PerThread(classRepositoryFactory), c2));
Lifetime management ?
Why to do it ?
• 99% of time you don’t have a problem for IoC container
• IoC makes easier things you shouldn’t be doing anyway
• Feel the pain and think
To many dependencies ?
• You have another serious problem
Is this…
SIMPLE ?
Is is just pure C# code
Part 2 – Control complexity
Composition strikes again…but in different shape
Writing a program using functions
How to order sequence of functions ?
ParseCopyright(string text) { return text + “©” }
ParseAppendix(string text) { return text.Remove(“APPENDIX”); }
Solution
By composing them
ParseCopyright(ParseAppendix(text));
But this can fail
ParseAppendix function may throw an exception
Solution
Return two kind of things from ParseAppendix function
string string
Instead of Let’s allow
string
string
Error
or
But function can return one thing
And only one thing
Solution
Put in in the box
string ParseResult
What happens to this now ?
ParseCopyright(ParseAppendix(text));
string ParseResultParseAppendix ParseCopyright
is success
Solution
Let’s have a special “link”/”connect”/”compose” function
string ParseResultParseAppendix ParseCopyrightstring
Error
Connect
What we have seen is a…
M***D
Demo
Functional programming in C#
Functional programming in C#
Composition
Composition is the key to controlling complexity in software.
“In our study of program design, we have seen that expert
programmers control the complexity of their designs with the
same general techniques used by designers of all complex
systems. They combine primitive elements to form
compound objects, they abstract compound objects to
form higher-level building blocks, and they preserve
modularity by adopting appropriate large-scale views of system
structure.”
Should I do functional programming
in C# ?
To take away
• Be stupid! Don’t waste your brain on complicated code
• Don’t waste your time to understand Rube Goldberg machines
• Simplicity. Write only the code that matters.
• Readability
• Less bugs
Questions ?
Thanks

More Related Content

PPTX
Functional Dependency Injection in C#
Thomas Jaskula
 
PPTX
Wiesław Kałkus: C# functional programming
AnalyticsConf
 
PDF
Dependency Injection
Giovanni Scerra ☃
 
PPTX
Inversion of Control and Dependency Injection
Dinesh Sharma
 
PPTX
Dependency Injection Inversion Of Control And Unity
rainynovember12
 
PPTX
Introduction to OO, Java and Eclipse/WebSphere
eLink Business Innovations
 
PPTX
Skillwise EJB3.0 training
Skillwise Group
 
PDF
Dependency injection Drupal Camp Wrocław 2014
Greg Szczotka
 
Functional Dependency Injection in C#
Thomas Jaskula
 
Wiesław Kałkus: C# functional programming
AnalyticsConf
 
Dependency Injection
Giovanni Scerra ☃
 
Inversion of Control and Dependency Injection
Dinesh Sharma
 
Dependency Injection Inversion Of Control And Unity
rainynovember12
 
Introduction to OO, Java and Eclipse/WebSphere
eLink Business Innovations
 
Skillwise EJB3.0 training
Skillwise Group
 
Dependency injection Drupal Camp Wrocław 2014
Greg Szczotka
 

What's hot (20)

PPT
Deployment
Roy Antony Arnold G
 
PPTX
Tech io spa_angularjs_20130814_v0.9.5
Ganesh Kondal
 
PPTX
Spring FrameWork Tutorials Java Language
Mahika Tutorials
 
PPTX
Dependency injection - the right way
Thibaud Desodt
 
PPT
Silverlight 2 for Developers - TechEd New Zealand 2008
Jonas Follesø
 
ODP
CDI @javaonehyderabad
Prasad Subramanian
 
PDF
Introduction au Web
Lilia Sfaxi
 
PPTX
Behaviour Driven Development V 0.1
willmation
 
PPTX
Poco Es Mucho: WCF, EF, and Class Design
James Phillips
 
ODP
Hibernate complete Training
sourabh aggarwal
 
PPT
Unit Testing Documentum Foundation Classes Code
BlueFish
 
PPTX
Building Large Scale PHP Web Applications with Laravel 4
Darwin Biler
 
PPTX
Bridging the communication Gap & Continuous Delivery
masoodjan
 
PDF
Javascript Design Patterns
Lilia Sfaxi
 
PDF
Java persistence api 2.1
Rakesh K. Cherukuri
 
PDF
The Zen of Inversion of Control
christopherfairbairn
 
PPTX
JPA For Beginner's
NarayanaMurthy Ganashree
 
PDF
Dependency Injection with Unity Container
Mindfire Solutions
 
PDF
Design Patterns in iOS
Yi-Shou Chen
 
ODP
Spring survey
Chris Roeder
 
Tech io spa_angularjs_20130814_v0.9.5
Ganesh Kondal
 
Spring FrameWork Tutorials Java Language
Mahika Tutorials
 
Dependency injection - the right way
Thibaud Desodt
 
Silverlight 2 for Developers - TechEd New Zealand 2008
Jonas Follesø
 
CDI @javaonehyderabad
Prasad Subramanian
 
Introduction au Web
Lilia Sfaxi
 
Behaviour Driven Development V 0.1
willmation
 
Poco Es Mucho: WCF, EF, and Class Design
James Phillips
 
Hibernate complete Training
sourabh aggarwal
 
Unit Testing Documentum Foundation Classes Code
BlueFish
 
Building Large Scale PHP Web Applications with Laravel 4
Darwin Biler
 
Bridging the communication Gap & Continuous Delivery
masoodjan
 
Javascript Design Patterns
Lilia Sfaxi
 
Java persistence api 2.1
Rakesh K. Cherukuri
 
The Zen of Inversion of Control
christopherfairbairn
 
JPA For Beginner's
NarayanaMurthy Ganashree
 
Dependency Injection with Unity Container
Mindfire Solutions
 
Design Patterns in iOS
Yi-Shou Chen
 
Spring survey
Chris Roeder
 
Ad

Viewers also liked (18)

PPTX
CQRS recipes or how to cook your architecture
Thomas Jaskula
 
PPTX
Leveraging more then DDD Lite in the startup project
Thomas Jaskula
 
PDF
Getting better
Tom Janssens
 
PPTX
Rx- Reactive Extensions for .NET
Jakub Malý
 
PDF
What is "Domain Driven Design" and what can you expect from it?
Tom Janssens
 
PDF
A Quick Intro to ReactiveX
Troy Miles
 
PDF
Dependency Injection
Fabien Potencier
 
PDF
Domain Driven Design
Pascal Larocque
 
PDF
Common ddd pitfalls
Tom Janssens
 
PDF
Selling ddd
Tom Janssens
 
PDF
Functional Reactive Programming / Compositional Event Systems
Leonardo Borges
 
PDF
Domain-driven design - tactical patterns
Tom Janssens
 
PPTX
Functional Programming with C#
EastBanc Tachnologies
 
PDF
Functional Programming in C# and F#
Alfonso Garcia-Caro
 
PDF
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...
Wes McKinney
 
PDF
Taste-of-Summit: Discover the Foundations of Digital Transformation
Eric D. Schabell
 
PPTX
CQRS and Event Sourcing, An Alternative Architecture for DDD
Dennis Doomen
 
PPTX
Why functional programming in C# & F#
Riccardo Terrell
 
CQRS recipes or how to cook your architecture
Thomas Jaskula
 
Leveraging more then DDD Lite in the startup project
Thomas Jaskula
 
Getting better
Tom Janssens
 
Rx- Reactive Extensions for .NET
Jakub Malý
 
What is "Domain Driven Design" and what can you expect from it?
Tom Janssens
 
A Quick Intro to ReactiveX
Troy Miles
 
Dependency Injection
Fabien Potencier
 
Domain Driven Design
Pascal Larocque
 
Common ddd pitfalls
Tom Janssens
 
Selling ddd
Tom Janssens
 
Functional Reactive Programming / Compositional Event Systems
Leonardo Borges
 
Domain-driven design - tactical patterns
Tom Janssens
 
Functional Programming with C#
EastBanc Tachnologies
 
Functional Programming in C# and F#
Alfonso Garcia-Caro
 
Practical Medium Data Analytics with Python (10 Things I Hate About pandas, P...
Wes McKinney
 
Taste-of-Summit: Discover the Foundations of Digital Transformation
Eric D. Schabell
 
CQRS and Event Sourcing, An Alternative Architecture for DDD
Dennis Doomen
 
Why functional programming in C# & F#
Riccardo Terrell
 
Ad

Similar to Functional programming in C# (20)

PDF
Design Pattern Observations
Dmitri Nesteruk
 
PDF
Enforce Consistentcy with Clean Architecture
Florin Coros
 
PPTX
C# 6 and 7 and Futures 20180607
Kevin Hazzard
 
PPTX
F# in the enterprise
7sharp9
 
PDF
Reinventing the Transaction Script (NDC London 2020)
Scott Wlaschin
 
PDF
Functional Design Patterns (DevTernity 2018)
Scott Wlaschin
 
PPT
Manage software dependencies with ioc and aop
Stefano Leli
 
PPTX
Functional DDD
Alessandro Melchiori
 
PPTX
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
tdc-globalcode
 
PPTX
Solid Software Design Principles
Jon Kruger
 
PPTX
Most Useful Design Patterns
Steven Smith
 
PDF
Dot Net Design Patterns Interview Questions PDF By ScholarHat
Scholarhat
 
PPTX
F# as our day job by 2016
Tomas Jansson
 
PDF
.Net template solution architecture
Diogo Gonçalves da Cunha
 
PDF
[4DEV] Bartosz Sokół - Functional developer in object oriented world - how F#...
PROIDEA
 
KEY
SOLID Principles
Chris Weldon
 
PPTX
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
David Wengier
 
PPTX
An Introduction To CQRS
Neil Robbins
 
PPTX
Mixing functional programming approaches in an object oriented language
Mark Needham
 
PDF
Epic.NET: Processes, patterns and architectures
Giacomo Tesio
 
Design Pattern Observations
Dmitri Nesteruk
 
Enforce Consistentcy with Clean Architecture
Florin Coros
 
C# 6 and 7 and Futures 20180607
Kevin Hazzard
 
F# in the enterprise
7sharp9
 
Reinventing the Transaction Script (NDC London 2020)
Scott Wlaschin
 
Functional Design Patterns (DevTernity 2018)
Scott Wlaschin
 
Manage software dependencies with ioc and aop
Stefano Leli
 
Functional DDD
Alessandro Melchiori
 
TDC2016POA | Trilha .NET - C# como você nunca viu: conceitos avançados de pro...
tdc-globalcode
 
Solid Software Design Principles
Jon Kruger
 
Most Useful Design Patterns
Steven Smith
 
Dot Net Design Patterns Interview Questions PDF By ScholarHat
Scholarhat
 
F# as our day job by 2016
Tomas Jansson
 
.Net template solution architecture
Diogo Gonçalves da Cunha
 
[4DEV] Bartosz Sokół - Functional developer in object oriented world - how F#...
PROIDEA
 
SOLID Principles
Chris Weldon
 
Lowering in C#: What really happens with your code?, from NDC Oslo 2019
David Wengier
 
An Introduction To CQRS
Neil Robbins
 
Mixing functional programming approaches in an object oriented language
Mark Needham
 
Epic.NET: Processes, patterns and architectures
Giacomo Tesio
 

Recently uploaded (20)

PPTX
Why Use Open Source Reporting Tools for Business Intelligence.pptx
Varsha Nayak
 
PDF
How to Seamlessly Integrate Salesforce Data Cloud with Marketing Cloud.pdf
NSIQINFOTECH
 
PDF
Become an Agentblazer Champion Challenge
Dele Amefo
 
DOCX
The Future of Smart Factories Why Embedded Analytics Leads the Way
Varsha Nayak
 
PPT
Overview of Oracle Receivables Process.ppt
nbvreddy229
 
PDF
Bandai Playdia The Book - David Glotz
BluePanther6
 
PPTX
Materi_Pemrograman_Komputer-Looping.pptx
RanuFajar1
 
PPTX
10 Hidden App Development Costs That Can Sink Your Startup.pptx
Lunar Web Solution
 
PPTX
What to Capture When It Breaks: 16 Artifacts That Reveal Root Causes
Tier1 app
 
PPTX
Audio Editing and it's techniques in computer graphics.pptx
fosterbayirinia3
 
PDF
Winning Business in a Slowing Economy, How CPQ helps Manufacturers Protect Ma...
systemscincom
 
PDF
Solar Panel Installation Guide – Step By Step Process 2025.pdf
CRMLeaf
 
PDF
Become an Agentblazer Champion Challenge Kickoff
Dele Amefo
 
PPTX
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PPTX
Presentation of Computer CLASS 2 .pptx
darshilchaudhary558
 
PPTX
Save Business Costs with CRM Software for Insurance Agents
Insurance Tech Services
 
PDF
The Role of Automation and AI in EHS Management for Data Centers.pdf
TECH EHS Solution
 
PPTX
Materi-Enum-and-Record-Data-Type (1).pptx
RanuFajar1
 
PDF
Micromaid: A simple Mermaid-like chart generator for Pharo
ESUG
 
PDF
Why Use Open Source Reporting Tools for Business Intelligence.pdf
Varsha Nayak
 
Why Use Open Source Reporting Tools for Business Intelligence.pptx
Varsha Nayak
 
How to Seamlessly Integrate Salesforce Data Cloud with Marketing Cloud.pdf
NSIQINFOTECH
 
Become an Agentblazer Champion Challenge
Dele Amefo
 
The Future of Smart Factories Why Embedded Analytics Leads the Way
Varsha Nayak
 
Overview of Oracle Receivables Process.ppt
nbvreddy229
 
Bandai Playdia The Book - David Glotz
BluePanther6
 
Materi_Pemrograman_Komputer-Looping.pptx
RanuFajar1
 
10 Hidden App Development Costs That Can Sink Your Startup.pptx
Lunar Web Solution
 
What to Capture When It Breaks: 16 Artifacts That Reveal Root Causes
Tier1 app
 
Audio Editing and it's techniques in computer graphics.pptx
fosterbayirinia3
 
Winning Business in a Slowing Economy, How CPQ helps Manufacturers Protect Ma...
systemscincom
 
Solar Panel Installation Guide – Step By Step Process 2025.pdf
CRMLeaf
 
Become an Agentblazer Champion Challenge Kickoff
Dele Amefo
 
Visualising Data with Scatterplots in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Presentation of Computer CLASS 2 .pptx
darshilchaudhary558
 
Save Business Costs with CRM Software for Insurance Agents
Insurance Tech Services
 
The Role of Automation and AI in EHS Management for Data Centers.pdf
TECH EHS Solution
 
Materi-Enum-and-Record-Data-Type (1).pptx
RanuFajar1
 
Micromaid: A simple Mermaid-like chart generator for Pharo
ESUG
 
Why Use Open Source Reporting Tools for Business Intelligence.pdf
Varsha Nayak
 

Functional programming in C#

  • 1. Functional Programming in C# NCrafts 21-22 May, Paris 2015 @tjaskula
  • 2. What is functional programming ? • Functions as building blocks • Function returns values only based on the passed input • Recursion • HOF (Higher Order Functions) • Creation of anonymous functions, in-line, lambda expressions • Closures • Immutability
  • 3. What REALY is FP ? “Natural way of telling the computer what it should do, by describing properties of a given problem in a concise language”
  • 4. Programmers responsibility in FP ? Specify functions to describe a given set of problems
  • 5. Object Oriented Programming • Encapsulation • Combining data and behavior into classes and objects • Modeling Real-World
  • 6. Relationship FP to OOP • No silver bullet • Programmer needs to understand different techniques
  • 7. Why to talk about ? • Concurrency programming models • Writing software it’s a complex process • Managing side effects
  • 8. Part 1 – Make it simple Composing dependencies
  • 9. The OOP way IoC container granted from the start. Developers argue about which framework to chose and not the problem to solve.
  • 10. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); try { student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } catch (Exception e) { // log } }
  • 11. New requirements Log, Security, Audit, Cache…Cross Cutting Concerns
  • 12. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; private readonly UnitOfWork _unitOfWork; private readonly EnrollementNotificationService _notificationService; private readonly ILogger _logger; private readonly AuthorizationService _authorizationService; private readonly CalendarService _calendarService; private readonly ServiceFoo _serviceFoo; private readonly ServiceBlah _serviceBlah; private readonly FactoryFoo _facoFactoryFoo; private readonly FactoryBlah _factoryBlah; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository, UnitOfWork unitOfWork, EnrollementNotificationService notificationService, ILogger logger, AuthorizationService authorizationService, CalendarService calendarService, ServiceFoo serviceFoo, ServiceBlah serviceBlah, FactoryFoo facoFactoryFoo, FactoryBlah factoryBlah ) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; _unitOfWork = unitOfWork; _notificationService = notificationService; _logger = logger; _authorizationService = authorizationService; _calendarService = calendarService; _serviceFoo = serviceFoo; _serviceBlah = serviceBlah; _facoFactoryFoo = facoFactoryFoo; _factoryBlah = factoryBlah; } } public void Handles(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); try { _unitOfWork.BeginTransaction(); student.TryEnrollIn(@class); @class.TryEnroll(student);
  • 13. …or better… AOP to the rescue
  • 14. [Logable] [Authorizable] [Cachable] [ExceptionPolicy] [Blablable] public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Handles(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); try { student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } catch (Exception e) { // log } }
  • 15. Yes, but container can do more !
  • 16. AOP with interception var calculator = new Calculator(); var calculatorProxy = Intercept.ThroughProxy<ICalculator>(calculator, new InterfaceInterceptor(), new[] { new LogBehavior() });
  • 17. but one must : • know Dynamic Proxy pattern • know the difference of Instance and Type Interceptors • know Interception behaviors • not forget VIRTUAL keyword on methods • wire up IoC container correctly
  • 18. Really ?!!! Is this… SIMPLE ?
  • 20. DI flavors IoC with conventions... Scan(x => { x.TheCallingAssembly(); x.ExcludeNamespaceContainingType<IEvent>(); x.ExcludeNamespaceContainingType<SearchModel>(); x.ExcludeNamespaceContainingType<AuthenticationService>() x.ExcludeNamespaceContainingType<DovetailController>(); x.AddAllTypesOf<IDomainMap>(); x.WithDefaultConventions();
  • 21. DI flavors IoC with conventions... Scan(x => { x.TheCallingAssembly(); x.ExcludeNamespaceContainingType<IEvent>(); x.ExcludeNamespaceContainingType<SearchModel>(); x.ExcludeNamespaceContainingType<AuthenticationService>() x.ExcludeNamespaceContainingType<DovetailController>(); x.AddAllTypesOf<IDomainMap>(); x.WithDefaultConventions();
  • 22. DI flavors IoC with manual configuration... var container = new UnityContainer(); container.RegisterType<IService, Service>(“Service”); container.RegisterType<IService,ServiceDecorator>( new InjectionConstructor(new ResolvedParameter(typeof(IS Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne c.Resolve<ISubServiceProvider(); )); container.AddNewExtension<DecoratorContainerExtension>(); container.RegisterType<IService, ServiceDecorator>();
  • 23. DI flavors IoC with manual configuration... var container = new UnityContainer(); container.RegisterType<IService, Service>(“Service”); container.RegisterType<IService,ServiceDecorator>( new InjectionConstructor(new ResolvedParameter(typeof(IS Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(ne c.Resolve<ISubServiceProvider(); )); container.AddNewExtension<DecoratorContainerExtension>(); container.RegisterType<IService, ServiceDecorator>();
  • 24. DI flavors IoC with XML configuration... <unity> <typeAliases> <typeAlias alias="string" type="System.String, mscorlib" /> <typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" /> <typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" /> <typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" /> <typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" /> <typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" /> <typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" /> </typeAliases> <containers> <container> <types> <type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/> <type type="ILogger" mapTo="DebugLogger" name="debugLogger"/> <type type="IContext" mapTo="UnityContext"> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi <constructor> <param name="logger" parameterType="ILogger">
  • 25. DI flavors IoC with XML configuration... <unity> <typeAliases> <typeAlias alias="string" type="System.String, mscorlib" /> <typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" /> <typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" /> <typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" /> <typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" /> <typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" /> <typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" /> </typeAliases> <containers> <container> <types> <type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/> <type type="ILogger" mapTo="DebugLogger" name="debugLogger"/> <type type="IContext" mapTo="UnityContext"> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi <constructor> <param name="logger" parameterType="ILogger">
  • 26. DI flavors IoC with XML configuration... <unity> <typeAliases> <typeAlias alias="string" type="System.String, mscorlib" /> <typeAlias alias="ILogger" type="UnitySamples.ILogger, UnitySamples" /> <typeAlias alias="ConsoleLogger" type="UnitySamples.ConsoleLogger, UnitySamples" /> <typeAlias alias="DebugLogger" type="UnitySamples.DebugLogger, UnitySamples" /> <typeAlias alias="IContext" type="UnitySamples.IContext, UnitySamples" /> <typeAlias alias="UnityContext" type="UnitySamples.UnityContext, UnitySamples" /> <typeAlias alias="CustomerTasks" type="UnitySamples.CustomerTasks, UnitySamples" /> </typeAliases> <containers> <container> <types> <type type="ILogger" mapTo="ConsoleLogger" name="defaultLogger"/> <type type="ILogger" mapTo="DebugLogger" name="debugLogger"/> <type type="IContext" mapTo="UnityContext"> <typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practi <constructor> <param name="logger" parameterType="ILogger">
  • 27. What problem do we try to solve ? • Decoupling ? • Testing ? • Modular Design ? • Dependencies management ?
  • 28. Dependencies are bad.... public class EnrollmentCommandHandler { public EnrollmentCommandHandler(StudentRepository studentReposit ClassRepository classReposit StudentArchiveRepository stu UnitOfWork unitOfWork, EnrollementNotificationServi ILogger logger, AuthorizationService authori CalendarService calendarServ ServiceFoo serviceFoo, ServiceBlah serviceBlah, FactoryFoo facoFactoryFoo, FactoryBlah factoryBlah
  • 29. Cyclic dependencies are evil.... public class EnrollmentCommandHandler { public EnrollmentCommandHandler(StudentRepository studentReposit ClassRepository classReposit StudentArchiveRepository stu UnitOfWork unitOfWork, EnrollementNotificationServi ILogger logger, AuthorizationService authori CalendarService calendarServ ServiceFoo serviceFoo, ServiceBlah serviceBlah, FactoryFoo facoFactoryFoo, FactoryBlah factoryBlah
  • 30. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } } Code we have....
  • 31. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } } Code that matters…
  • 32. The rest is Plumbing code
  • 33. Functional way int Multiply(int a, int b) { return a * b; } Partial application Func<int, int> multiplyBy10 = b => Multiply(10, b);
  • 34. Functional way int a = 3; int b = a + 7; int c = b * 10; Composition Func<int, int> calcCFromA = a => CalcC(CalcB(a)); int CalcCFromA(int a) { return (a + 7) * 10; } int CalcCFromA(int a) { return CalcC(CalcB(a)); } let calcCFromA = calcB >> calcC
  • 35. public class EnrollmentCommandHandler { private readonly StudentRepository _studentRepository; private readonly ClassRepository _classRepository; private readonly StudentArchiveRepository _studentArchiveRepository; public EnrollmentCommandHandler(StudentRepository studentRepository, ClassRepository classRepository, StudentArchiveRepository studentArchiveRepository) { _studentRepository = studentRepository; _classRepository = classRepository; _studentArchiveRepository = studentArchiveRepository; } public void Enroll(StudentEnrollCommand command) { var student = _studentRepository.GetById(command.StudentId); var @class = _classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } } Refactor this…
  • 36. public void Enroll(StudentRepository studentRepository, ClassRepository classRepository, StudentEnrollCommand command) { var student = studentRepository.GetById(command.StudentId); var @class = classRepository.GetById(command.ClassId); student.TryEnrollIn(@class); @class.TryEnroll(student); student.Enroll(@class); @class.Enroll(student); } to this…
  • 37. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); var pipeline = c => handlers.Enroll(studentRepository, classRepository, c); Bootstrap in one place…
  • 39. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); var pipeline = c => handlers.Log(c, c1 => handlers.Enroll(studentRepository, classRepository, c1)); Want to log ?
  • 40. var studentRepository = new StudentRepository(); var classRepository = new ClassRepository(); var studentEnrollPipeline = c => handlers.Audit(c, c1 => handlers.Log(c1, c2 => handlers.Enroll(studentRepository,classRepository, c2)); Audit ?
  • 41. var lifeTime = new LifeTime(); var studentRepositoryFactory = () => new StudentRepository(); var classRepositoryFactory = () => new ClassRepository(); var studentEnrollPipeline = c => handlers.Audit(c, c1 => handlers.Log(c1, c2 => handlers.Enroll(lifeTime.PerThread(studentRepositoryFactory), lifeTime.PerThread(classRepositoryFactory), c2)); Lifetime management ?
  • 42. Why to do it ? • 99% of time you don’t have a problem for IoC container • IoC makes easier things you shouldn’t be doing anyway • Feel the pain and think
  • 43. To many dependencies ? • You have another serious problem
  • 44. Is this… SIMPLE ? Is is just pure C# code
  • 45. Part 2 – Control complexity Composition strikes again…but in different shape
  • 46. Writing a program using functions How to order sequence of functions ? ParseCopyright(string text) { return text + “©” } ParseAppendix(string text) { return text.Remove(“APPENDIX”); }
  • 48. But this can fail ParseAppendix function may throw an exception
  • 49. Solution Return two kind of things from ParseAppendix function string string Instead of Let’s allow string string Error or
  • 50. But function can return one thing And only one thing
  • 51. Solution Put in in the box string ParseResult
  • 52. What happens to this now ? ParseCopyright(ParseAppendix(text)); string ParseResultParseAppendix ParseCopyright
  • 53. is success Solution Let’s have a special “link”/”connect”/”compose” function string ParseResultParseAppendix ParseCopyrightstring Error Connect
  • 54. What we have seen is a… M***D
  • 55. Demo
  • 58. Composition Composition is the key to controlling complexity in software. “In our study of program design, we have seen that expert programmers control the complexity of their designs with the same general techniques used by designers of all complex systems. They combine primitive elements to form compound objects, they abstract compound objects to form higher-level building blocks, and they preserve modularity by adopting appropriate large-scale views of system structure.”
  • 59. Should I do functional programming in C# ?
  • 60. To take away • Be stupid! Don’t waste your brain on complicated code • Don’t waste your time to understand Rube Goldberg machines • Simplicity. Write only the code that matters. • Readability • Less bugs

Editor's Notes

  • #3: Functional programmers use functions as building blocks to create new functions. There are other language elements available to them but the function is the main construct that the architecture is built from Referential transparency or pure functions. In OOP program state often influences the return of the function
  • #4: What the problem you’re solving and not describing the precise way of the solution
  • #5: Then computer can decide on best evaluation order Parallization opportunities If certain functions can be evaluated at all
  • #7: Programmer needs to understand different techniques and make decisions for and against them based on the problem to solve at hand
  • #8: Very hard to achieve with imperative program accessing shared state. Store data in one place for read and writes (needs LOCKS) when accessible by many functions Complex process can be controlled by composition Side effects cannot be removed completely but can be reduced significantly
  • #10: We don't even question if IoC container is needed because nowadays this is considered granted. We argue between containers and theirs features rather than a correct application design.
  • #19: Can I explain it to junior developer ? Do you want to not hire developers because we don't have 2 years of teaching a framework ?
  • #20: How many developpers do you know that knows Rube Goldberg machine ? What to do if there is a bug in a framework ? You send an email to the group and pray
  • #45: Can I explain it to junior developer ?
  • #47: How can we say what is to be executed first? How can we form an ordered sequence of functions
  • #48: How can we say what is to be executed first? How can we form an ordered sequence of functions
  • #53: And, we don't want to change every function we could connect with ParseAppendix to consume a ParseResult .
  • #54: That way, we can, behind the scenes, adapt the output of one function to feed the following one. This algorithm must be written only once per "boxing type" (different box, different adapting algorithm)
  • #57: A Monad is a pattern for doing function composition with ‘amplified’ types. You can think of an amplified type as a generic type with a single type parameter. IEnumerable<T> is a very good example. Monads provide techniques for removing repetitive and awkward code and can allow us to significantly simplify many programming problems.
  • #59: Composition is the key to controlling complexity in software.