434 lines
14 KiB
TeX
434 lines
14 KiB
TeX
\documentclass[10pt,a5paper,mathserif,serif,usenames,dvipsnames]{beamer}
|
|
|
|
% packages
|
|
\usepackage{xcolor}
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage{amsmath}
|
|
\usepackage{amsfonts}
|
|
\usepackage{amssymb}
|
|
\usepackage{graphicx}
|
|
\usepackage{listings}
|
|
|
|
% package configuration
|
|
\DeclareGraphicsExtensions{.pdf,.png,.jpg}
|
|
\beamertemplatenavigationsymbolsempty
|
|
|
|
% title page information
|
|
\author{Julian Ospald}
|
|
|
|
\institute{FH Bielefeld}
|
|
\title{Haskell: introduction}
|
|
|
|
% color definition
|
|
\definecolor{solarized}{HTML}{002B36}
|
|
\definecolor{mygreen}{rgb}{0,0.6,0}
|
|
|
|
% macros and environments
|
|
\newcommand{\code}[1]{\texttt{#1}}
|
|
\newcommand{\setHaskellCodeStyle}{
|
|
\lstset{
|
|
language=Haskell,
|
|
backgroundcolor=\color{lightgray},
|
|
commentstyle=\color{mygreen},
|
|
keywordstyle=\color{blue},
|
|
frame=single,
|
|
keepspaces=true
|
|
}
|
|
}
|
|
\newcommand{\setCCodeStyle}{
|
|
\lstset{
|
|
language=C,
|
|
backgroundcolor=\color{lightgray},
|
|
commentstyle=\color{mygreen},
|
|
keywordstyle=\color{blue},
|
|
frame=single,
|
|
keepspaces=true
|
|
}
|
|
}
|
|
\newcommand{\setCppCodeStyle}{
|
|
\lstset{
|
|
language=C++,
|
|
backgroundcolor=\color{lightgray},
|
|
commentstyle=\color{mygreen},
|
|
keywordstyle=\color{blue},
|
|
frame=single,
|
|
keepspaces=true
|
|
}
|
|
}
|
|
|
|
\begin{document}
|
|
|
|
% redefinition of author, fails before document env
|
|
\author{
|
|
\begin{tabular}{r@{ }l}
|
|
Author: & Julian Ospald \\[1ex]
|
|
Parts stolen from: & Brent Yorgey\\
|
|
& (link at the end of the document)
|
|
\end{tabular}
|
|
}
|
|
|
|
\frame{\titlepage}
|
|
|
|
\begin{frame}
|
|
\frametitle{Why haskell?}
|
|
A Haskeller might claim: haskell...
|
|
\begin{itemize}[<+->]
|
|
\item eliminates certain classes of bugs
|
|
\item makes it easy to reason about code
|
|
\item decreases the bus-factor
|
|
\item makes it possible to apply huge changes to large programs without worrying about the implicit state machine
|
|
\item makes it easier to program complex problems
|
|
\item allows for clean APIs, even without any OOP
|
|
\item a haskell program of 10K LOC isn't that much different to maintain as a 100K LOC
|
|
\end{itemize}
|
|
\vspace{\baselineskip}
|
|
\onslide<+->
|
|
We'll have to see if this holds true.
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Why haskell? (ctn.)}
|
|
From C++ std:
|
|
\setCppCodeStyle
|
|
\begin{lstlisting}
|
|
void pop();
|
|
\end{lstlisting}
|
|
\setCCodeStyle
|
|
\onslide<+->
|
|
From the C FLINT library:
|
|
\begin{lstlisting}
|
|
void fmpz_mod_poly_add(
|
|
fmpz_mod_poly_t res,
|
|
const fmpz_mod_poly_t poly1,
|
|
const fmpz_mod_poly_t poly2);
|
|
\end{lstlisting}
|
|
\vspace{\baselineskip}
|
|
\onslide<+->
|
|
Regular C functions in real-world (omitting examples on purpose):
|
|
\begin{itemize}[<+->]
|
|
\item 100+ LOC
|
|
\item at least 7 ifs, 4 whiles, 12 variables, 1 goto
|
|
\item accesses both static and global variables
|
|
\item indenting level of 5 or more
|
|
\item a lot of memory management and custom-made error handling
|
|
\item references everywhere!
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Why haskell? (ctn.)}
|
|
You need to change only one single line in such a C function. You have to know:
|
|
\begin{itemize}[<+->]
|
|
\item does the order of function calls matter?
|
|
\item how does the change effect the memory management? Do we have memory leaks? Do we access invalid memory?
|
|
\item does it change the state of static or global variables?
|
|
\item does it implicitly change the state of out-parameters?
|
|
\item if it changes any of those states, is the function still correct?
|
|
\item what happens if the program flow reaches this codepath with variable X in that particular state, while variable Z is NULL, and...
|
|
\item did you just nuke a small former Soviet state?
|
|
\end{itemize}
|
|
\vspace{\baselineskip}
|
|
\onslide<+->
|
|
Conclusion: you really need to understand the complete environment of that line/function.
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Why haskell? (ctn.)}
|
|
But java helps! Does it?
|
|
Sort of, because:
|
|
\begin{itemize}[<+->]
|
|
\item it improves APIs compared to C, since you can hide or encapsulate information in the state of an object
|
|
\item it has a garbage collector, so you don't need to worry too much about memory
|
|
\end{itemize}
|
|
\onslide<+->
|
|
Unfortunately, we:
|
|
\begin{itemize}[<+->]
|
|
\item now got even more states to keep track of (intellectual complexity?)
|
|
\item have clouded the program flow... it's now about object-interaction with their explicit and implicit states
|
|
\item still have \textbf{side effects} everywhere: one object changes the state of another and vice versa, may arbitrarily write to the hard drive, do kernel calls or launch a missle
|
|
\end{itemize}
|
|
\onslide<+->
|
|
Some parts of the implicit state machine have been made explicit by modelling classes, but it's still there and we have to deal with it, because we are modelling everything around states. Wouldn't it be nice if we could just forget about the global state machine? Maybe there is even a way to remove side effects and have more "predictability"?
|
|
\onslide<+->
|
|
We are lucky. There is. It's called \textbf{Haskell}.
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{What is haskell?}
|
|
Haskell is a \textbf{functional}, \textbf{pure}, \textbf{lazy} and \textbf{statically typed} high-level programming language.\\
|
|
\onslide<+->
|
|
\vspace{\baselineskip}
|
|
A few of the following facts will be white lies. But let's not worry about that. It's maybe more about "how to think in terms of haskell?" than "what is haskell?".
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{What does \textbf{functional} mean?}
|
|
Think of haskell functions as regular \emph{mathematical} functions.
|
|
\onslide<+->
|
|
\vspace{\baselineskip}
|
|
\includegraphics*[scale=0.4]{function-machine.png}
|
|
\begin{itemize}[<+->]
|
|
\item does this function write to the hard drive?
|
|
\item does the output depend on anything else except the input (e.g. time, environment, ...)?
|
|
\end{itemize}
|
|
\onslide<+->
|
|
\vspace{\baselineskip}
|
|
It's all about \emph{input} and \emph{ouput} of functions! And that's it. Nothing else to worry about.
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{What does \textbf{functional} mean? (ctn.)}
|
|
\begin{itemize}[<+->]
|
|
\item \emph{first-class} citizens: functions are values and can be used as such
|
|
\item a haskell program is what happens when \emph{expressions are evaluated}, it's not about executing instructions
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{What does \textbf{pure} mean?}
|
|
\emph{Referential transparency}, as in:
|
|
\onslide<+->
|
|
\begin{itemize}[<+->]
|
|
\item everything (variables, data structures...) is \emph{immutable}
|
|
\item expressions never have side-effects (remember: mathematical functions)
|
|
\item same input $\mapsto$ same output... \emph{always}!
|
|
\item replace a function with it's (return) value? Yes. (what happens in C or java if you do that?)
|
|
\end{itemize}
|
|
\onslide<+->
|
|
\vspace{\baselineskip}
|
|
possible benefits?
|
|
\begin{itemize}[<+->]
|
|
\item parallelism
|
|
\item equational reasoning and refactoring
|
|
\item less bugs!
|
|
\end{itemize}
|
|
\onslide<+->
|
|
\vspace{\baselineskip}
|
|
Question: call-by-value? call-by-reference? call-by-need?
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{What does \textbf{lazy} mean?}
|
|
In haskell expressions are not evaluated until their results are actually needed. That has a lot of consequences, a few of them being:
|
|
\onslide<+->
|
|
\begin{itemize}[<+->]
|
|
\item infinite data structures are now possible (recursive and non-recursive)
|
|
\item defining new control structures by just defining a function (since not everything is evaluated... who needs if-then-else anyway?)
|
|
\item important for compositional programming and efficiency
|
|
\item laziness causes (memory) overhead, but most of the time the benefits outweigh the costs
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{What does \textbf{statically typed} mean?}
|
|
Every haskell expression has a type and types are always checked at \emph{compile-time}. Programs with errors will not compile and definitely not run.\\
|
|
\vspace{\baselineskip}
|
|
It is possible to simulate dynamic types however. In the end, they are still statically type-checked (as in: the compiler always knows what's going on).
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{What is haskell again?}
|
|
Let's reiterate. Haskell is:
|
|
\begin{itemize}
|
|
\item functional
|
|
\item pure
|
|
\item lazy
|
|
\item statically typed (and truly typesafe)
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Types, types, types}
|
|
\begin{itemize}
|
|
\item think in types!
|
|
\item don't be afraid of type errors
|
|
\item let the type-checker do the work for you (does this function do what I think it does?)
|
|
\item understand functions just by looking at their type signature?
|
|
\end{itemize}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Declarations}
|
|
Let's go!
|
|
\setHaskellCodeStyle
|
|
\begin{lstlisting}
|
|
x :: Int
|
|
x = 3
|
|
|
|
-- how about this?
|
|
x = 5
|
|
|
|
-- Int vs Integer
|
|
n :: Integer
|
|
n = 12345678909876543219873409823349873498723498
|
|
|
|
d :: Double
|
|
d = 5.0
|
|
|
|
c :: Char
|
|
c = 'k'
|
|
|
|
s :: String
|
|
s = "Hello, world?"
|
|
\end{lstlisting}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Arithmetic and co.}
|
|
\setHaskellCodeStyle
|
|
GHCi:
|
|
\begin{lstlisting}
|
|
> 3 + 5
|
|
> (3 :: Integer) + (5 :: Int)
|
|
> 6 * 5.0
|
|
> "Hello" ++ " world"
|
|
> "Haskell" > "C++"
|
|
> True && False
|
|
\end{lstlisting}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Functions and control structures}
|
|
\setHaskellCodeStyle
|
|
Let's make our first function. We want something like the following mathematical function\\
|
|
$f(x) = x * x$\\
|
|
\vspace{\baselineskip}
|
|
How could the haskell code look like?
|
|
\pause
|
|
Almost the same:
|
|
\begin{lstlisting}
|
|
f x = x * x
|
|
\end{lstlisting}
|
|
\vspace{\baselineskip}
|
|
GHCi...\\
|
|
\pause
|
|
\vspace{\baselineskip}
|
|
What is a possible type signature for this function?
|
|
\begin{lstlisting}
|
|
f :: Int -> Int
|
|
f x = x * x
|
|
\end{lstlisting}
|
|
So the function gets an Int and returns an Int. Don't get confused by "\verb|->|". Just think of it as a symbol for separating input and output.
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Functions and control structures (ctn.)}
|
|
In haskell we often use \textbf{pattern matching}. That means we define a function multiple times, but e.g. for different values of its input parameters. Let's see:
|
|
\pause
|
|
\setHaskellCodeStyle
|
|
\vspace{\baselineskip}
|
|
\begin{lstlisting}
|
|
isZero :: Int -> Bool
|
|
isZero 0 = True
|
|
isZero x = False
|
|
\end{lstlisting}
|
|
\vspace{\baselineskip}
|
|
So if we pass it 0, we get True. If we do not pass 0, we get False and the value we passed gets basically ignored.\\
|
|
\vspace{\baselineskip}
|
|
What might happen if we remove the second or the third line? What is a \textbf{partial function} and a \textbf{total function}?
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Functions and control structures (ctn.)}
|
|
How about \emph{recursion}? Let's define the modulo of any \emph{Int} to \emph{2}.
|
|
\pause
|
|
\setHaskellCodeStyle
|
|
\vspace{\baselineskip}
|
|
\begin{lstlisting}
|
|
mod2 :: Int -> Int
|
|
mod2 x
|
|
| x - 2 == 0 = 0
|
|
| x - 2 < 0 = x
|
|
| otherwise = mod2 (x - 2)
|
|
\end{lstlisting}
|
|
These \verb#|# things above are called \textbf{guards} and are similar to \emph{pattern matching}. They are processed in order. If the condition on the left side of the equation is true, then it returns what stands on the right side of the equation. If it's false, then it processes the next line.\\ \emph{"otherwise"} on the last line is just defined as \emph{True}, to make these constructs reasier to read and catch all other cases of input.
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Pairs/Tuples}
|
|
Defining a pair is easy.
|
|
\setHaskellCodeStyle
|
|
\begin{lstlisting}
|
|
p :: (Int, Char) -- this is the type
|
|
p = (2, 'y') -- this is how we construct the pair
|
|
|
|
-- pattern matching against pairs
|
|
sumPair :: (Int, Int) -> Int
|
|
sumPair (x, y) = x + y
|
|
\end{lstlisting}
|
|
\pause
|
|
Note: we use \code{(x, y)} notation for both the type and the definition! Those are still two different things. We can also have triples, quadruples etc.
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Lists}
|
|
\setHaskellCodeStyle
|
|
The list is probably the most basic data structure in Haskell. Like the array in C. It is a singly-linked list and is very lazy. The compiler has numerous ways to optimize lists, so don't be afraid to use them, even for huge things.
|
|
\pause
|
|
We build lists by using either the \code{[]} notation:
|
|
\begin{lstlisting}
|
|
list1 :: [Integer]
|
|
list1 = [1, 2]
|
|
\end{lstlisting}
|
|
\pause
|
|
or by using the \emph{cons} operator \code{(:)} which takes an element and a list and produces a new list with the element prepended to the front.
|
|
\begin{lstlisting}
|
|
list2 = 1 : []
|
|
|
|
-- is this really a list?
|
|
list3 = [1, 2] == 1 : 2 : []
|
|
|
|
emptyList = []
|
|
\end{lstlisting}
|
|
\pause
|
|
How about something more interesting:
|
|
\begin{lstlisting}
|
|
infiniteList = [1..]
|
|
\end{lstlisting}
|
|
\end{frame}
|
|
|
|
\begin{frame}[fragile]
|
|
\frametitle{Lists (ctn.)}
|
|
Again, we can do pattern matching on lists.
|
|
\setHaskellCodeStyle
|
|
\begin{lstlisting}
|
|
listLen :: [Integer] -> Integer
|
|
listLen [] = 0
|
|
listLen (x:xs) = 1 + listLen xs
|
|
\end{lstlisting}
|
|
We can also nest pattern matching:
|
|
\begin{lstlisting}
|
|
sumEveryTwo :: [Integer] -> [Integer]
|
|
sumEveryTwo [] = 0
|
|
sumEveryTwo (x:[]) = [x]
|
|
sumEveryTwo (x:(y:zs)) = (x + y) : sumEveryTwo zs
|
|
\end{lstlisting}
|
|
Note that \code{(x:(y:zs))} may also be written as \code{(x:y:zs)}.
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Toolchain}
|
|
You need:
|
|
\begin{itemize}
|
|
\item \textbf{GHC}: this is the Haskell compiler
|
|
\item \textbf{GHCi}: this an interactive environment of GHC, similar to the interactive ruby shell \emph{irb}
|
|
\item \textbf{The Haskell Platform}: a collection including GHC, GHCi and basic libraries
|
|
\end{itemize}
|
|
Go to \url{https://www.haskell.org/platform}\\
|
|
For haskell IDEs, see \url{https://wiki.haskell.org/IDEs}
|
|
\end{frame}
|
|
|
|
\begin{frame}
|
|
\frametitle{Further reading and useful links}
|
|
\begin{itemize}
|
|
\item the most popular haskell course from Brent Yorgey:\\ \url{https://www.seas.upenn.edu/~cis194/fall14/spring13/lectures.html}
|
|
\item very verbose and enthusiastic haskell book, good for reading once:\\ \url{http://learnyouahaskell.com}
|
|
\item collection of websites teaching haskell:\\ \url{https://github.com/bitemyapp/learnhaskell}
|
|
\item haskell programming tips (and wiki):\\ \url{https://wiki.haskell.org/Haskell_programming_tips}
|
|
\item the standard module (similar to libc in C):\\ \url{https://hackage.haskell.org/package/base-4.7.0.0/docs/Prelude.html}
|
|
\item debugging in haskell:\\ \url{https://wiki.haskell.org/Debugging}
|
|
\end{itemize}
|
|
|
|
\end{frame}
|
|
|
|
\end{document} |