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”
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
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>();
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
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.”
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
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
What the problem you’re solving and not describing the precise way of the solution
Then computer can decide
on best evaluation order
Parallization opportunities
If certain functions can be evaluated at all
Programmer needs to understand different techniques and make decisions for and against them based on the problem to solve at hand
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
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.
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 ?
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
Can I explain it to junior developer ?
How can we say what is to be executed first? How can we form an ordered sequence of functions
How can we say what is to be executed first? How can we form an ordered sequence of functions
And, we don't want to change every function we could connect with ParseAppendix to consume a ParseResult .
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)
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.
Composition is the key to controlling complexity in software.