Functional programming as an alternative (additional) paradigm to OOP Mikhail Smal https://mikhail.dev
Who are you?
http://bonkersworld.net/object-world
AbstractToastHeaterGeneratorFactoryInterfaceImplementer abstractToastHeaterGeneratorFactoryInterfaceImplementer = new AbstractToastHeaterGeneratorFactoryInterfaceImplementer( AbstractToastHeaterGeneratorFactoryInterfaceImplementer.DEFAULT_PARAMS, 0, NULL);
Rien n'est plus dangereux qu'une idée, quand on n'a qu'une idée Émile-Auguste Chartier
Nothing is more dangerous than an idea, when you have only one idea Émile-Auguste Chartier
Nothing is more dangerous than an IDE, when you have only one IDE
Nothing is more dangerous than an OO, when you have only one object
http://bonkersworld.net/object-world
There are only two hard things in Computer Science: cache invalidation and naming things Phil Karlton
It is possible to do Object-Oriented programming in Java William Cook, "On Understanding Data Abstraction, Revisited"
public class Ellipse public class Ellipse { public double public double SemiMajorAxis SemiMajorAxis { get; set; } { get; set; } public double public double SemiMinorAxis SemiMinorAxis { get; set; } { get; set; } } public class Circle : Ellipse public class Circle : Ellipse { { public double Radius { get; set; } public double Radius { get; set; } }
publi blic c c class lass Ell Ellips ipse { publ ublic vi ic virtu rtual al doubl double e Semi emiMajor MajorAxi Axis { get; get; se set; t; } publ ublic vi ic virtu rtual al doubl double e Semi emiMinor MinorAxi Axis { get; get; se set; t; } } publi blic c c class lass Cir Circle cle : El : Ellip lipse se { ... .. publ ublic ov ic overr erride ide doub double le Sem SemiMajo iMajorAx rAxis is { get = get => . > ... .. set = set => t > thro hrow new w new NotSu tSupport pportedE edExce xception ption(); (); } ... ... publ ublic ov ic overr erride ide doub double le Sem SemiMino iMinorAx rAxis is { ... .. }
publi blic c c class lass Ell Ellips ipse { publ ublic do ic doubl uble e SemiMa emiMajor jorAxi Axis { g { get; et; } } publ ublic do ic doubl uble e SemiMi emiMinor norAxi Axis { g { get; et; } } publ ublic El ic Ellip lipse( se(doubl double e semi emiMajor MajorAxi Axis, doubl double e semi emiMinor MinorAxi Axis) { SemiM SemiMajo ajorAx rAxis is = = sem semiMa iMajorAx jorAxis is; SemiM emiMino norAx Axis = = sem emiMi MinorAx orAxis; } ... .. } pu publi lic c class ass Cir ircle le { publ ublic do ic doubl uble R e Radius adius { { get get; } ; } publ ublic Ci ic Circl rcle(d e(double ouble ra radiu dius) s) { Radiu Radius = s = ra radius; dius; } publ ublic El ic Ellip lipse se ToEll ToEllips ipse() { { ... .. }
publi blic c c class lass Ell Ellips ipse { publ ublic do ic doubl uble e SemiMa emiMajor jorAxi Axis { g { get; et; } } publ ublic do ic doubl uble e SemiMi emiMinor norAxi Axis { g { get; et; } } publ ublic El ic Ellip lipse( se(doubl double e semi emiMajor MajorAxi Axis, doubl double e semi emiMinor MinorAxi Axis) { SemiM SemiMajo ajorAx rAxis is = = sem semiMa iMajorAx jorAxis is; SemiM emiMino norAx Axis = = sem emiMi MinorAx orAxis; } ... .. publ ublic bo ic bool ol IsC IsCircle ircle => .. ... . } pu publi lic c class ass Cir ircle le { publ ublic do ic doubl uble R e Radius adius { { get get; } ; } publ ublic Ci ic Circl rcle(d e(double ouble ra radiu dius) s) { Radiu Radius = s = ra radius; dius; } publ ublic El ic Ellip lipse se ToEll ToEllips ipse() { { ... .. }
Just because you have a getter, doesn’t mean you should have a matching setter
public class Ellipse public class Ellipse { public double public double SemiMajorAxis SemiMajorAxis { get; set; } { get; set; } public double public double SemiMinorAxis SemiMinorAxis { get; set; } { get; set; } }
public class Ellipse public class Ellipse { public double public double SemiMajorAxis SemiMajorAxis { get; } { get; } public double public double SemiMinorAxis SemiMinorAxis { get; } { get; } public Ellipse(double public Ellipse(double semiMajorAxis semiMajorAxis, double , double semiMajorAxis semiMajorAxis) { SemiMajorAxis SemiMajorAxis = = semiMajorAxis semiMajorAxis; SemiMinorAxis SemiMinorAxis = = semiMinorAxis semiMinorAxis; } }
type Ellipse = type Ellipse = { { SemiMajorAxis SemiMajorAxis : float : float SemiMinorAxis SemiMinorAxis : float } : float } let ellipse = let ellipse = { { SemiMajorAxis SemiMajorAxis = 10. = 10. SemiMinorAxis SemiMinorAxis = 20. } = 20. } let let newEllipse newEllipse = { ellipse with { ellipse with SemiMinorAxis SemiMinorAxis = 30. } = 30. }
Encapsulation Polymorphism Inheritance
public public IConnection IConnection CreateConnection CreateConnection(Provider (Provider connectionProvider connectionProvider) { ... ...
public public Pool ooledC edConnect onnection ion ConnectT ConnectTo(Pr (Provi ovider er ofU ofUpdates pdates) { ... ...
Object-oriented vs Functional
Imperative vs Declarative
var var numb numbers ers = [1 = [10, 3 0, 3, 7, , 7, 1, 1, 25] 25] num numbers ers.sor sort() ()
func function tion sor sorted( ted(numb numbers) ers) { { ... ... }
Excel is the world's most popular functional language Simon Peyton-Jones
There is no state in math
f(x f(x) = = expr xpressi ssion
In functional programming, programs are executed by evaluating expressions, in contrast with imperative programming where programs are composed of statements which change global state when executed. Functional programming typically avoids using mutable state. https://wiki.haskell.org/Functional_programming
Many programming languages support programming in both functional and imperative style but the syntax and facilities of a language are typically optimised for only one of these styles, and social factors like coding conventions and libraries often force the programmer towards one of the styles. https://wiki.haskell.org/Functional_programming
int int squa square(i re(int x nt x) { { retu return x rn x * x * x; }
func function tion squ square( are(x) { x) { ret return rn x * * x }
public class Math public class Math { { public static int Square(int x) public static int Square(int x) { return x * x; return x * x; } }
squa square(X re(X) ) -> X * X * X. X.
square : squa re :: In : Int t -> > Int Int squa square x re x = x = x * x * x
▪ do do Loops ▪ foreach foreach ▪ for for ▪ while while
fun funct ction ion f fact actor orial ial(n (n) { ) { var ar re resul sult t = 1 = 1; whil hile e (n (n > > 1) 1) re resul sult t *= *= n-- --; retu eturn rn re resu sult; lt; }
fun funct ction ion f fact actor orial ial(n (n) { ) { if ( f (n n > 1 > 1) re retur turn n n * n * f fact actor orial ial(n (n - 1) 1); else lse re retur turn n 1; 1; }
fun funct ction ion f fact actor orial ial(n (n) { ) { retu eturn rn ( ( n > 1 n > 1 ? ? n * n * f fact actor orial ial(n (n - 1) 1) : : 1); 1); }
funct function f ion factor actorial(n ial(n) { ) { fun functi ction lo on loop(n, op(n, resu result) { lt) { re return turn ( ( n > n > 1 1 ? l ? loop( oop(n n - 1, 1, n * n * re resul sult) t) : r : result esult); ); } ret return urn loop loop(n, 1 (n, 1); ); }
𝒐! = ቊ 𝟐, 𝒐 = 𝟏, 𝒐 − 𝟐 ! × 𝒐, 𝒐 > 𝟏.
𝑜 𝑜! = ෑ 𝑙 𝑙=1
fac factori orial n l n = p = produ oduct [ t [1..n ..n]
fac factori orial n l n = f = foldl ldl (*) (*) 1 [ 1 [1..n ..n]
f(x f(x) = = λ x • exp express ression ion
Lambda-calculus was the first object-oriented language (1941) William Cook, "On Understanding Data Abstraction, Revisited"
A higher-order function is a function that takes other functions as arguments or returns a function as result. https://wiki.haskell.org/Higher_order_function
squa square = re = fun functio ction (x n (x) { ) { ret return rn x * * x; }
squ square re = x x => x > x * x * x
squ square re = \x x -> x > x * * x
map map squa square [ re [1..1 1..100] 00]
map map (\x x -> x > x * * x) [ ) [1..1 ..100] 0]
pro product uct = = fo foldr ldr (*) *) 1
Partial application is the conversion of a polyadic function into a function taking fewer arguments by providing one or more arguments in advance. http://raganwald.com/2013/03/07/currying-and-partial-application.html
f( ) f( ) g( ) g( ) h( ) h( ) x x
(f ∙ g ∙ h)(x)
x x . h h f g
(f . g . h) x (f . g . h) x
Recommend
More recommend