wtfunctional/tex/wtfunctional.tex

315 lines
8.9 KiB
TeX
Raw Normal View History

\documentclass[english]{beamer}
\usepackage{babel}
\usepackage{csquotes}
\usepackage{tabularx}
2016-04-25 16:20:31 +02:00
\usepackage[backend=biber,]{biblatex}
\bibliography{wtf}
\usepackage{fontspec}
\setsansfont{Fira Sans}
\setmonofont{Inconsolata-g}
\usetheme{Antibes}
%\usecolortheme{beaver}
\setbeamercovered{transparent}
\title{WTFunctional}
\author{Oliver Rümpelein}
\subtitle{Using functional structures in non-functional languages}
\input{headers/listings}
\begin{document}
\frame{\titlepage}
\section{Dafunc?}
\subsection{Functional programming}
\begin{frame}{Understanding functional paradigms}
Here: so called \enquote{purely functional} paradigm.
\begin{itemize}
\item<+-> Programming without \enquote{side-effects}
\begin{itemize}
\item<+-> No mutability
\item<+-> Functions work only in local context
\end{itemize}
\item<+-> Extensive use of lists and so called maps/reduces (later)
\item<+-> Do not mix up with \enquote{procedural} programming (using only functions)!
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Example}
2016-04-25 16:20:31 +02:00
% ToDo: C-code call by value, call by reference.
\begin{cppcode}
int f(int x) { return ++x;}
int g(int& x) { return ++x;}
int main() {
int x = 2;
f(x);
assert(x==2); // f is “functional”
g(x);
assert(x!=2); // g is not!
}
\end{cppcode}
\end{frame}
\begin{frame}{Pros and Cons}
Pros:
\begin{itemize}[<+->]
\item Maintainability
\item Testing
\item (often) shorter code
\end{itemize}
Cons:
\begin{itemize}[<+->]
\item harder to learn
\item harder to understand
\item slower due to abstraction
\end{itemize}
\end{frame}
\subsection{Case study: Haskell}
\begin{frame}{Overview}
\begin{itemize}[<+->]
\item \emph{Haskell} is a purely functional, compiled programming language
developed since 1990.
\item It is typed and has a strong meta-type system (comparable to
interfaces in OOP)
\item The most important implementation is \emph{GHC} (Glasgow Haskell
Compiler)
\item Haskell is lazy. Statements get evaluated only when needed, if ever.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Syntax Functions}
Function constraints, definition and calls:
2016-04-25 16:20:31 +02:00
\begin{haskell}
mysum :: Num a => a -> a -> a -> a
mysum x y z = x + y + z
-- b == 6
b = mysum 1 2 3
\end{haskell}
\pause
Functions always get evaluated left to right, thus the following works (\emph{Currying}):
2016-04-25 16:20:31 +02:00
\begin{haskell}
mysum2 = mysum 2
-- c == 12
c = mysum2 4 6
\end{haskell}
\end{frame}
\begin{frame}[fragile]{Syntax Lists (1)}
\begin{itemize}[<+->]
\item Lists in Haskell can only hold data of one type. They are defined using
\haskellcmd{a = [1,2,3,4]} or similar.
\item An automatic range can be obtained by using \haskellcmd{b = [1..4]},
where the last number is inclusive.
\item If possible, Haskell will try to inhibit the step
automatically. \haskellcmd{c = [1,3..7]} yields
\haskellcmd{[1,3,5,7]}.
\item When leaving out the end specifier, a range can be infinite. In this case,
it's up to the programmer to constrain things.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Syntax Lists (2)}
\begin{itemize}[<+->]
\item Two lists can be concatenated using the \haskellcmd{++} operator:
\haskellcmd{[1,2,3] ++ [4..7]}
\item Single objects get pushed to the front using
2016-04-25 16:20:31 +02:00
\enquote{\haskellcmd{:}}: \haskellcmd{1:[2..7]}.
\item This can also be used vice versa to extract single values from lists:
2016-04-25 16:20:31 +02:00
\begin{haskell}
extract (x:xs) = x
-- a = 1
a = extract [1..5]
\end{haskell}
\end{itemize}
\end{frame}
2016-04-25 16:20:31 +02:00
\begin{frame}[fragile]{Syntax Recursion}
Example: Add a value to every entry in an array
2016-04-25 16:20:31 +02:00
\begin{haskell}
addto :: (Num a) => [a] -> a -> [a]
addto [] _ = [] -- edge case (list empty)
addto (x:xs) y = (x+y) : addto xs y
b = [1..4]
-- c == [5,6,7,8]
c = addto b 4
\end{haskell}
\end{frame}
\begin{frame}[fragile]{Lambdas}
\begin{itemize}[<+->]
\item By now: lambda-functions well known from other programming languages
\item Represent \enquote{anonymous} functions, i.e. locally defined functions
without associated name
\item Can simply be passed to algorithms, i.e. sort.
\item Syntax: \haskellcmd{\var1 var2 -> retval}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Maps, Filters}
\begin{itemize}[<+->]
\item A \emph{Map} applies a function to all elements of a list:
\haskellcmd{map (^2) c}\quad (square the elements of c)
\item A \emph{Filter} does exactly that to a list:
\haskellcmd{filter (\x -> (mod x 2) == 0) c} \quad (even numbers in c,
filtering done using a lambda function)
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Folds (1)}
\begin{itemize}[<+->]
\item \emph{Folds} (or sometimes \emph{reductions}) create single values
using whole lists, i.e. sums over all elements
\item Often implemented using recursion
\item Need a function, an initialization value and a list
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Folds (2)}
2016-04-25 16:20:31 +02:00
\uncover<+-> Example: Self written Right fold and sum:
\begin{haskell}
mfold f z [] = z
mfold f z (x:xs) = f x (mfold f z xs)
msum = mfold (+) 0
-- g == 5050
g = msum [1..100]
\end{haskell}
\uncover<+->{Note that this gets pretty resource hungry with large
lists, better use left-folds for this (see~\cite{whichfold})}
\end{frame}
\begin{frame}[fragile]{Example: Pythagorean triangles}
Get all Pythagorean triangles with a hypotenuse off length at most 15:
2016-04-25 16:20:31 +02:00
\begin{haskell}
> [(a,b,c) | a <- [1..15],
b <- [1..a],
c <- [1..b],
a^2 == b^2 + c^2]
[(5,4,3),(10,8,6),(13,12,5),(15,12,9)]
\end{haskell}
\end{frame}
\begin{frame}[fragile]{Example: Bubble-sort}
Recursive, functional bubble-sort algorithm:
2016-04-25 16:20:31 +02:00
\begin{haskell}
bsort f [] = []
bsort f (x:xs) = (bsort f a) ++ [x] ++ (bsort f b)
where a = [ y | y <- xs, not (f x y) ]
b = [ y | y <- xs, (f x y) ]
mbsort = bsort (\x y -> (x > y))
\end{haskell}
\pause Result:
2016-04-25 16:20:31 +02:00
\begin{haskell}
λ> h = [1, 20, -10, 5]
λ> mbsort h
[-10,1,5,29]
\end{haskell}
\end{frame}
\section{Phuncy!}
\subsection{Overview}
\begin{frame}{Functional programming in Python}
\begin{itemize}[<+->]
\item Obviously, python is not strictly functional…
\item …but has functions as first class objects!
\item Some other stuff is widely used, but with another syntax…
\item …, although there are ways to get the \enquote{real} functional
style.
\item I use python3 here, python2 differs in some points.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Lambdas, Maps}
\begin{itemize}[<+->]
\item Lambda-syntax: \pycmd{lambda a,b: a+b}
\item Maps are done by \pycmd{map}
\item \emph{Note:} Most functional list-functions return iterators in
python, not lists!
\item Use \pycmd{list()} to cast Iterators, but this is usually not
necessary.
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Filters}
\begin{itemize}[<+->]
\item Can be done using \pycmd{filter(func, iter)}:
\begin{pycode}
a = range(1,7)
b = filter(lambda x: x%2, a)
print(list(b))
# [1,3,5]
\end{pycode}
\item Alternatively, use List Comprehension:
\begin{pycode}
a = range(1,7)
b = [x for x in a if x%2]
print(b)
\end{pycode}
\item Pro: Maybe easier readable, returns list
\item Con: Returns list (slower when iterating afterwards)
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Fold}
\begin{itemize}[<+->]
\item From the python2 to python3 Changelog:
\begin{quote}
Removed `reduce()`. Use `functools.reduce()` if you really need it;
however, 99 percent of the time an explicit `for` loop is more
readable.
\end{quote}
\item I disagree Old-style is more explicit and still available from \pycmd{functools}
\item Example sum of squares
\begin{pycode}
from functools import reduce
a = range(10)
mapped = map(lambda x: x**2, a)
reduced = reduce(lambda x,y: x+y, mapped)
\end{pycode}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Currying}
\begin{itemize}[<+->]
\item No real currying, but several workarounds
\item Lambdas: \pycmd{g=lambda x: foo(2,x)}
\item \pycmd{functools.partial}:
\begin{pycode}
def foo(x,y):
return x+y
bar=partial(foo, 2)
bar(3) # 5
\end{pycode}
\end{itemize}
\end{frame}
\begin{frame}[fragile]{Decorators}
\begin{itemize}[<+->]
\item Often used to modify functions in Frameworks
\item Encapsulates other functions. More infos at \cite{decorators}
\begin{pycode}
def debug(func):
def inner(*args, **kwargs):
sys.stderr.write("F: {}, args: {}, kwargs {}".format(func.__name__, args,
kwargs))
return func(*args, **args)
return inner
@debug
def foo(x):
print(x)
\end{pycode}
\end{itemize}
\end{frame}
\begin{frame}[plain]{References}
\printbibliography
2016-04-25 16:20:31 +02:00
\end{frame}
\end{document}
%%% Local Variables:
%%% mode: latex
2016-04-25 16:20:31 +02:00
%%% ispell-local-dictionary: "en_GB"
%%% End: