deft/archives/pres-FP-Survey.org

287 lines
9.5 KiB
Org Mode
Raw Permalink Normal View History

2017-12-27 23:32:14 +00:00
#+Title: Functional Programming Overview
2017-12-07 15:44:09 +00:00
#+Author: Yann Esposito
2017-08-24 18:58:13 +00:00
2017-12-27 23:32:14 +00:00
- Intro & Brief History Overview
- Major Principles (Theory)
- Major Languages (Practice)
2018-02-17 11:34:40 +00:00
* math function vs Procedures.
2017-12-27 23:32:14 +00:00
- *Immutable*: avoids changing-state and mutable data
- *Declarative programming*: expression or declarations instead of statements
2017-12-07 15:44:09 +00:00
- *Pure*:
- Output value of a function depends *only* on the arguments that are input to the function
- Eliminating side-effects, easier to reason about code and predict behavior
2017-12-27 23:32:14 +00:00
- Evaluation order and timing are a separated concern from function results
- *Functions are first-class*:
2017-12-07 15:44:09 +00:00
- functions are treated like any other values.
- functions can be passed as arguments to other functions
- functions can returns other functions
2017-12-27 23:32:14 +00:00
* Brief History Overview
2017-12-07 15:44:09 +00:00
** Short
- λ-Calculus, Alonzo Church & Rosser 1936
- LISP (McCarthy 1960)
- Algol 60 (Naur et al 1963)
- ISWIM (Landin 1966)
- PAL (Evans 1968)
- SASL (1973-83)
- Edinburgh (1969-80) NLP, early ML, HOPE
- Miranda (1986)
- Haskell (1992‥)
** λ-Calculus
2017-08-24 18:58:13 +00:00
*** λ-Calculus, Alonzo Church & Rosser 1936
Typeless theory of functions.
A syntaxic construction can be equivalent to any Turing Machine.
Mainly re-writing rules.
2017-12-07 15:44:09 +00:00
*** Learn λ-Calculus in less than 1 minute
*** Definitions
2017-08-24 18:58:13 +00:00
- =a,b,...= are variables
- =()= parenthesis to group part of an expression
- =λ= greek letter (pronounced Lambda) and the =.= to write functions.
2017-12-07 15:44:09 +00:00
*** Free vs Bound
2017-08-24 18:58:13 +00:00
- =λx.xy= the expression is open as =xy= contains a =y= and there is no =λy= that bound it.
- =λx.λy.xy= is said to be bound.
Bound expressions represent functions.
2017-12-07 15:44:09 +00:00
*** Rules
2017-12-27 23:32:14 +00:00
(α) =λx.A → λy.[y/x]A=
(β) =(λx.A)B → [B/x]A=
(η) =λx.Ax → A= if =x= not free in =A=
Where =[B/x]A= means substitue =B= for free occurrences of =x= in =A=.
Examples:
(α) =λx.(f x z x) → λy.(f y z y)=
2018-02-17 11:34:40 +00:00
(β) =(λx.(f x y))2 → (f 2 y)=
2017-12-27 23:32:14 +00:00
(η) =λx.f x → f=
2017-08-24 18:58:13 +00:00
2017-12-07 15:44:09 +00:00
*** Resume
How does that work? Simply cut and paste! That's it.
2017-08-24 18:58:13 +00:00
Example: =(λy.x(yz))(ab)=
So =(ab)= is an expression we apply to the function =(λy.x(yz))=.
So replace =y= by =ab= and we get: =x(abz)=.
And...
That's it.
2017-12-07 15:44:09 +00:00
** LISP
2017-08-24 18:58:13 +00:00
*** LISP (McCarthy 1960)
The first functional programming language and the second oldest programming
language stil in use (after FORTRAN).
2017-12-07 15:44:09 +00:00
*** LISP: S-Language
2017-08-24 18:58:13 +00:00
- atom which are words like X or TWO
- pairing operation written as a dot
2017-12-07 15:44:09 +00:00
#+BEGIN_SRC elisp
((X.Y).Z)
(ONE.(TWO.(THREE.NIL)))
#+END_SRC
2017-08-24 18:58:13 +00:00
List, Trees, etc..
2017-12-07 15:44:09 +00:00
*** LISP: M-Language
2017-08-24 18:58:13 +00:00
defines computations on S-exrepssions. It has
- S-expressions
- function application (=f[a;b;...]=) with primitve functions =cons=, =car=, =cdr=, =atom=, =eq=
- conditional expressions (=[ test1 -> result1 ; test2 -> result2 ; ... ]=)
- ability to define recursive functions (=first[x] = [atom [x] -> x ; T -> first[car[x]]]=)
2017-12-07 15:44:09 +00:00
*** LISP: Encode M-Language exprs as S-Expressions
Encoding M-Language expressions and functions as S-Expressions:
Define M-language functions =eval= and =apply= that correctly interpret these
S-expressions
2017-08-24 18:58:13 +00:00
Thus LISP allow meta-programming: treating program as data and vice versa
2017-12-07 15:44:09 +00:00
*** LISP: LISP Syntax so much parenthesis
2017-08-24 18:58:13 +00:00
It was intended to code use M-language in an Algol-like notation.
2017-12-07 15:44:09 +00:00
In practice LISPers wrote their code directly in S-expressions.
2017-08-24 18:58:13 +00:00
M-language became a kind of ghost... theoretically important but not used by anyone.
2017-12-07 15:44:09 +00:00
** History
*** 1960 → 1983
2017-12-27 23:32:14 +00:00
- Algol 60 (Naur et al 1963) -- /no I/O facilities/
- ISWIM (Landin 1966) -- /If you See What I Mean/
- PAL (Evans 1968) -- /Pedagogic Algorithmic Language/
- SASL (1973-83) -- /St Andrews Static Language/
2017-12-07 15:44:09 +00:00
*** Edinburgh (1969-80)
2017-12-27 23:32:14 +00:00
- NLP /strongly typed/ but no polymorphisms, call-by-value
- NLP evolved into HOPE: higher order, /strongly typed/ with explicit types and
/polymorphic type variables/, /purely functional/.
2017-08-24 18:58:13 +00:00
- ML (Meta-Language) emerged as the meta-language of Edinburgh LCF, programmable verification system
2017-12-27 23:32:14 +00:00
- Standard ML (Milner et al. 1990) /pattern matching/ and /type inference/ but *not pure*.
2017-08-24 18:58:13 +00:00
*** Miranda (1986)
2017-12-27 23:32:14 +00:00
- Milner type discipline:
#+BEGIN_SRC
tree * :: Leaf * | Node (tree *) (tree *)
#+END_SRC
2017-08-24 18:58:13 +00:00
- Use of =*=, =**=, =***=, ... syntax as type variables from original ML
*** Haskell (1992...)
Similar to Miranda but richer and more redundant syntax.
+ type classes
+ monadic IO
+ module system
* Major Principles (Theoretical)
** Higher-order functions
2017-12-07 15:44:09 +00:00
A function can take another function as parameter.
#+BEGIN_SRC haskell
map :: (a -> b) -> [a] -> [b]
map (+2) [1,2,3] -- ⇒ [3,4,5]
filter :: (a -> Bool) -> [a] -> [a]
filter (>2) [1,2,3] -- ⇒ [3]
#+END_SRC
2017-08-24 18:58:13 +00:00
** Purity
*** Function vs Procedure/Subroutines
2017-12-07 15:44:09 +00:00
- A Function is something that doesn't have any effect.
- A Procedure/subroutine is something that can interleave effects during
evaluation
*** Referential Transparency vs Referential Opacity
2017-08-24 18:58:13 +00:00
- Ability to copy/paste without changing result vs impossible
- Help the programmer but also the compiler!
- Help in proving correctness
- Help simplifying algorithms, better linters
2017-12-07 15:44:09 +00:00
- Optimizing by:
- memoization
- common subexpression elimination
- lazy evaluation
- parallelization
*** Extremely Easy to Parallelze
**** Evaluation strategies:
=(h (f a) (g b))= We can evaluate:
- =a= then =(f a)= then =b= then =(g b)= and finally =(h (f a) (g b))=
- =b= then =a= then =(g b)= then =(f a)= and finally =(h (f a) (g b))=
- =a= and =b= in parallel then =(f a)= and =(g b)= in parallel and finally
=(h (f a) (g b))=
- =h= and then evaluate =(f a)= only if needed and then =(g b)= only if needed...
2017-08-24 18:58:13 +00:00
That's called non-strict evaluation (sometime lazy evaluation)
For example if: =(def h (λx.λy.(+ x x)))= we don't need to evaluate =y=, in our case =(g b)=
2017-12-07 15:44:09 +00:00
2017-08-24 18:58:13 +00:00
**** Time is Hard, purity remove time from the paradigm
2017-12-07 15:44:09 +00:00
Calling the same function with the same parameter twice will always results in
the same value.
2017-08-24 18:58:13 +00:00
*** Effects?
**** Side effects in the language
2017-12-07 15:44:09 +00:00
The programmer must be careful not to use impure functions in place where only
pure functions are expected.
2017-08-24 18:58:13 +00:00
**** Split impurity using a flag (generaly a type)
- =foo : Int -> String= declared as pure
- =foo : Int -> IO String= declared as impure (IO)
*** Exceptions / Errors?
We can't avoid the fact real world has limits! Space limit, maybe time limit,
maybe access limitations...
** Tail Recursion
Recursion is heavily used in functional programming. Functional language will
often include *tail call optimisation* to ensure that heavy recursion does not
consume excessive memory.
** Functional Programming Style and Grey area Languages
Functional Style can be achieved in most languages. For example in Perl, PHP,
C++11, Java 8 and C# 3.0. all added features to facilitate the functional style.
Scala is special as it is frequently written in a functional style but the
presence of side effects and mutable state place it in a grey area.
*** A Hole in purity, and all great properties of functional programming fall appart
This is a major point. You cannot compromise with purity without losing
everything. Extremely well explained in the SICP when he introduce the =set!=
ability to *mutate* the value associated to a variable.
*** Grey Area Languages
**** XSLT
**** R, J, K and Q
**** SQL (declarative)
**** Lex/Yacc a bit
** Meta-Programming and Macros!
If you really want to have the next power level, you can write macros, or what
is mostly called meta-programming.
A notable thing to know about are LISP Macros.
** Type System
First, If when I say static typing you think C, C++, Java... No, that's NOT THAT AT ALL!
Type Theory is a vast mathematical field, with lot of hard and incredible work.
Some language don't need type system at all. Typically most LISP are very close to a raw lambda calculus.
But there is a problem with untyped languages: ⊥
Even we provided purity, you can imagine a system that help you reason about
your code even further by adding more meta informations.
Different type systems: Hindley Milner, Martin/Lof, HoTT
- Basic Types (same as in Java)
- Parametric Types ⇒ many different polymorphisms to choose
- ADT! ⇒ Algebraic Data Types (type with algebraic properties FTW!)
- GADT! ⇒ Generalized Algebraic Data Types
- Generic Programming (be able to understand that two data structure share the same underlying structure)
- Typeclasses ⇒ Incredible ability to abstraction (Monoids, Functor, Applicative, Monads, Traversables...)
* Major Languages (Practical)
- We only talk about General purpose languages (not domain specific languages)
- Prod ready or not is only regarding our current knowledge. And by prod ready
it won't be enough to name less than 5 company using it for small project.
- Prod ready mean used at 100% by a company earning money for some years, and
used partially (more than 10%) by more than 10 company or having a big
production project
** Not Pure
*** Can be used in modern production env
**** LISP Family
***** Common Lisp
***** Clojure (Generally pure as default data structure are pure)
**** Not LISP & General Purpose Languages
***** Erlang
***** Mathematica
***** OCaml
***** F#
*** Not suitable for production yet
**** LISP Family
***** Scheme
***** Racket
**** Not LISP, General Purpose Languages
***** Erlang
***** ML, Caml
** Pure
*** Prod ready
**** Haskell
**** Elm
2017-12-07 15:44:09 +00:00
**** Purescript
2017-08-24 18:58:13 +00:00
*** Not Prod ready yet
**** Idris
**** Frege
**** Eta (Haskell 7.10 on the JVM) might be used in production but really recent
**** Clean
2018-02-17 11:34:40 +00:00
* Practical Examples
** Bug 1 - Parallelization / pureté
- =map=
- =pmap=
** Bug 2 - Waiting icon
Waiting icon
** Bug 3 - Null Pointer Exception
No NPE with Maybe
** Helper - Non deterministic programming
- for (for (for .... ))) pyramid of hell
List monad