diff --git a/Notes.md b/Notes.md
index 3ea8333..de84ccc 100644
--- a/Notes.md
+++ b/Notes.md
@@ -52,19 +52,19 @@ html header: `
+ + `std::accumulate` from `numeric`: Wants binary operation, i.e. `std::minus`
diff --git a/examples/02_python.py b/examples/02_python.py
new file mode 100644
index 0000000..b4ec711
--- /dev/null
+++ b/examples/02_python.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+import sys
+
+
+def debug(func):
+ def inner(*args, **kwargs):
+ sys.stderr.write("F: {}, args: {}, kwargs: {}\n"
+ .format(func.__name__, args, kwargs))
+ return func(*args, **kwargs)
+ return inner
+
+
+@debug
+def foo(x):
+ pass
+
+
+def mybubblesort(array, func=lambda x, y: True if x > y else False):
+ if (len(array) == 0):
+ return []
+ else:
+ x, *xs = array
+ return mybubblesort([y for y in xs if func(x, y)], func) \
+ + [x] \
+ + mybubblesort([y for y in xs if not func(x, y)], func)
+
+if __name__ == "__main__":
+ foo(2)
+ a = [2,5,12,4,1,0]
+ print(mybubblesort(a))
+ print(mybubblesort(a, lambda x, y: True if x < y else False))
diff --git a/examples/03_cpp.cpp b/examples/03_cpp.cpp
new file mode 100644
index 0000000..b93537e
--- /dev/null
+++ b/examples/03_cpp.cpp
@@ -0,0 +1,50 @@
+#include
+#include
+#include
+#include
+
+int main() {
+ std::vector a{1,2,3,4};
+ std::vector b{5,6,7,8};
+ // result vector
+ std::vector c(a.size(), 0);
+
+ // double
+ std::for_each(a.begin(), a.end(), [](int &n){ n*=2;});
+
+ std::cout << "Double:" << std::endl;
+ for (auto const &i: a){ std::cout<());
+ int mult = std::accumulate(a.begin(), a.end(), 1,
+ [](int a, int b)->int { return a * b; });
+ std::cout << "Sum: " << sum
+ << "\nDiff from 15: " << diff
+ << "\nProd: " << mult
+ << std::endl;
+
+ return 0;
+}
diff --git a/examples/04_cpp17.cpp b/examples/04_cpp17.cpp
new file mode 100644
index 0000000..8852249
--- /dev/null
+++ b/examples/04_cpp17.cpp
@@ -0,0 +1,32 @@
+#include
+// compile using std=c++1z-option
+// tested with clang++ and g++
+// using:
+// $CC -Wall -Werror -pedantic -pedantic-errors -std=c++1z -o $OUT $IN
+
+/* "Old" code:
+ * The usage of auto to implicitly get the return type is C++17,
+ * the main part is using C++11 variadic templates and overloading
+ */
+auto sum1() { return 0;}
+
+template
+auto sum1(T t) { return t; }
+
+template
+auto sum1(T t, Ts... ts) {return t + sum1(ts...);}
+
+/* New code:
+ * Using c++17 fold expressions, this gets way shorter and
+ * less error prone
+ */
+template
+auto sum2 (T... args){
+ return (... + args);
+}
+
+int main() {
+ std::cout << sum1(1,2,3,4,5,6,7,8,9,10) << std::endl;
+ std::cout << sum2(1,2,3,4,5,6,7,8,9,10) << std::endl;
+ return 0;
+}
diff --git a/tex/headers/listings.tex b/tex/headers/listings.tex
index b0095f1..a1b3161 100644
--- a/tex/headers/listings.tex
+++ b/tex/headers/listings.tex
@@ -3,6 +3,8 @@
\usepackage{upquote}
\usepackage[section, cache=true,]{minted}
+\usemintedstyle{manni}
+
\newminted[ccode]{c}%
{
linenos=true,
@@ -58,5 +60,5 @@
%%% Local Variables:
%%% mode: latex
-%%% TeX-master: "../linux-script"
+%%% TeX-master: "../wtfunctional"
%%% End:
diff --git a/tex/wtf.bib b/tex/wtf.bib
index d79d91c..fa653c5 100644
--- a/tex/wtf.bib
+++ b/tex/wtf.bib
@@ -1,11 +1,29 @@
@online{whichfold,
-title={Foldr Foldl Foldl' - HaskellWiki},
-urldate={2016-04-21},
-url={https://wiki.haskell.org/Foldr_Foldl_Foldl%27},
+title = {Foldr Foldl Foldl' - HaskellWiki},
+url = {wiki.haskell.org/Foldr_Foldl_Foldl},
}
@online{decorators,
-title={simeonfranklin.com - Understanding Python Decorators in 12 Easy Steps!},
-urldate={2016-04-25},
-url={http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/},
+title = {simeonfranklin.com - Understanding Python Decorators in 12 Easy Steps!},
+url = {simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/},
+}
+
+@Online{cppiter,
+title = {C++ concepts: Iterator - cppreference.com},
+url = {en.cppreference.com/w/cpp/concept/Iterator},
+}
+
+@online{generics,
+title = {Index of /~kami/2015-32C3/},
+url = {people.freebsd.org/~kami/2015-32C3/},
+}
+
+@online{cpp17,
+title = {C++17 content prediction (pre-Jacksonville and post-Kona report) – Michael Wong's Standard},
+url = {https://wongmichael.com/2016/02/28/c17-content-predictionpre-jacksonville-and-post-kona-report/},
+}
+
+@online{cppfolds,
+title = {Fold expressions},
+url = {www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4191.html},
}
\ No newline at end of file
diff --git a/tex/wtfunctional.tex b/tex/wtfunctional.tex
index 27c9618..621b338 100644
--- a/tex/wtfunctional.tex
+++ b/tex/wtfunctional.tex
@@ -5,15 +5,17 @@
\usepackage{tabularx}
\usepackage[backend=biber,]{biblatex}
\bibliography{wtf}
+\renewcommand{\bibfont}{\small}
\usepackage{fontspec}
\setsansfont{Fira Sans}
\setmonofont{Inconsolata-g}
\usetheme{Antibes}
-%\usecolortheme{beaver}
\setbeamercovered{transparent}
+\newcommand{\cpp}{\texttt{C++}}
+
\title{WTFunctional}
\author{Oliver Rümpelein}
\subtitle{Using functional structures in non-functional languages}
@@ -23,6 +25,17 @@
\begin{document}
\frame{\titlepage}
+\begin{frame}[plain]{What?}
+ \begin{enumerate}[<+->]
+ \item Dafunc? Introduction to functional paradigms using Haskell
+ \item PhuncY! Functional programming in Python
+ \item Fun\cpp{}tional: STL-hacks and usage in \cpp
+ \end{enumerate}
+ \begin{uncoverenv}<4-| invisible@1-3>
+ \emph{With preview to \cpp{}17/20/22!}
+ \end{uncoverenv}
+\end{frame}
+
\section{Dafunc?}
\subsection{Functional programming}
\begin{frame}{Understanding functional paradigms}
@@ -169,7 +182,7 @@ c = addto b 4
\end{frame}
\begin{frame}[fragile]{Folds (2)}
- \uncover<+-> Example: Self written Right fold and sum:
+ \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)
@@ -185,9 +198,9 @@ g = msum [1..100]
Get all Pythagorean triangles with a hypotenuse off length at most 15:
\begin{haskell}
> [(a,b,c) | a <- [1..15],
-b <- [1..a],
-c <- [1..b],
-a^2 == b^2 + c^2]
+ 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}
@@ -197,8 +210,8 @@ a^2 == b^2 + c^2]
\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) ]
+ 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:
@@ -209,7 +222,7 @@ mbsort = bsort (\x y -> (x > y))
\end{haskell}
\end{frame}
-\section{Phuncy!}
+\section{PhuncY!}
\subsection{Overview}
\begin{frame}{Functional programming in Python}
\begin{itemize}[<+->]
@@ -222,6 +235,7 @@ mbsort = bsort (\x y -> (x > y))
\end{itemize}
\end{frame}
+\subsection{Elements}
\begin{frame}[fragile]{Lambdas, Maps}
\begin{itemize}[<+->]
\item Lambda-syntax: \pycmd{lambda a,b: a+b}
@@ -286,27 +300,233 @@ bar(3) # 5
\end{itemize}
\end{frame}
-\begin{frame}[fragile]{Decorators}
+\begin{frame}{Decorators (1)}
\begin{itemize}[<+->]
\item Often used to modify functions in Frameworks
- \item Encapsulates other functions. More infos at \cite{decorators}
+ \item Basic pattern: Decorator is a function that itself takes a function,
+ and returns a wrapper
+ \item Step-by-step introduction to decorators at~\cite{decorators}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Decorators (2)}
\begin{pycode}
def debug(func):
def inner(*args, **kwargs):
- sys.stderr.write("F: {}, args: {}, kwargs {}".format(func.__name__, args,
- kwargs))
- return func(*args, **args)
+ print("F: {}, args: {}, kwargs: {}\n"
+ .format(func.__name__, args, kwargs))
+ return func(*args, **kwargs)
return inner
+
@debug
def foo(x):
- print(x)
+ pass
+
+foo(2) # => F: foo, args: (2), kwargs: {}
\end{pycode}
+\end{frame}
+
+\subsection{Conclusion}
+\begin{frame}{Quite enough…}
+ \begin{itemize}[<+->]
+ \item Python is not really functional…
+ \item …but is strongly influenced by functional paradigms.
+ \item Its functional parts are heavily used, i.e in Genomics
\end{itemize}
\end{frame}
+\begin{frame}[fragile]{Example}
+\begin{pycode}
+def mybubblesort(array,
+ func=lambda x, y: True if x > y else False):
+ if (len(array) == 0):
+ return []
+ else:
+ x, *xs = array
+ return mybubblesort([y for y in xs
+ if func(x,y)], func) \
+ + [x] \
+ + mybubblesort([y for y in xs \
+ if not func(x,y)], func)
+\end{pycode}
+\end{frame}
+
+\section{Fun\cpp{}ional}
+\subsection{Overview}
+
+\begin{frame}{Functional programming in \cpp{}}
+ \begin{itemize}[<+->]
+ \item \enquote{Classical} \cpp{} has a few functional elements…
+ \item …but lacks lambdas, for instance.
+ \item This changed with the modern standards, starting from \cpp{}11.
+ \end{itemize}
+\end{frame}
+
+
+\subsection{Elements}
+\begin{frame}[fragile]{Lists}
+ \begin{itemize}[<+->]
+ \item In \cpp{}, \emph{Iterators} are equivalent to lists in functional languages.
+ \item Examples of iterators include \cppcmd{vector} and \cppcmd{array}.
+ \item See~\cite{cppiter} for more information about the specific iterator
+ types and the prerequisites they bring.
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{lambdas}
+ \begin{itemize}[<+->]
+ \item \emph{Lambdas} have been introduced with \cpp{}11
+ \item Syntax:
+\begin{cppcode}
+[v1,&v2](int v1, int v2)
+ {return v1 < v2}
+\end{cppcode}
+ \item The \cppcmd{[]} denotes the capture-list and specifies, whether
+ variables are used by value or by reference. If this is empty,
+ anything is used by value.
+ \item Lambdas are fully-featured \emph{functionals}, such are functions
+ wrapped with \cppcmd{std::function}, and objects implementing
+ \cppcmd{operator()}.
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Maps (1)}
+ \uncover<+->{\begin{alertblock}{map ≠ map}
+ \cppcmd{std::map} is a data-type similar to pythons \pycmd{dict} and has no
+ relation to the functional concept of maps!
+ \end{alertblock}}
+ \uncover<+->{The following can be used instead (both from \cppcmd{}):}
+ \begin{itemize}[<+->]
+ \item \cppcmd{std::for_each}
+ \item \cppcmd{std::transform}
+ \end{itemize}
+\uncover<+->{But they are quite different.}
+\end{frame}
+
+\begin{frame}[fragile]{Maps (2)}
+ \uncover<+->{\cppcmd{std::for_each} applies a function \cppcmd{void fun(T &a)} to elements
+ of an iterator containing values of type \cppcmd{T} in place:}
+
+ \begin{uncoverenv}<+->
+\begin{cppcode}
+vector a{1,2,3};
+for_each(a.begin(), a.end(),
+ [](int &n){ n*=2; });
+\end{cppcode}
+ \end{uncoverenv}
+
+ \uncover<+->{This multiplies each element in \cppcmd{a} by 2.}
+\end{frame}
+
+\begin{frame}[fragile]{Maps (3)}
+ \uncover<+->{In contrast, \cppcmd{std::transform} returns a new iterator containing type
+\cppcmd{U}. Thus, the function has to be \cppcmd{U func(T val)}:}
+
+\begin{uncoverenv}<+->
+\begin{cppcode}
+vector b{1,2,3,4};
+vector c(b.size(), 0.0);
+transform(b.begin(), b.end(), c.begin(),
+ [](int i){ return 1.0/i; });
+\end{cppcode}
+\end{uncoverenv}
+
+\uncover<+->{This gives a vector c filled with the inverse elements of b.}
+\uncover<+->{There are also forms of \cppcmd{transform} that merge two
+ iterators (see examples in git-repo).}
+\end{frame}
+
+\begin{frame}[fragile]{Filters}
+ \begin{itemize}[<+->]
+ \item This is ugly
+ \item No syntactic sugar as with python's list comprehensions
+ \item Use \cppcmd{std::remove_if} or \cppcmd{std::remove_copy_if} from \cppcmd{},
+ \item afterwards \cppcmd{transform}.
+ \item Or make use of the \cppcmd{boost::filter_iterator} library.
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Folds}
+ \begin{itemize}[<+->]
+ \item \cppcmd{std::accumulate} is defined in \cppcmd{}
+ \item Takes bounds of an Iterator, and a \cppcmd{BinaryOperation}
+ \item Example:
+\begin{cppcode}
+vector a{1,2,3,4}
+int b = accumulate(a.begin(), a.end(), 0); // sum
+int c = accumulate(a.begin(), a.end(), 15, minus());
+\end{cppcode}
+ \cppcmd{std::minus} is defined in \cppcmd{} as well.
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Generics and \texttt{D}}
+\begin{itemize}[<+->]
+ \item These are only procedural examples of functional programming.
+ \item Much can be done using \emph{generic} techniques
+ (\enquote{templates}).
+ \item Many examples: \cite{generics}
+ \item Much more to come in \cpp{}20/22 (\cite[What will Not make it into
+ C+17,…]{cpp17})
+ \begin{itemize}[<+->]
+ \item \emph{Concepts} are kind of constraints on template parameters.
+ \item \emph{Ranges} will replace iterators
+ \item All of the above and more are available in the \texttt{D}
+ programming language! (\url{dlang.org})
+ \end{itemize}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]{Generics example: Folds}
+ \begin{uncoverenv}<+->
+ Using \cpp{}11 with variadic templates, one has (mod \cppcmd{auto})
+\begin{cppcode}
+auto sum() { return 0; }
+
+template
+auto sum(T t) { return t; }
+
+template
+auto sum(T t, Ts... ts) { return t + sum(ts...); }
+\end{cppcode}
+ \end{uncoverenv}
+ \begin{uncoverenv}<+->
+ With new folding expression (\cite{cppfolds}):
+\begin{cppcode}
+template
+auto sum(const auto&... args)
+ { return (args + ...); }
+\end{cppcode}
+ \end{uncoverenv}
+\end{frame}
+
\begin{frame}[plain]{References}
\printbibliography
\end{frame}
+
+\section{The}
+\subsection{end}
+
+\begin{frame}[plain]{Thanks for listening!}{Any questions?}
+ \href{https://git.f3l.de/pheerai/wtfunctional/}{Git-Repo with examples and
+ slides}: \url{git.f3l.de/pheerai/wtfunctional/}
+
+ \begin{description}
+ \item[Mail:] \url{oli_r@fg4f.de}
+ \item[XMPP:] \url{pheerai@im.f3l.de}
+ \item[Github:] \href{https://github.com/pheerai/}{pheerai}
+ \item[Misc:] Signal, Telegram,…
+ \item[…or] later having some drink
+ \end{description}
+ \vfill
+ \tiny \raggedleft Proudly typed using Lua\LaTeX{}. Slides-theme: \emph{Antibes}\\
+ Fonts used are \href{github.com/mozilla/Fira}{\emph{Fira Sans}} and
+ \href{leonardo-m.livejournal.com/77079.html}{\emph{Inconsolata G}}.\\
+ Syntax and code highlighting with
+ \href{https://github.com/gpoore/minted}{\emph{minted}} and
+ \href{http://pygments.org}{\emph{pygments}}.
+\end{frame}
+
\end{document}
%%% Local Variables: