| author | Christian Urban <christian.urban@kcl.ac.uk> | 
| Fri, 26 Apr 2024 17:35:36 +0100 | |
| changeset 483 | a2c4c6bf319d | 
| parent 482 | 20f02c5ff53f | 
| child 489 | 6ee9ad5d766f | 
| permissions | -rw-r--r-- | 
| 197 | 1 | % !TEX program = xelatex | 
| 123 | 2 | \documentclass{article}
 | 
| 423 | 3 | \usepackage{../styles/style}
 | 
| 4 | \usepackage{../styles/langs}
 | |
| 272 | 5 | \usepackage{tikz}
 | 
| 6 | \usepackage{pgf}
 | |
| 123 | 7 | \usepackage{marvosym}
 | 
| 184 | 8 | \usepackage{boxedminipage}
 | 
| 123 | 9 | |
| 352 | 10 | \lstset{escapeinside={/*!}{!*/}}
 | 
| 11 | \newcommand{\annotation}[1]{\hfill\footnotesize{}#1}
 | |
| 272 | 12 | |
| 352 | 13 | \usepackage{menukeys}
 | 
| 468 | 14 | \usepackage{emoji}
 | 
| 335 | 15 | |
| 123 | 16 | %cheat sheet | 
| 17 | %http://worldline.github.io/scala-cheatsheet/ | |
| 18 | ||
| 181 | 19 | % case class, apply, unapply | 
| 170 | 20 | % see https://medium.com/@thejasbabu/scala-pattern-matching-9c9e73ba9a8a | 
| 21 | ||
| 191 | 22 | % the art of programming | 
| 23 | % https://www.youtube.com/watch?v=QdVFvsCWXrA | |
| 24 | ||
| 25 | % functional programming in Scala | |
| 26 | %https://www.amazon.com/gp/product/1449311032/ref=as_li_ss_tl?ie=UTF8&tag=aleottshompag-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=1449311032 | |
| 27 | ||
| 197 | 28 | % functional programming in C | 
| 191 | 29 | %https://www.amazon.com/gp/product/0201419505/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0201419505&linkCode=as2&tag=aleottshompag-20 | 
| 30 | ||
| 31 | %speeding through haskell | |
| 32 | %https://openlibra.com/en/book/download/speeding-through-haskell | |
| 33 | ||
| 34 | % fp books --- ocaml | |
| 35 | % http://courses.cms.caltech.edu/cs134/cs134b/book.pdf | |
| 36 | % http://alexott.net/en/fp/books/ | |
| 37 | ||
| 257 | 38 | %John Hughes’ simple words: | 
| 39 | %A combinator is a function which builds program fragments | |
| 40 | %from program fragments. | |
| 41 | ||
| 42 | ||
| 301 | 43 | %explain graph colouring program (examples from) | 
| 264 | 44 | %https://www.metalevel.at/prolog/optimization | 
| 45 | ||
| 46 | % nice example for map and reduce using Harry potter characters | |
| 47 | % https://www.matthewgerstman.com/map-filter-reduce/ | |
| 48 | ||
| 333 | 49 | % interesting talk about differences in Java and Scala | 
| 50 | % Goto'19 conference ; about differences in type-system | |
| 51 | % https://www.youtube.com/watch?v=e6n-Ci8V2CM | |
| 264 | 52 | |
| 329 | 53 | % Timing | 
| 54 | % | |
| 55 | % xs.map(x => (x, xs.count(_==x))) | |
| 56 | % | |
| 57 | % vs xs.groupBy(identity) | |
| 58 | % | |
| 59 | % first is quadratic, while second is linear. | |
| 60 | ||
| 61 | % contrast map with a for loop in imperative languages | |
| 62 | % | |
| 63 | % Let’s use a simple example of calculating sales tax on an array of | |
| 64 | % prices. | |
| 65 | % | |
| 66 | % const prices = [19.99, 4.95, 25, 3.50]; | |
| 67 | % let new_prices = []; | |
| 68 | % | |
| 69 | %       for(let i=0; i < prices.length; i++) {
 | |
| 70 | % new_prices.push(prices[i] * 1.06); | |
| 71 | % } | |
| 72 | % | |
| 73 | % We can achieve the same results using .map(): | |
| 74 | % | |
| 75 | % const prices = [19.99, 4.95, 25, 3.50]; | |
| 76 | % let new_prices = prices.map(price => price * 1.06); | |
| 77 | % | |
| 78 | % The syntax above is condensed so let’s walk through it a bit. The | |
| 79 | % .map() method takes a callback, which can be thought of as a function. | |
| 80 | % That’s what is between the parentheses. The variable price is the name | |
| 81 | % that will be used to identify each value. Since there’s only one | |
| 82 | % input, we can omit the usual parentheses around the parameters. | |
| 83 | ||
| 84 | % potentially a worked example? Tetris in scala.js | |
| 85 | % | |
| 86 | % https://medium.com/@michael.karen/learning-modern-javascript-with-tetris-92d532bcd057 | |
| 87 | % | |
| 88 | % Scala videos | |
| 89 | % https://www.youtube.com/user/DrMarkCLewis | |
| 90 | ||
| 334 | 91 | |
| 92 | %% https://alvinalexander.com/downloads/HelloScala-FreePreview.pdf | |
| 93 | %% | |
| 94 | %% Section 10 about strings; interpolations and multiline strings | |
| 95 | ||
| 343 | 96 | % Easy installation | 
| 97 | %https://alexarchambault.github.io/posts/2020-09-21-cs-setup.html | |
| 98 | ||
| 423 | 99 | % scala libraries | 
| 100 | %https://index.scala-lang.org | |
| 101 | ||
| 102 | ||
| 103 | % Learning functional programming is an opportunity to discover a new | |
| 104 | % way to represent programs, to approach problems, and to think about | |
| 105 | % languages. While programming with a functional language is still | |
| 106 | % fundamentally similar to programming with any other type of language | |
| 107 | % (examples of others being imperative or logic), it represents | |
| 108 | % programs and algorithms through distinct forms of abstraction and | |
| 109 | % gives you a new toolset with which to solve programming | |
| 110 | % problems. Additionally, many of the techniques of functional | |
| 111 | % programming are beginning to permeate new mainstream languages, so | |
| 112 | % taking the time now to develop a thorough understanding of them is | |
| 113 | % an investment which will pay great dividends. | |
| 114 | ||
| 115 | ||
| 334 | 116 | |
| 335 | 117 | % Exact colors from NB | 
| 118 | \usepackage[breakable]{tcolorbox}
 | |
| 119 | \definecolor{incolor}{HTML}{303F9F}
 | |
| 120 | \definecolor{outcolor}{HTML}{D84315}
 | |
| 121 | \definecolor{cellborder}{HTML}{CFCFCF}
 | |
| 122 | \definecolor{cellbackground}{HTML}{F7F7F7}
 | |
| 334 | 123 | |
| 335 | 124 | |
| 125 | ||
| 123 | 126 | \begin{document}
 | 
| 480 | 127 | \fnote{\copyright{} Christian Urban, King's College London, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024}
 | 
| 123 | 128 | |
| 335 | 129 | %\begin{tcolorbox}[breakable,size=fbox,boxrule=1pt,pad at break*=1mm,colback=cellbackground,colframe=cellborder]
 | 
| 130 | % abd | |
| 131 | %\end{tcolorbox}
 | |
| 132 | ||
| 125 | 133 | \section*{A Crash-Course in Scala}
 | 
| 123 | 134 | |
| 182 | 135 | \mbox{}\hfill\textit{``Scala --- \underline{S}lowly \underline{c}ompiled 
 | 
| 136 | \underline{a}cademic \underline{la}nguage''}\smallskip\\
 | |
| 192 | 137 | \mbox{}\hfill\textit{ --- a joke(?) found on Twitter}\bigskip
 | 
| 195 | 138 | |
| 467 | 139 | \mbox{}\hfill\textit{``Life is too short for \texttt{malloc}.''}\smallskip\\
 | 
| 140 | \mbox{}\hfill\textit{ --- said Neal Ford at Oscon'13}\;\hr{https://www.youtube.com/watch?v=7aYS9PcAITQ}\bigskip\\ 
 | |
| 141 | ||
| 482 | 142 | % In 1982, James or Jim Morris wrote: | 
| 143 | % | |
| 144 | % Functional languages are unnatural to use; but so are knives and | |
| 145 | % forks, diplomatic protocols, double-entry bookkeeping, and a host of | |
| 146 | % other things modern civilization has found useful. | |
| 147 | % | |
| 148 | % Real Programming in Functional Languages | |
| 149 | % Xerox PARC technical report | |
| 150 | % CSL·81·11 July 1,1981 | |
| 151 | ||
| 152 | ||
| 467 | 153 | |
| 195 | 154 | \subsection*{Introduction}
 | 
| 155 | ||
| 178 | 156 | \noindent | 
| 170 | 157 | Scala is a programming language that combines functional and | 
| 158 | object-oriented programming-styles. It has received quite a bit of | |
| 482 | 159 | attention in the last ten or so years. One reason for this attention is | 
| 181 | 160 | that, like the Java programming language, Scala compiles to the Java | 
| 161 | Virtual Machine (JVM) and therefore Scala programs can run under MacOSX, | |
| 195 | 162 | Linux and Windows. Because of this it has also access to | 
| 181 | 163 | the myriads of Java libraries. Unlike Java, however, Scala often allows | 
| 186 | 164 | programmers to write very concise and elegant code. Some therefore say | 
| 182 | 165 | ``Scala is the better Java''.\footnote{from
 | 
| 480 | 166 |   \url{https://www.slideshare.net/maximnovak/joy-of-scala}, though this might
 | 
| 167 | be outdated as latest versions of Java are catching up somewhat} | |
| 188 | 168 | |
| 482 | 169 | A number of companies---the Guardian, Duolingo, Coursera, FourSquare, | 
| 191 | 170 | Netflix, LinkedIn, ITV to name a few---either use Scala exclusively in | 
| 188 | 171 | production code, or at least to some substantial degree. Scala seems | 
| 172 | also useful in job-interviews (especially in data science) according to | |
| 173 | this anecdotal report | |
| 170 | 174 | |
| 181 | 175 | \begin{quote}
 | 
| 176 | \url{http://techcrunch.com/2016/06/14/scala-is-the-new-golden-child}
 | |
| 170 | 177 | \end{quote}
 | 
| 178 | ||
| 179 | \noindent | |
| 468 | 180 | The official Scala web-page is here: | 
| 170 | 181 | |
| 182 | \begin{quote}
 | |
| 195 | 183 | \url{http://www.scala-lang.org}\medskip
 | 
| 184 | \end{quote}
 | |
| 170 | 185 | |
| 395 | 186 | \noindent\alert | 
| 482 | 187 | For PEP, make sure you are using the version 3(!) of Scala. This is | 
| 467 | 188 | the version I am going to use in the lectures and in the coursework. This | 
| 482 | 189 | can be any version of Scala 3.X where $X=\{3,4\}$. Also the minor
 | 
| 190 | number does not matter. Note that this will be the second year I am | |
| 191 | using this newer version of Scala -- some hiccups can still happen. Apologies | |
| 467 | 192 | in advance!\bigskip | 
| 395 | 193 | |
| 468 | 194 | \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
 | 
| 473 | 195 |   I will be using the \textbf{\texttt{scala-cli}} REPL for Scala 3, rather
 | 
| 468 | 196 | than the ``plain'' Scala REPL. This is a batteries included version of | 
| 473 | 197 | Scala 3 and is easier to use and install. In fact | 
| 198 |   \texttt{scala-cli} is designated to replace
 | |
| 199 | the ``plain'' Scala REPL in future versions of Scala. | |
| 200 | So why not using it now? | |
| 468 | 201 | It can be downloaded from: | 
| 202 | ||
| 203 |   \begin{center}
 | |
| 204 |   \url{https://scala-cli.virtuslab.org}  
 | |
| 205 |   \end{center}  
 | |
| 206 | \end{tcolorbox}\medskip  
 | |
| 207 | ||
| 208 | ||
| 170 | 209 | \noindent | 
| 482 | 210 | If you are interested, there are also experimental backends for Scala | 
| 467 | 211 | for generating JavaScript code (\url{https://www.scala-js.org}), and
 | 
| 212 | there is work under way to have a native Scala compiler generating | |
| 213 | X86-code (\url{http://www.scala-native.org}). There are also some
 | |
| 473 | 214 | tricks for Scala programs to run as a native | 
| 467 | 215 | GraalVM~\hr{https://scala-cli.virtuslab.org/docs/cookbooks/native-images/}
 | 
| 473 | 216 | image. Though be warned these backends are still rather beta or even | 
| 467 | 217 | alpha. | 
| 195 | 218 | |
| 219 | \subsection*{VS Code and Scala}
 | |
| 220 | ||
| 184 | 221 | I found a convenient IDE for writing Scala programs is Microsoft's | 
| 181 | 222 | \textit{Visual Studio Code} (VS Code) which runs under MacOSX, Linux and
 | 
| 269 
3ef2542207c4
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
265diff
changeset | 223 | obviously Windows.\footnote{\ldots{}unlike \emph{Microsoft Visual Studio}---note
 | 
| 191 | 224 | the minuscule difference in the name---which is a heavy-duty, | 
| 269 
3ef2542207c4
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
265diff
changeset | 225 | Windows-only IDE\ldots{}jeez, with all their money could they not have come
 | 
| 191 | 226 | up with a completely different name for a complete different project? | 
| 227 | For the pedantic, Microsoft Visual Studio is an IDE, whereas Visual | |
| 482 | 228 | Studio Code is considered to be a \emph{source code editor}. Anybody
 | 
| 229 | out there knows what the | |
| 191 | 230 | difference is?} It can be downloaded for free from | 
| 181 | 231 | |
| 232 | \begin{quote}
 | |
| 233 | \url{https://code.visualstudio.com}
 | |
| 234 | \end{quote}
 | |
| 235 | ||
| 236 | \noindent | |
| 237 | and should already come pre-installed in the Department (together with | |
| 195 | 238 | the Scala compiler). Being a project that just started in 2015, VS Code is | 
| 467 | 239 | relatively new and therefore far from perfect. However it includes a | 
| 182 | 240 | \textit{Marketplace} from which a multitude of extensions can be
 | 
| 184 | 241 | downloaded that make editing and running Scala code a little easier (see | 
| 242 | Figure~\ref{vscode} for my setup).
 | |
| 181 | 243 | |
| 244 | \begin{figure}[t]
 | |
| 184 | 245 | \begin{boxedminipage}{\textwidth}  
 | 
| 181 | 246 | \begin{center}  
 | 
| 247 | \includegraphics[scale=0.15]{../pics/vscode.png}\\[-10mm]\mbox{}
 | |
| 248 | \end{center}
 | |
| 468 | 249 | \caption{My installation of VS Code / Codium includes the 
 | 
| 250 |   package  \textbf{Scala Syntax (official)} 0.5.7 from Marketplace.
 | |
| 251 |   I have also bound the keys \keys{Ctrl} \keys{Ret} to the
 | |
| 195 | 252 | action ``Run-Selected-Text-In-Active-Terminal'' in order to quickly | 
| 468 | 253 | evaluate small code snippets in the Scala REPL. I use Codium's internal | 
| 254 |   terminal to run \texttt{scala-cli} version 1.0.5 which
 | |
| 255 |   uses Scala 3.3.1.\label{vscode}}
 | |
| 184 | 256 | \end{boxedminipage}
 | 
| 181 | 257 | \end{figure}  
 | 
| 258 | ||
| 473 | 259 | Actually \alert last year I switched to VS Codium as IDE for writing Scala programs. VS Codium is VS Code | 
| 467 | 260 | minus all the telemetry that is normally sent to Microsoft. Apart from | 
| 261 | the telemetry (and Copilot, which you are not supposed to use anyway), | |
| 262 | it works pretty much the same way as the original but is driven by a | |
| 263 | dedicated community, rather than a big company. You can download VS | |
| 264 | Codium from | |
| 438 | 265 | |
| 266 | \begin{quote}
 | |
| 267 | \url{https://vscodium.com}
 | |
| 268 | \end{quote}
 | |
| 269 | ||
| 270 | ||
| 468 | 271 | What I like most about VS Code/Codium is that it provides easy access | 
| 473 | 272 | to any Scala REPL. But if you prefer another editor for coding, it is | 
| 468 | 273 | also painless to work with Scala completely on the command line (as | 
| 482 | 274 | you might do with \texttt{g++} in the second part of PEP). For
 | 
| 468 | 275 | the lazybones among us, there are even online editors and environments | 
| 482 | 276 | for developing and running Scala programs: for example \textit{Scastie}
 | 
| 277 | is one of them. It requires zero setup | |
| 278 | (assuming you have a browser handy). You can access it at | |
| 181 | 279 | |
| 280 | \begin{quote}
 | |
| 482 | 281 |   \url{https://scastie.scala-lang.org}
 | 
| 181 | 282 | \end{quote}
 | 
| 283 | ||
| 195 | 284 | \noindent | 
| 197 | 285 | But you should be careful if you use them for your coursework: they | 
| 468 | 286 | are meant to play around, not really for serious work. Make | 
| 287 | sure your \texttt{scala-cli} works on your own machine ASAP!
 | |
| 197 | 288 | |
| 438 | 289 | As one might expect, Scala can be used with the heavy-duty IDEs | 
| 468 | 290 | Eclipse and IntelliJ. For example IntelliJ includes plugins for | 
| 291 | Scala | |
| 170 | 292 | |
| 293 | \begin{quote}
 | |
| 468 | 294 | \url{https://scalacenter.github.io/bloop/docs/ides/intellij}
 | 
| 170 | 295 | \end{quote}
 | 
| 296 | ||
| 297 | \noindent | |
| 468 | 298 | \underline{\textbf{BUT}}, I do \textbf{not} recommend the usage of
 | 
| 299 | either Eclipse or IntelliJ for PEP: these IDEs seem to make your life | |
| 300 | harder, rather than easier, for the small programs that we will write | |
| 301 | in this module. They are really meant to be used when you have a | |
| 302 | million-lines codebase instead of our small | |
| 303 | ``toy-programs''\ldots{}for example why on earth am I required to
 | |
| 304 | create a completely new project with several subdirectories when I | |
| 305 | just want to try out 20-lines of Scala code? Your mileage may vary | |
| 306 | though.~\texttt{;o)}
 | |
| 182 | 307 | |
| 308 | \subsection*{Why Functional Programming?}
 | |
| 309 | ||
| 186 | 310 | Before we go on, let me explain a bit more why we want to inflict upon | 
| 311 | you another programming language. You hopefully have mastered Java and | |
| 482 | 312 | soon will master C++ as well, you possibly know Python already\ldots{}
 | 
| 313 | the world should be your oyster, no? Well, as usual matters are not as simple | |
| 314 | as one might wish. We do require Scala in PEP, but actually we do not | |
| 315 | religiously care whether you learn Scala---after all it is just a | |
| 316 | programming language (albeit a nifty one IMHO). What we do care about | |
| 317 | is that you learn about \textit{functional programming}. Scala is just
 | |
| 318 | the vehicle for that. Still, you need to learn Scala well enough to | |
| 319 | get good marks in PEP, but functional programming could perhaps | |
| 320 | equally be taught with Haskell, F\#, SML, Ocaml, Kotlin, Clojure, | |
| 321 | Scheme, Elm and many other functional programming languages. | |
| 333 | 322 | |
| 323 | %Your friendly lecturer just | |
| 324 | %happens to like Scala and the Department agreed that it is a good idea | |
| 325 | %to inflict Scala upon you. | |
| 182 | 326 | |
| 327 | Very likely writing programs in a functional programming language is | |
| 467 | 328 | quite different from what you are used to in your study so far. It | 
| 183 | 329 | might even be totally alien to you. The reason is that functional | 
| 330 | programming seems to go against the core principles of | |
| 467 | 331 | \textit{imperative programming} (which is what you do in Java and
 | 
| 468 | 332 | C/C++). The main idea of imperative programming is that | 
| 467 | 333 | you have some form of \emph{state} in your program and you
 | 
| 334 | continuously change this state by issuing some commands---for example | |
| 335 | for updating a field in an array or for adding one to a variable | |
| 336 | stored in memory and so on. The classic example for this style of | |
| 482 | 337 | programming is a \texttt{for}-loop in say Java and C/C++.  Consider the snippet:
 | 
| 182 | 338 | |
| 339 | \begin{lstlisting}[language=C,numbers=none]
 | |
| 184 | 340 | for (int i = 10; i < 20; i++) { 
 | 
| 269 
3ef2542207c4
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
265diff
changeset | 341 | //...do something with i... | 
| 184 | 342 | } | 
| 182 | 343 | \end{lstlisting}
 | 
| 344 | ||
| 467 | 345 | \noindent Here the integer variable \texttt{i} embodies part of the
 | 
| 346 | state of the program, which is first set to \texttt{10} and then
 | |
| 347 | increased by one in each loop-iteration until it reaches \texttt{20}
 | |
| 348 | at which point the loop exits. When this code is compiled and actually | |
| 349 | runs, there will be some dedicated space reserved for \texttt{i} in
 | |
| 350 | memory. This space of typically 32 bits contains \texttt{i}'s current
 | |
| 351 | value\ldots\texttt{10} at the beginning, and then the content will be
 | |
| 352 | overwritten with new content in every iteration. The main point here | |
| 353 | is that this kind of updating, or overwriting, of memory is | |
| 354 | 25.806\ldots or \textbf{THE ROOT OF ALL EVIL}!!
 | |
| 186 | 355 | |
| 356 | \begin{center}
 | |
| 357 | \includegraphics[scale=0.25]{../pics/root-of-all-evil.png}
 | |
| 358 | \end{center}  
 | |
| 359 | ||
| 182 | 360 | |
| 361 | \noindent | |
| 362 | \ldots{}Well, it is perfectly benign if you have a sequential program
 | |
| 363 | that gets run instruction by instruction...nicely one after another. | |
| 364 | This kind of running code uses a single core of your CPU and goes as | |
| 184 | 365 | fast as your CPU frequency, also called clock-speed, allows. The problem | 
| 366 | is that this clock-speed has not much increased over the past decade and | |
| 367 | no dramatic increases are predicted for any time soon. So you are a bit | |
| 277 | 368 | stuck. This is unlike previous generations of developers who could rely | 
| 278 | 369 | upon the fact that approximately every 2 years their code would run | 
| 370 | twice as fast because the clock-speed of their CPUs got twice as fast. | |
| 333 | 371 | |
| 482 | 372 | Unfortunately this does not happen any more nowadays. To get you out | 
| 373 | of this dreadful situation, CPU producers pile more and more cores | |
| 374 | into CPUs in order to make them more powerful and potentially make | |
| 375 | software faster. The task for you as developer is to take somehow | |
| 376 | advantage of these cores by running as much of your code as possible | |
| 377 | in parallel on as many cores you have available (typically 4-8 or even | |
| 378 | more in modern laptops and sometimes much more on high-end | |
| 379 | machines---and we conveniently ignore how many cores are on modern | |
| 380 | GPUs). In this situation \textit{mutable} variables like \texttt{i} in
 | |
| 381 | the for-loop above are evil, or at least a major nuisance: Because if | |
| 382 | you want to distribute some of the loop-iterations over several cores | |
| 383 | that are currently idle in your system, you need to be extremely | |
| 384 | careful about who can read and overwrite the variable | |
| 385 | \texttt{i}.\footnote{If you are of the mistaken belief that nothing
 | |
| 386 |   nasty can happen to \texttt{i} inside the \texttt{for}-loop, then
 | |
| 387 | you will have to be extra careful with the C++ material.} | |
| 333 | 388 | Especially the writing operation is critical because you do not want | 
| 389 | that conflicting writes mess about with \texttt{i}. Take my word: an
 | |
| 482 | 390 | untold amount of misery has arisen from this problem. The catch is | 
| 391 | that if you try to solve this problem in C/C++ or Java, and be as | |
| 392 | defensive as possible about reads and writes to \texttt{i}, then you
 | |
| 393 | need to synchronise access to it. The result is that very often your | |
| 394 | program waits more than it runs, thereby defeating the point of trying | |
| 395 | to run the program in parallel in the first place. If you are less | |
| 396 | defensive, then usually all hell breaks loose by seemingly obtaining | |
| 397 | random results. And forget the idea of being able to debug such | |
| 398 | code. If you want to watch a 5-minute video of horror stories, feel | |
| 399 | free to follow \ldots{}
 | |
| 400 | \hr{https://www.youtube.com/watch?v=LdLUgCJkiHY} (I love the fact, he
 | |
| 401 | says at 4:02 that he does not understand how the JVM really | |
| 402 | works\ldots{} I always assumed I am the only idiot who does not
 | |
| 403 | understand how threads work on the JVM. Apparently not. \raisebox{-0.7mm}{\emoji{rofl}})\bigskip
 | |
| 182 | 404 | |
| 482 | 405 | \noindent | 
| 184 | 406 | The central idea of functional programming is to eliminate any state | 
| 482 | 407 | and mutable variables from programs---or at least from the ``interesting bits'' of the | 
| 195 | 408 | programs. Because then it is easy to parallelise the resulting | 
| 409 | programs: if you do not have any state, then once created, all memory | |
| 410 | content stays unchanged and reads to such memory are absolutely safe | |
| 411 | without the need of any synchronisation. An example is given in | |
| 412 | Figure~\ref{mand} where in the absence of the annoying state, Scala
 | |
| 413 | makes it very easy to calculate the Mandelbrot set on as many cores of | |
| 414 | your CPU as possible. Why is it so easy in this example? Because each | |
| 415 | pixel in the Mandelbrot set can be calculated independently and the | |
| 416 | calculation does not need to update any variable. It is so easy in | |
| 417 | fact that going from the sequential version of the Mandelbrot program | |
| 418 | to the parallel version can be achieved by adding just eight | |
| 419 | characters---in two places you have to add \texttt{.par}. Try the same
 | |
| 272 | 420 | in C/C++ or Java! | 
| 182 | 421 | |
| 422 | \begin{figure}[p]
 | |
| 184 | 423 | \begin{boxedminipage}{\textwidth}
 | 
| 187 | 424 | |
| 191 | 425 | A Scala program for generating pretty pictures of the Mandelbrot set.\smallskip\\ | 
| 426 | (See \url{https://en.wikipedia.org/wiki/Mandelbrot_set} or\\
 | |
| 427 | \phantom{(See }\url{https://www.youtube.com/watch?v=aSg2Db3jF_4}):
 | |
| 184 | 428 | \begin{center}    
 | 
| 429 | \begin{tabular}{c}  
 | |
| 191 | 430 | \includegraphics[scale=0.11]{../pics/mand1.png}\\[-8mm]\mbox{}
 | 
| 184 | 431 | \end{tabular}
 | 
| 187 | 432 | \end{center}
 | 
| 184 | 433 | |
| 187 | 434 | \begin{center}
 | 
| 435 | \begin{tabular}{@{}p{0.45\textwidth}|p{0.45\textwidth}@{}}
 | |
| 191 | 436 | \bf sequential version: & \bf parallel version on 4 cores:\smallskip\\ | 
| 182 | 437 | |
| 191 | 438 |   {\hfill\includegraphics[scale=0.11]{../pics/mand4.png}\hfill} &
 | 
| 439 |   {\hfill\includegraphics[scale=0.11]{../pics/mand3.png}\hfill} \\
 | |
| 187 | 440 | |
| 441 | {\footnotesize\begin{lstlisting}[xleftmargin=-1mm]
 | |
| 186 | 442 | for (y <- (0 until H)) {
 | 
| 443 |   for (x <- (0 until W)) {
 | |
| 444 | ||
| 445 | val c = start + | |
| 446 | (x * d_x + y * d_y * i) | |
| 447 | val iters = iterations(c, max) | |
| 191 | 448 | val colour = | 
| 186 | 449 | if (iters == max) black | 
| 450 | else colours(iters % 16) | |
| 451 | ||
| 191 | 452 | pixel(x, y, colour) | 
| 186 | 453 | } | 
| 454 | viewer.updateUI() | |
| 455 | } | |
| 187 | 456 | \end{lstlisting}}   
 | 
| 457 | & | |
| 458 | {\footnotesize\begin{lstlisting}[xleftmargin=0mm]
 | |
| 400 | 459 | for (y <- (0 until H).par) {
 | 
| 460 |   for (x <- (0 until W).par) {
 | |
| 187 | 461 | |
| 462 | val c = start + | |
| 463 | (x * d_x + y * d_y * i) | |
| 464 | val iters = iterations(c, max) | |
| 191 | 465 | val colour = | 
| 187 | 466 | if (iters == max) black | 
| 467 | else colours(iters % 16) | |
| 468 | ||
| 191 | 469 | pixel(x, y, colour) | 
| 187 | 470 | } | 
| 471 | viewer.updateUI() | |
| 472 | } | |
| 191 | 473 | \end{lstlisting}}\\[-2mm]
 | 
| 187 | 474 | |
| 475 | \centering\includegraphics[scale=0.5]{../pics/cpu2.png} &
 | |
| 188 | 476 | \centering\includegraphics[scale=0.5]{../pics/cpu1.png}
 | 
| 184 | 477 | \end{tabular}
 | 
| 478 | \end{center}
 | |
| 482 | 479 | \caption{The code of the two ``main'' loops in my version of the mandelbrot program.
 | 
| 191 | 480 | The parallel version differs only in \texttt{.par} being added to the
 | 
| 195 | 481 | ``ranges'' of the x and y coordinates. As can be seen from the CPU loads, in | 
| 482 | the sequential version there is a lower peak for an extended period, | |
| 191 | 483 | while in the parallel version there is a short sharp burst for | 
| 484 | essentially the same workload\ldots{}meaning you get more work done 
 | |
| 195 | 485 | in a shorter amount of time. This easy \emph{parallelisation} 
 | 
| 482 | 486 | only works reliably with immutable programs. | 
| 188 | 487 | \label{mand}} 
 | 
| 184 | 488 | \end{boxedminipage}
 | 
| 182 | 489 | \end{figure}  
 | 
| 490 | ||
| 275 | 491 | But remember this easy parallelisation of code requires that we have no | 
| 492 | state in our programs\ldots{}that is no counters like \texttt{i} in
 | |
| 493 | \texttt{for}-loops. You might then ask, how do I write loops without
 | |
| 494 | such counters? Well, teaching you that this is possible is one of the | |
| 495 | main points of the Scala-part in PEP. I can assure you it is possible, | |
| 496 | but you have to get your head around it. Once you have mastered this, it | |
| 497 | will be fun to have no state in your programs (a side product is that it | |
| 498 | much easier to debug state-less code and also more often than not easier | |
| 499 | to understand). So have fun with Scala!\footnote{If you are still not
 | |
| 500 | convinced about the function programming ``thing'', there are a few more | |
| 501 | arguments: a lot of research in programming languages happens to take | |
| 502 | place in functional programming languages. This has resulted in | |
| 503 | ultra-useful features such as pattern-matching, strong type-systems, | |
| 504 | laziness, implicits, algebraic datatypes to name a few. Imperative | |
| 505 | languages seem to often lag behind in adopting them: I know, for | |
| 506 | example, that Java will at some point in the future support | |
| 507 | pattern-matching, which has been used for example in SML for at least | |
| 508 | 40(!) years. See | |
| 438 | 509 | \url{https://openjdk.org/projects/amber/design-notes/patterns/pattern-matching-for-java}.
 | 
| 275 | 510 | Automatic garbage collection was included in Java in 1995; the | 
| 511 | functional language LISP had this already in 1958. Generics were added | |
| 512 | to Java 5 in 2004; the functional language SML had it since 1990. | |
| 277 | 513 | Higher-order functions were added to C\# in 2007, to Java 8 in | 
| 275 | 514 | 2014; again LISP had them since 1958. Also Rust, a C-like programming | 
| 515 | language that has been developed since 2010 and is gaining quite some | |
| 516 | interest, borrows many ideas from functional programming from | |
| 277 | 517 | yesteryear.}\medskip | 
| 170 | 518 | |
| 277 | 519 | \noindent | 
| 438 | 520 | If you need any after-work distractions, you might have fun reading | 
| 467 | 521 | the following article about FP (functional programming) --- you | 
| 438 | 522 | might have to disable your browser cookies though if you want to read | 
| 523 | it for free. And spoiler alert: This is tongue-in-cheek \texttt{;o)}
 | |
| 277 | 524 | |
| 525 | \begin{quote}
 | |
| 467 | 526 |   \url{https://archive.ph/vrofC}
 | 
| 277 | 527 | \end{quote}
 | 
| 188 | 528 | |
| 123 | 529 | \subsection*{The Very Basics}
 | 
| 530 | ||
| 473 | 531 | Let us get back to Scala and \texttt{scala-cli}: One advantage of
 | 
| 532 | Scala over Java is that it includes an interpreter (a REPL, or | |
| 123 | 533 | \underline{R}ead-\underline{E}val-\underline{P}rint-\underline{L}oop)
 | 
| 181 | 534 | with which you can run and test small code snippets without the need | 
| 123 | 535 | of a compiler. This helps a lot with interactively developing | 
| 467 | 536 | programs. It is my preferred way of writing small Scala programs. Once | 
| 473 | 537 | you installed \texttt{scala-cli}, you can start the interpreter by typing on the
 | 
| 467 | 538 | command line: | 
| 123 | 539 | |
| 540 | \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
 | |
| 468 | 541 | $ scala-cli | 
| 482 | 542 | Welcome to Scala 3.4.1 (21.0.2, Java OpenJDK 64-Bit Server VM). | 
| 468 | 543 | Type in expressions for evaluation. Or try :help. | 
| 123 | 544 | |
| 545 | scala> | |
| 546 | \end{lstlisting}%$
 | |
| 547 | ||
| 473 | 548 | \noindent The precise response may vary depending on the version and | 
| 549 | platform where you installed \texttt{scala-cli}. Make sure however that
 | |
| 550 | \texttt{scala-cli} uses Scala version 3---you can find the version
 | |
| 551 | number in the welcome message. Also note that at the first time | |
| 552 | \texttt{scala-cli} runs, it might download various components, for
 | |
| 553 | example the Scala compiler, Scala runtimes etc. Once | |
| 554 | \texttt{scala-cli} is up and running, you can type at the prompt
 | |
| 555 | expressions like \code{2 + 3}\;\keys{Ret} and the output will be
 | |
| 123 | 556 | |
| 467 | 557 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 123 | 558 | scala> 2 + 3 | 
| 467 | 559 | val res0: Int = 5 | 
| 123 | 560 | \end{lstlisting}
 | 
| 561 | ||
| 188 | 562 | \noindent The answer means that he result of the addition is of type | 
| 478 | 563 | 0\code{Int} and the actual result is 5; \code{res0} is a name that
 | 
| 125 | 564 | Scala gives automatically to the result. You can reuse this name later | 
| 188 | 565 | on, for example | 
| 181 | 566 | |
| 467 | 567 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 181 | 568 | scala> res0 + 4 | 
| 467 | 569 | val res1: Int = 9 | 
| 181 | 570 | \end{lstlisting}
 | 
| 571 | ||
| 572 | \noindent | |
| 573 | Another classic example you can try out is | |
| 123 | 574 | |
| 467 | 575 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 468 | 576 | scala> println("hello world")
 | 
| 123 | 577 | hello world | 
| 578 | \end{lstlisting}
 | |
| 579 | ||
| 580 | \noindent Note that in this case there is no result. The | |
| 468 | 581 | reason is that \code{println} does not actually produce a result
 | 
| 124 | 582 | (there is no \code{resX} and no type), rather it is a
 | 
| 123 | 583 | function that causes the \emph{side-effect} of printing out a
 | 
| 584 | string. Once you are more familiar with the functional | |
| 585 | programming-style, you will know what the difference is | |
| 586 | between a function that returns a result, like addition, and a | |
| 468 | 587 | function that causes a side-effect, like \code{println}. We
 | 
| 123 | 588 | shall come back to this point later, but if you are curious | 
| 589 | now, the latter kind of functions always has \code{Unit} as
 | |
| 188 | 590 | return type. It is just not printed by Scala. | 
| 123 | 591 | |
| 468 | 592 | You can try more examples with the \texttt{scala-cli} REPL, but feel free to
 | 
| 181 | 593 | first guess what the result is (not all answers by Scala are obvious): | 
| 123 | 594 | |
| 468 | 595 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 123 | 596 | scala> 2 + 2 | 
| 597 | scala> 1 / 2 | |
| 598 | scala> 1.0 / 2 | |
| 599 | scala> 1 / 2.0 | |
| 600 | scala> 1 / 0 | |
| 601 | scala> 1.0 / 0.0 | |
| 602 | scala> true == false | |
| 603 | scala> true && false | |
| 604 | scala> 1 > 1.0 | |
| 605 | scala> "12345".length | |
| 181 | 606 | scala> List(1,2,1).size | 
| 607 | scala> Set(1,2,1).size | |
| 265 | 608 | scala> List(1) == List(1) | 
| 609 | scala> Array(1) == Array(1) | |
| 610 | scala> Array(1).sameElements(Array(1)) | |
| 335 | 611 | \end{lstlisting}
 | 
| 612 | ||
| 613 | \noindent | |
| 614 | Also observe carefully what Scala responds in the following | |
| 615 | three instances involving the constant \lstinline!1!---can | |
| 616 | you explain the differences? | |
| 617 | ||
| 618 | ||
| 619 | \begin{lstlisting}[numbers=none]
 | |
| 620 | scala> 1 | |
| 621 | scala> 1L | |
| 622 | scala> 1F | |
| 181 | 623 | \end{lstlisting}\smallskip
 | 
| 123 | 624 | |
| 335 | 625 | |
| 626 | ||
| 181 | 627 | \noindent | 
| 628 | Please take the Scala REPL seriously: If you want to take advantage of my | |
| 629 | reference implementation for the assignments, you will need to be | |
| 630 | able to ``play around'' with it! | |
| 631 | ||
| 632 | \subsection*{Standalone Scala Apps}
 | |
| 123 | 633 | |
| 277 | 634 | If you want to write a standalone app in Scala, you can | 
| 468 | 635 | implement a function \texttt{hello} and annotate the tag
 | 
| 636 | \texttt{@main}. For example write
 | |
| 123 | 637 | |
| 638 | \begin{lstlisting}[numbers=none]
 | |
| 468 | 639 | @main | 
| 640 | def Hello() = println("hello world")
 | |
| 123 | 641 | \end{lstlisting}
 | 
| 642 | ||
| 468 | 643 | %object Hello extends App {
 | 
| 644 | %    println("hello world")
 | |
| 645 | %} | |
| 646 | ||
| 197 | 647 | \noindent save it in a file, say {\tt hello-world.scala}, and
 | 
| 468 | 648 | then use \texttt{scala-cli run} (which internally compiles the
 | 
| 649 | scala file and runs it): | |
| 123 | 650 | |
| 651 | \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
 | |
| 468 | 652 | $ scala-cli run hello-world.scala | 
| 123 | 653 | hello world | 
| 654 | \end{lstlisting}
 | |
| 655 | ||
| 124 | 656 | \noindent | 
| 123 | 657 | Like Java, Scala targets the JVM and consequently | 
| 658 | Scala programs can also be executed by the bog-standard Java | |
| 468 | 659 | Runtime. This can be done as follows: | 
| 123 | 660 | |
| 661 | \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
 | |
| 468 | 662 | $ scala-cli --power package --assembly hello-world.scala | 
| 663 | $ java -jar Hello.jar | |
| 123 | 664 | hello world | 
| 665 | \end{lstlisting}
 | |
| 666 | ||
| 667 | ||
| 668 | \subsection*{Values}
 | |
| 669 | ||
| 467 | 670 | \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
 | 
| 671 |   Do not use \code{var} in your code for PEP! This declares a mutable variable.
 | |
| 672 |   Only use \code{val}!
 | |
| 673 | \end{tcolorbox}\medskip  
 | |
| 674 | ||
| 675 | \noindent | |
| 124 | 676 | In the lectures I will try to avoid as much as possible the term | 
| 677 | \emph{variables} familiar from other programming languages. The reason
 | |
| 678 | is that Scala has \emph{values}, which can be seen as abbreviations of
 | |
| 482 | 679 | potentially larger expressions. The keyword for defining values is \code{val}.
 | 
| 271 | 680 | For example | 
| 123 | 681 | |
| 682 | \begin{lstlisting}[numbers=none]
 | |
| 683 | scala> val x = 42 | |
| 467 | 684 | val x: Int = 42 | 
| 123 | 685 | |
| 686 | scala> val y = 3 + 4 | |
| 467 | 687 | val y: Int = 7 | 
| 123 | 688 | |
| 689 | scala> val z = x / y | |
| 467 | 690 | val z: Int = 6 | 
| 123 | 691 | \end{lstlisting}
 | 
| 692 | ||
| 693 | \noindent | |
| 272 | 694 | As can be seen, we first define \code{x} and {y} with admittedly some silly
 | 
| 271 | 695 | expressions, and then reuse these values in the definition of \code{z}.
 | 
| 272 | 696 | All easy, right? Why the kerfuffle about values? Well, values are | 
| 271 | 697 | \emph{immutable}. You cannot change their value after you defined them.
 | 
| 698 | If you try to reassign \code{z} above, Scala will yell at you:
 | |
| 123 | 699 | |
| 700 | \begin{lstlisting}[numbers=none]
 | |
| 701 | scala> z = 9 | |
| 467 | 702 | -- [E052] Type Error: ----------------------------------- | 
| 703 | 1 |z = 9 | |
| 704 | |^^^^^ | |
| 705 | |Reassignment to val z | |
| 706 | | ... | |
| 707 | 1 error found | |
| 123 | 708 | \end{lstlisting}
 | 
| 709 | ||
| 710 | \noindent | |
| 711 | So it would be a bit absurd to call values as variables...you cannot | |
| 195 | 712 | change them; they cannot vary. You might think you can reassign them like | 
| 123 | 713 | |
| 714 | \begin{lstlisting}[numbers=none]
 | |
| 715 | scala> val x = 42 | |
| 716 | scala> val z = x / 7 | |
| 717 | scala> val x = 70 | |
| 718 | scala> println(z) | |
| 719 | \end{lstlisting}
 | |
| 720 | ||
| 124 | 721 | \noindent but try to guess what Scala will print out | 
| 123 | 722 | for \code{z}?  Will it be \code{6} or \code{10}? A final word about
 | 
| 723 | values: Try to stick to the convention that names of values should be | |
| 188 | 724 | lower case, like \code{x}, \code{y}, \code{foo41} and so on. Upper-case
 | 
| 271 | 725 | names you should reserve for what is called \emph{constructors}. And 
 | 
| 726 | forgive me when I call values as variables\ldots{}it is just something that
 | |
| 727 | has been in imprinted into my developer-DNA during my early days and | |
| 272 | 728 | is difficult to get rid of.~\texttt{;o)}  
 | 
| 123 | 729 | |
| 730 | ||
| 731 | \subsection*{Function Definitions}
 | |
| 732 | ||
| 181 | 733 | We do functional programming! So defining functions will be our main occupation. | 
| 182 | 734 | As an example, a function named \code{f} taking a single argument of type 
 | 
| 181 | 735 | \code{Int} can be defined in Scala as follows:
 | 
| 123 | 736 | |
| 737 | \begin{lstlisting}[numbers=none]
 | |
| 181 | 738 | def f(x: Int) : String = ...EXPR... | 
| 123 | 739 | \end{lstlisting} 
 | 
| 740 | ||
| 741 | \noindent | |
| 124 | 742 | This function returns the value resulting from evaluating the expression | 
| 271 | 743 | \code{EXPR} (whatever is substituted for this). Since we declared
 | 
| 744 | \code{String}, the result of this function will be of type
 | |
| 745 | \code{String}. It is a good habit to always include this information
 | |
| 272 | 746 | about the return type, while it is only strictly necessary to give this | 
| 482 | 747 | type in recursive functions (later more on that). Simple examples of Scala functions are: | 
| 123 | 748 | |
| 749 | \begin{lstlisting}[numbers=none]
 | |
| 750 | def incr(x: Int) : Int = x + 1 | |
| 751 | def double(x: Int) : Int = x + x | |
| 752 | def square(x: Int) : Int = x * x | |
| 753 | \end{lstlisting}
 | |
| 754 | ||
| 755 | \noindent | |
| 482 | 756 | The general scheme for functions is | 
| 123 | 757 | |
| 758 | \begin{lstlisting}[numbers=none]
 | |
| 759 | def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = {
 | |
| 271 | 760 | ...BODY... | 
| 123 | 761 | } | 
| 762 | \end{lstlisting}
 | |
| 763 | ||
| 764 | \noindent | |
| 197 | 765 | where each argument, \texttt{arg1}, \texttt{arg2} and so on, requires 
 | 
| 766 | its type and the result type of the | |
| 767 | function, \code{rty}, should also be given. If the body of the function is
 | |
| 467 | 768 | more complex, then it can be enclosed in braces, like above. If it | 
| 124 | 769 | is just a simple expression, like \code{x + 1}, you can omit the
 | 
| 195 | 770 | braces. Very often functions are recursive (that is call themselves), | 
| 771 | like the venerable factorial function: | |
| 123 | 772 | |
| 773 | \begin{lstlisting}[numbers=none]
 | |
| 271 | 774 | def fact(n: Int) : Int = | 
| 123 | 775 | if (n == 0) 1 else n * fact(n - 1) | 
| 776 | \end{lstlisting}
 | |
| 188 | 777 | |
| 778 | \noindent | |
| 467 | 779 | where we have to give the return type \code{Int}. Note we could also
 | 
| 780 | have written this with braces as | |
| 271 | 781 | |
| 782 | \begin{lstlisting}[numbers=none]
 | |
| 783 | def fact(n: Int) : Int = {
 | |
| 784 | if (n == 0) 1 | |
| 785 | else n * fact(n - 1) | |
| 786 | } | |
| 787 | \end{lstlisting}
 | |
| 788 | ||
| 789 | \noindent | |
| 272 | 790 | but this seems a bit overkill for a small function like \code{fact}.
 | 
| 468 | 791 | Notice that I did not use a \code{then}-keyword in the
 | 
| 792 | \code{if}-statements and that I enclosed the condition inside
 | |
| 793 | parentheses, like \code{(n == 0)}. Your eyes might hurt to not see an
 | |
| 482 | 794 | \code{then} with an \code{if}, but this has been long established
 | 
| 468 | 795 | syntax for \code{if}-statements. Scala, to my knowledge, was pretty
 | 
| 796 | unique in that for nearly 20 years of its existence\ldots{}until Scala
 | |
| 797 | 3 came along. While people like me have perfectly adapted to the sight | |
| 798 | of \code{if}s without \code{then}s, it seems the developers of Scala
 | |
| 799 | caved in to the special eyesight of Gen-Python people and now allow to | |
| 800 | write the same function also as | |
| 801 | ||
| 802 | \begin{lstlisting}[numbers=none]
 | |
| 803 | def fact(n: Int) : Int = {
 | |
| 482 | 804 | if n == 0 | 
| 805 | then 1 | |
| 468 | 806 | else n * fact(n - 1) | 
| 807 | } | |
| 808 | \end{lstlisting}
 | |
| 809 | ||
| 810 | \noindent | |
| 811 | I accept this might look a bit more familiar to beginners of Scala, if | |
| 812 | they come from other languages, like Java or C++. But that we also had | |
| 813 | to get rid in Scala 3 of the familiar \texttt{\{\}}-parentheses is
 | |
| 814 | completely beyond me. So in Scala 3 the braces are optional and the | |
| 815 | \texttt{fact}-function can even be written as
 | |
| 816 | ||
| 817 | \begin{lstlisting}[numbers=none]
 | |
| 818 | def fact(n: Int) : Int = | |
| 482 | 819 | if n == 0 | 
| 820 | then 1 | |
| 468 | 821 | else n * fact(n - 1) | 
| 822 | \end{lstlisting}
 | |
| 823 | ||
| 824 | \noindent on the condition that indents now become \emph{meaningful}
 | |
| 825 | (as in Python).\raisebox{-0.7mm}{\emoji{face-vomiting}} All versions are now permitted in Scala 3. While you
 | |
| 826 | are free to use any syntax version you want in PEP, or even mix them, | |
| 827 | I will \textbf{not} show you any of my code in the newfangled
 | |
| 828 | Pythonesque meaningful-indent-syntax. When necessary, I will always | |
| 829 | use braces to indicate the beginning and end of a code block, and I | |
| 482 | 830 | have not yet get completely get used to the \code{if}s with
 | 
| 831 | \code{then}s. Please forgive me for being still inconsistent with this\footnote{Scala adopted some very fine features of Python, for example string interpolations, but that we had to completely cave in to
 | |
| 832 | the demands of Gen-Python is a bridge too far for my completely | |
| 833 | insignificant opinion. | |
| 468 | 834 | I always assumed escaping Python's dependency hell | 
| 482 | 835 | is every software developers life goal---apparently not. \emoji{exploding-head}}
 | 
| 468 | 836 | |
| 837 | ||
| 838 | However, no matter which syntax style you adopt for \code{if}s, never
 | |
| 839 | write an \code{if} without an \code{else}-branch! That has something
 | |
| 840 | to do with functional programming and you will see its purpose later | |
| 841 | on. Coming back to function definitions: While \code{def} is the main
 | |
| 335 | 842 | mechanism for defining functions, there are a few other ways for doing | 
| 843 | this. We will see some of them in the next sections. | |
| 272 | 844 | |
| 845 | Before we go on, let me explain one tricky point in function | |
| 335 | 846 | definitions, especially in larger definitions. What does a Scala | 
| 847 | function return as result? Scala has a \code{return} keyword, but it is
 | |
| 272 | 848 | used for something different than in Java (and C/C++). Therefore please | 
| 849 | make sure no \code{return} slips into your Scala code.
 | |
| 850 | ||
| 851 | So in the absence of \code{return}, what value does a Scala function
 | |
| 852 | actually produce? A rule-of-thumb is whatever is in the last line of the | |
| 853 | function is the value that will be returned. Consider the following | |
| 854 | example:\footnote{We could have written this function in just one line,
 | |
| 467 | 855 | but for the sake of argument let's keep the two intermediate values.} | 
| 272 | 856 | |
| 857 | \begin{lstlisting}[numbers=none]
 | |
| 277 | 858 | def average(xs: List[Int]) : Int = {
 | 
| 272 | 859 | val s = xs.sum | 
| 860 | val n = xs.length | |
| 861 | s / n | |
| 862 | } | |
| 863 | \end{lstlisting}
 | |
| 864 | ||
| 865 | \noindent In this example the expression \code{s / n} is in the last
 | |
| 866 | line of the function---so this will be the result the function | |
| 867 | calculates. The two lines before just calculate intermediate values. | |
| 335 | 868 | This principle of the ``last-line'' comes in handy when you need to | 
| 869 | print out values, for example, for debugging purposes. Suppose you want | |
| 272 | 870 | rewrite the function as | 
| 871 | ||
| 872 | \begin{lstlisting}[numbers=none]
 | |
| 277 | 873 | def average(xs: List[Int]) : Int = {
 | 
| 272 | 874 | val s = xs.sum | 
| 875 | val n = xs.length | |
| 876 | val h = xs.head | |
| 877 | println(s"Input $xs with first element $h") | |
| 878 | s / n | |
| 879 | } | |
| 880 | \end{lstlisting}
 | |
| 881 | ||
| 882 | \noindent | |
| 467 | 883 | Here the function still only returns the expression \code{s / n} in
 | 
| 884 | the last line.  The \code{println} before just prints out some
 | |
| 885 | information about the input of this function, but does not contribute | |
| 886 | to the result of the function. Similarly, the value \code{h} is used
 | |
| 887 | in the \code{println} but does not contribute to what integer is
 | |
| 888 | returned by the function. | |
| 335 | 889 | |
| 890 | A caveat is that the idea with the ``last line'' is only a rough | |
| 891 | rule-of-thumb. A better rule might be: the last expression that is | |
| 892 | evaluated in the function. Consider the following version of | |
| 893 | \code{average}:
 | |
| 272 | 894 | |
| 895 | \begin{lstlisting}[numbers=none]
 | |
| 277 | 896 | def average(xs: List[Int]) : Int = {
 | 
| 272 | 897 | if (xs.length == 0) 0 | 
| 898 | else xs.sum / xs.length | |
| 899 | } | |
| 900 | \end{lstlisting}
 | |
| 901 | ||
| 902 | \noindent | |
| 335 | 903 | What does this function return? Well there are two possibilities: either | 
| 904 | the result of \code{xs.sum / xs.length} in the last line provided the
 | |
| 905 | list \code{xs} is nonempty, \textbf{or} if the list is empty, then it
 | |
| 906 | will return \code{0} from the \code{if}-branch (which is technically not
 | |
| 907 | the last line, but the last expression evaluated by the function in the | |
| 272 | 908 | empty-case). | 
| 909 | ||
| 910 | Summing up, do not use \code{return} in your Scala code! A function
 | |
| 911 | returns what is evaluated by the function as the last expression. There | |
| 912 | is always only one such last expression. Previous expressions might | |
| 277 | 913 | calculate intermediate values, but they are not returned. If your | 
| 914 | function is supposed to return multiple things, then one way in Scala is | |
| 915 | to use tuples. For example returning the minimum, average and maximum | |
| 916 | can be achieved by | |
| 271 | 917 | |
| 277 | 918 | \begin{lstlisting}[numbers=none]
 | 
| 919 | def avr_minmax(xs: List[Int]) : (Int, Int, Int) = {
 | |
| 920 | if (xs.length == 0) (0, 0, 0) | |
| 921 | else (xs.min, xs.sum / xs.length, xs.max) | |
| 922 | } | |
| 923 | \end{lstlisting}
 | |
| 924 | ||
| 925 | \noindent | |
| 926 | which still satisfies the rule-of-thumb. | |
| 927 | ||
| 467 | 928 | \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
 | 
| 929 |   Do not use \code{return} in your code to indicate what a function
 | |
| 930 | produces as a result! It has a different meaning in Scala than in | |
| 931 | Java. It can change the meaning of your program, and you should | |
| 932 | never use it. | |
| 933 | \end{tcolorbox}
 | |
| 934 | ||
| 277 | 935 | |
| 936 | \subsection*{Loops, or Better the Absence Thereof}
 | |
| 123 | 937 | |
| 272 | 938 | Coming from Java or C/C++, you might be surprised that Scala does | 
| 123 | 939 | not really have loops. It has instead, what is in functional | 
| 940 | programming called, \emph{maps}. To illustrate how they work,
 | |
| 941 | let us assume you have a list of numbers from 1 to 8 and want to | |
| 942 | build the list of squares. The list of numbers from 1 to 8 | |
| 943 | can be constructed in Scala as follows: | |
| 944 | ||
| 467 | 945 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 123 | 946 | scala> (1 to 8).toList | 
| 467 | 947 | val res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8) | 
| 123 | 948 | \end{lstlisting}
 | 
| 949 | ||
| 197 | 950 | \noindent Generating from this list the list of corresponding | 
| 951 | squares in a programming language such as Java, you would assume | |
| 952 | the list is given as a kind of array. You would then iterate, or loop, | |
| 123 | 953 | an index over this array and replace each entry in the array | 
| 954 | by the square. Right? In Scala, and in other functional | |
| 955 | programming languages, you use maps to achieve the same. | |
| 956 | ||
| 272 | 957 | A map essentially takes a function that describes how each element is | 
| 958 | transformed (in this example the function is $n \rightarrow n * n$) and | |
| 959 | a list over which this function should work. Pictorially you can think | |
| 960 | of the idea behind maps as follows: | |
| 961 | ||
| 962 | \begin{center}
 | |
| 963 | \begin{tikzpicture}
 | |
| 964 | ||
| 965 |   \node (A0) at (1.2,0) {\texttt{List(}};
 | |
| 966 |   \node (A1) at (2.0,0) {\texttt{1\makebox[0mm]{ ,}}};
 | |
| 967 |   \node (A2) at (2.9,0) {\texttt{2\makebox[0mm]{ ,}}};
 | |
| 968 |   \node (A3) at (3.8,0) {\texttt{3\makebox[0mm]{ ,}}};
 | |
| 969 |   \node (A4) at (4.7,0) {\texttt{4\makebox[0mm]{ ,}}};
 | |
| 970 |   \node (A5) at (5.6,0) {\texttt{5\makebox[0mm]{ ,}}};
 | |
| 971 |   \node (A6) at (6.5,0) {\texttt{6\makebox[0mm]{ ,}}};
 | |
| 972 |   \node (A7) at (7.4,0) {\texttt{7\makebox[0mm]{ ,}}};
 | |
| 973 |   \node (A8) at (8.3,0) {\texttt{8)}};
 | |
| 974 | ||
| 975 |   \node (B0) at (1.2,-3) {\texttt{List(}};
 | |
| 976 |   \node (B1) at (2.0,-3) {\texttt{1\makebox[0mm]{ ,}}};
 | |
| 977 |   \node (B2) at (3.0,-3) {\texttt{4\makebox[0mm]{ ,}}};
 | |
| 978 |   \node (B3) at (4.1,-3) {\texttt{9\makebox[0mm]{ ,}}};
 | |
| 979 |   \node (B4) at (5.2,-3) {\texttt{16\makebox[0mm]{ ,}}};
 | |
| 980 |   \node (B5) at (6.3,-3) {\texttt{25\makebox[0mm]{ ,}}};
 | |
| 981 |   \node (B6) at (7.4,-3) {\texttt{36\makebox[0mm]{ ,}}};
 | |
| 982 |   \node (B7) at (8.4,-3) {\texttt{49\makebox[0mm]{ ,}}};
 | |
| 983 |   \node (B8) at (9.4,-3) {\texttt{64\makebox[0mm]{ )}}};
 | |
| 984 | ||
| 985 | \draw [->,line width=1mm] (A1.south) -- (B1.north); | |
| 986 | \draw [->,line width=1mm] (A2.south) -- (B2.north); | |
| 987 | \draw [->,line width=1mm] (A3.south) -- (B3.north); | |
| 988 | \draw [->,line width=1mm] (A4.south) -- (B4.north); | |
| 989 | \draw [->,line width=1mm] (A5.south) -- (B5.north); | |
| 990 | \draw [->,line width=1mm] (A6.south) -- (B6.north); | |
| 991 | \draw [->,line width=1mm] (A7.south) -- (B7.north); | |
| 992 | \draw [->,line width=1mm] (A8.south) -- (B8.north); | |
| 993 | ||
| 277 | 994 |   \node [red] (Q0) at (-0.3,-0.3) {\large\texttt{n}}; 
 | 
| 995 |   \node (Q1) at (-0.3,-0.4) {};
 | |
| 996 |   \node (Q2) at (-0.3,-2.5) {};
 | |
| 997 |   \node [red] (Q3) at (-0.3,-2.65) {\large\texttt{n\,*\,n}};
 | |
| 272 | 998 | \draw [->,red,line width=1mm] (Q1.south) -- (Q2.north); | 
| 999 | ||
| 1000 |   \node [red] at (-1.3,-1.5) {\huge{}\it\textbf{map}};
 | |
| 1001 |  \end{tikzpicture}
 | |
| 1002 | \end{center}
 | |
| 1003 | ||
| 1004 | \noindent | |
| 1005 | On top is the ``input'' list we want to transform; on the left is the | |
| 1006 | ``map'' function for how to transform each element in the input list | |
| 1007 | (the square function in this case); at the bottom is the result list of | |
| 277 | 1008 | the map. This means that a map generates a \emph{new} list, unlike a
 | 
| 273 | 1009 | for-loop in Java or C/C++ which would most likely just update the | 
| 277 | 1010 | existing list/array. | 
| 272 | 1011 | |
| 277 | 1012 | Now there are two ways for expressing such maps in Scala. The first way is | 
| 272 | 1013 | called a \emph{for-comprehension}. The keywords are \code{for} and
 | 
| 1014 | \code{yield}. Squaring the numbers from 1 to 8 with a for-comprehension
 | |
| 123 | 1015 | would look as follows: | 
| 1016 | ||
| 1017 | \begin{lstlisting}[numbers=none]
 | |
| 1018 | scala> for (n <- (1 to 8).toList) yield n * n | |
| 467 | 1019 | val res2: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) | 
| 123 | 1020 | \end{lstlisting}
 | 
| 1021 | ||
| 272 | 1022 | \noindent This for-comprehension states that from the list of numbers | 
| 277 | 1023 | we draw some elements. We use the name \code{n} to range over these
 | 
| 1024 | elements (whereby the name is arbitrary; we could use something more | |
| 1025 | descriptive if we wanted to). Using \code{n} we compute the result of
 | |
| 1026 | \code{n * n} after the \code{yield}. This way of writing a map resembles
 | |
| 1027 | a bit the for-loops from imperative languages, even though the ideas | |
| 1028 | behind for-loops and for-comprehensions are quite different. Also, this | |
| 1029 | is a simple example---what comes after \code{yield} can be a complex
 | |
| 1030 | expression enclosed in \texttt{\{...\}}. A more complicated example
 | |
| 1031 | might be | |
| 272 | 1032 | |
| 1033 | \begin{lstlisting}[numbers=none]
 | |
| 1034 | scala> for (n <- (1 to 8).toList) yield {
 | |
| 1035 | val i = n + 1 | |
| 1036 | val j = n - 1 | |
| 273 | 1037 | i * j + 1 | 
| 272 | 1038 | } | 
| 467 | 1039 | val res3: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) | 
| 272 | 1040 | \end{lstlisting}
 | 
| 1041 | ||
| 467 | 1042 | Let us come back to the simple example of squaring a list of numbers. | 
| 1043 | As you can see in the for-comprehensions above, we specified the list | |
| 1044 | where each \code{n} comes from, namely \code{(1 to 8).toList}, and how
 | |
| 1045 | each element needs to be transformed, the expression after the | |
| 1046 | \code{yield}. This can also be expressed in a second way in Scala by
 | |
| 1047 | using directly the function \code{map} as follows:
 | |
| 123 | 1048 | |
| 467 | 1049 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 123 | 1050 | scala> (1 to 8).toList.map(n => n * n) | 
| 467 | 1051 | val res3 = List(1, 4, 9, 16, 25, 36, 49, 64) | 
| 123 | 1052 | \end{lstlisting}
 | 
| 1053 | ||
| 272 | 1054 | \noindent In this way, the expression \code{n => n * n} stands for the
 | 
| 1055 | function that calculates the square (this is how the \code{n}s are
 | |
| 1056 | transformed by the map). It might not be obvious, but | |
| 277 | 1057 | the for-comprehensions above are just syntactic sugar: when compiling such | 
| 273 | 1058 | code, Scala translates for-comprehensions into equivalent maps. This | 
| 1059 | even works when for-comprehensions get more complicated (see below). | |
| 123 | 1060 | |
| 1061 | The very charming feature of Scala is that such maps or | |
| 272 | 1062 | for-comprehensions can be written for any kind of data collection, such | 
| 1063 | as lists, sets, vectors, options and so on. For example if we instead | |
| 1064 | compute the remainders modulo 3 of this list, we can write | |
| 123 | 1065 | |
| 467 | 1066 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 123 | 1067 | scala> (1 to 8).toList.map(n => n % 3) | 
| 467 | 1068 | val res4 = List(1, 2, 0, 1, 2, 0, 1, 2) | 
| 123 | 1069 | \end{lstlisting}
 | 
| 1070 | ||
| 1071 | \noindent If we, however, transform the numbers 1 to 8 not | |
| 270 
38e13601cb1b
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
269diff
changeset | 1072 | into a list, but into a set, and then compute the remainders | 
| 123 | 1073 | modulo 3 we obtain | 
| 1074 | ||
| 467 | 1075 | \begin{lstlisting}[numbers=none,language={}]
 | 
| 1076 | scala> (1 to 8).toSet.map(n => n % 3) | |
| 1077 | val res5 = Set(2, 1, 0) | |
| 123 | 1078 | \end{lstlisting}
 | 
| 1079 | ||
| 467 | 1080 | \noindent This\footnote{This returns actually \code{HashSet(1, 2, 3)},
 | 
| 301 | 1081 | but this is just an implementation detail of how sets are implemented in | 
| 1082 | Scala.} is the correct result for sets, as there are only three | |
| 467 | 1083 | equivalence classes of integers modulo 3. Since maps and | 
| 301 | 1084 | for-comprehensions are just syntactic variants of each other, the latter | 
| 1085 | can also be written as | |
| 123 | 1086 | |
| 1087 | \begin{lstlisting}[numbers=none]
 | |
| 467 | 1088 | scala> for (n <- (1 to 8).toSet) yield n % 3 | 
| 1089 | val res5 = Set(2, 1, 0) | |
| 123 | 1090 | \end{lstlisting}
 | 
| 1091 | ||
| 1092 | For-comprehensions can also be nested and the selection of | |
| 467 | 1093 | elements can be guarded (or filtered). For example if we want to pair up | 
| 123 | 1094 | the numbers 1 to 4 with the letters a to c, we can write | 
| 1095 | ||
| 1096 | \begin{lstlisting}[numbers=none]
 | |
| 1097 | scala> for (n <- (1 to 4).toList; | |
| 1098 |             m <- ('a' to 'c').toList) yield (n, m)
 | |
| 467 | 1099 | val res6 = List((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), | 
| 1100 | (3,a), (3,b), (3,c), (4,a), (4,b), (4,c)) | |
| 123 | 1101 | \end{lstlisting}
 | 
| 1102 | ||
| 1103 | \noindent | |
| 272 | 1104 | In this example the for-comprehension ranges over two lists, and | 
| 277 | 1105 | produces a list of pairs as output. Or, if we want to find all pairs of | 
| 272 | 1106 | numbers between 1 and 3 where the sum is an even number, we can write | 
| 123 | 1107 | |
| 1108 | \begin{lstlisting}[numbers=none]
 | |
| 1109 | scala> for (n <- (1 to 3).toList; | |
| 1110 | m <- (1 to 3).toList; | |
| 1111 | if (n + m) % 2 == 0) yield (n, m) | |
| 467 | 1112 | val res7 = List((1,1), (1,3), (2,2), (3,1), (3,3)) | 
| 123 | 1113 | \end{lstlisting}
 | 
| 1114 | ||
| 272 | 1115 | \noindent The \code{if}-condition in this for-comprehension filters out
 | 
| 277 | 1116 | all pairs where the sum is not even (therefore \code{(1, 2)}, \code{(2,
 | 
| 1117 | 1)} and \code{(3, 2)} are not in the result because their sum is odd). 
 | |
| 272 | 1118 | |
| 278 | 1119 | To summarise, maps (or for-comprehensions) transform one collection into | 
| 273 | 1120 | another. For example a list of \code{Int}s into a list of squares, and
 | 
| 1121 | so on. There is no need for for-loops in Scala. But please do not be | |
| 1122 | tempted to write anything like | |
| 272 | 1123 | |
| 1124 | \begin{lstlisting}[numbers=none]
 | |
| 1125 | scala> val cs = ('a' to 'h').toList
 | |
| 1126 | scala> for (n <- (0 until cs.length).toList) | |
| 1127 | yield cs(n).capitalize | |
| 467 | 1128 | val res8: List[Char] = List(A, B, C, D, E, F, G, H) | 
| 272 | 1129 | \end{lstlisting}
 | 
| 1130 | ||
| 1131 | \noindent | |
| 277 | 1132 | This is accepted Scala-code, but utterly bad style (it is more like | 
| 1133 | Java). It can be written much clearer as: | |
| 272 | 1134 | |
| 1135 | \begin{lstlisting}[numbers=none]
 | |
| 1136 | scala> val cs = ('a' to 'h').toList
 | |
| 1137 | scala> for (c <- cs) yield c.capitalize | |
| 467 | 1138 | val res9: List[Char] = List(A, B, C, D, E, F, G, H) | 
| 272 | 1139 | \end{lstlisting}
 | 
| 123 | 1140 | |
| 271 | 1141 | \subsection*{Results and Side-Effects}
 | 
| 1142 | ||
| 301 | 1143 | While hopefully all this about maps looks reasonable, there is one | 
| 273 | 1144 | complication: In the examples above we always wanted to transform one | 
| 1145 | list into another list (e.g.~list of squares), or one set into another | |
| 1146 | set (set of numbers into set of remainders modulo 3). What happens if we | |
| 1147 | just want to print out a list of integers? In these cases the | |
| 1148 | for-comprehensions need to be modified. The reason is that \code{print},
 | |
| 1149 | you guessed it, does not produce any result, but only produces what is | |
| 1150 | in the functional-programming-lingo called a \emph{side-effect}\ldots it
 | |
| 1151 | prints something out on the screen. Printing out the list of numbers | |
| 1152 | from 1 to 5 would look as follows | |
| 123 | 1153 | |
| 1154 | \begin{lstlisting}[numbers=none]
 | |
| 1155 | scala> for (n <- (1 to 5).toList) print(n) | |
| 1156 | 12345 | |
| 1157 | \end{lstlisting}
 | |
| 1158 | ||
| 1159 | \noindent | |
| 1160 | where you need to omit the keyword \code{yield}. You can
 | |
| 467 | 1161 | also do more elaborate calculations before printingh such as | 
| 123 | 1162 | |
| 1163 | \begin{lstlisting}[numbers=none]
 | |
| 1164 | scala> for (n <- (1 to 5).toList) {
 | |
| 197 | 1165 | val square = n * n | 
| 1166 | println(s"$n * $n = $square") | |
| 123 | 1167 | } | 
| 1168 | 1 * 1 = 1 | |
| 1169 | 2 * 2 = 4 | |
| 1170 | 3 * 3 = 9 | |
| 1171 | 4 * 4 = 16 | |
| 1172 | 5 * 5 = 25 | |
| 1173 | \end{lstlisting}%$
 | |
| 1174 | ||
| 301 | 1175 | \noindent In this code I use a value assignment (\code{val
 | 
| 197 | 1176 | square = ...} ) and also what is called in Scala a | 
| 123 | 1177 | \emph{string interpolation}, written \code{s"..."}. The latter
 | 
| 467 | 1178 | is for printing out formatted strings. It allows me to refer to the | 
| 270 
38e13601cb1b
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
269diff
changeset | 1179 | integer values \code{n} and \code{square} inside a string.
 | 
| 123 | 1180 | This is very convenient for printing out ``things''. | 
| 1181 | ||
| 1182 | The corresponding map construction for functions with | |
| 1183 | side-effects is in Scala called \code{foreach}. So you 
 | |
| 1184 | could also write | |
| 1185 | ||
| 1186 | ||
| 1187 | \begin{lstlisting}[numbers=none]
 | |
| 1188 | scala> (1 to 5).toList.foreach(n => print(n)) | |
| 1189 | 12345 | |
| 1190 | \end{lstlisting}
 | |
| 1191 | ||
| 1192 | ||
| 1193 | \noindent or even just | |
| 1194 | ||
| 1195 | \begin{lstlisting}[numbers=none]
 | |
| 1196 | scala> (1 to 5).toList.foreach(print) | |
| 1197 | 12345 | |
| 1198 | \end{lstlisting}
 | |
| 1199 | ||
| 273 | 1200 | \noindent | 
| 123 | 1201 | If you want to find out more about maps and functions with | 
| 1202 | side-effects, you can ponder about the response Scala gives if | |
| 1203 | you replace \code{foreach} by \code{map} in the expression
 | |
| 1204 | above. Scala will still allow \code{map} with side-effect
 | |
| 1205 | functions, but then reacts with a slightly interesting result. | |
| 1206 | ||
| 273 | 1207 | \subsection*{Aggregates}
 | 
| 1208 | ||
| 1209 | There is one more usage of for-loops in Java, C/C++ and the like: | |
| 1210 | sometimes you want to \emph{aggregate} something about a list, for
 | |
| 278 | 1211 | example summing up all its elements. In this case you cannot use maps, | 
| 273 | 1212 | because maps \emph{transform} one data collection into another data
 | 
| 1213 | collection. They cannot be used to generate a single integer | |
| 278 | 1214 | representing an aggregate. So how is this kind of aggregation done in | 
| 1215 | Scala? Let us suppose you want to sum up all elements from a list. You | |
| 1216 | might be tempted to write something like | |
| 273 | 1217 | |
| 1218 | \begin{lstlisting}[numbers=none]
 | |
| 1219 | var cnt = 0 | |
| 1220 | for (n <- (1 to 8).toList) {
 | |
| 1221 | cnt += n | |
| 1222 | } | |
| 1223 | print(cnt) | |
| 1224 | \end{lstlisting}
 | |
| 1225 | ||
| 1226 | \noindent | |
| 277 | 1227 | and indeed this is accepted Scala code and produces the expected result, | 
| 273 | 1228 | namely \code{36}, \textbf{BUT} this is imperative style and not
 | 
| 301 | 1229 | permitted in PEP. If you submit this kind of code, you get 0 marks. The | 
| 1230 | code uses a \code{var} and therefore violates the immutability property
 | |
| 1231 | I ask for in your code. Sorry! | |
| 273 | 1232 | |
| 1233 | So how to do that same thing without using a \code{var}? Well there are
 | |
| 1234 | several ways. One way is to define the following recursive | |
| 1235 | \code{sum}-function:
 | |
| 1236 | ||
| 1237 | \begin{lstlisting}[numbers=none]
 | |
| 1238 | def sum(xs: List[Int]) : Int = | |
| 1239 | if (xs.isEmpty) 0 else xs.head + sum(xs.tail) | |
| 1240 | \end{lstlisting}  
 | |
| 1241 | ||
| 1242 | \noindent | |
| 1243 | You can then call \code{sum((1 to 8).toList)} and obtain the same result
 | |
| 278 | 1244 | without a mutable variable and without a for-loop. Obviously for simple things like | 
| 277 | 1245 | sum, you could have written \code{xs.sum} in the first place. But not
 | 
| 1246 | all aggregate functions are pre-defined and often you have to write your | |
| 1247 | own recursive function for this. | |
| 273 | 1248 | |
| 352 | 1249 | %\subsection*{Always Produce a Result! No Exceptions!}
 | 
| 329 | 1250 | % | 
| 1251 | %Function should always produce a value. Exception is not thrown. | |
| 1252 | %Whenever there is a possibility of non-value result (exception, void, | |
| 1253 | %undefined, null, etc.), it should be incorporated in the result type. | |
| 1254 | %Such types include but not limited to | |
| 1255 | % | |
| 1256 | %Option[T] | |
| 1257 | ||
| 352 | 1258 | %TBD | 
| 334 | 1259 | |
| 329 | 1260 | |
| 271 | 1261 | \subsection*{Higher-Order Functions}
 | 
| 1262 | ||
| 301 | 1263 | Functions obviously play a central role in functional programming. Two simple | 
| 1264 | examples are | |
| 1265 | ||
| 1266 | \begin{lstlisting}[numbers=none]
 | |
| 1267 | def even(x: Int) : Boolean = x % 2 == 0 | |
| 1268 | def odd(x: Int) : Boolean = x % 2 == 1 | |
| 1269 | \end{lstlisting} 
 | |
| 1270 | ||
| 1271 | \noindent | |
| 1272 | More interestingly, the concept of functions is really pushed to the | |
| 1273 | limit in functional programming. Functions can take other functions as | |
| 1274 | arguments and can return a function as a result. This is actually | |
| 1275 | quite important for making code generic. Assume a list of 10 elements: | |
| 1276 | ||
| 1277 | \begin{lstlisting}[numbers=none]
 | |
| 1278 | val lst = (1 to 10).toList | |
| 1279 | \end{lstlisting} 
 | |
| 1280 | ||
| 1281 | \noindent | |
| 1282 | Say, we want to filter out all even numbers. For this we can use | |
| 1283 | ||
| 1284 | \begin{lstlisting}[numbers=none]
 | |
| 1285 | scala> lst.filter(even) | |
| 1286 | List(2, 4, 6, 8, 10) | |
| 1287 | \end{lstlisting} 
 | |
| 1288 | ||
| 1289 | \noindent | |
| 1290 | where \code{filter} expects a function as argument specifying which
 | |
| 1291 | elements of the list should be kept and which should be left out. By | |
| 1292 | allowing \code{filter} to take a function as argument, we can also
 | |
| 1293 | easily filter out odd numbers as well. | |
| 1294 | ||
| 1295 | \begin{lstlisting}[numbers=none]
 | |
| 1296 | scala> lst.filter(odd) | |
| 1297 | List(1, 3, 5, 7, 9) | |
| 1298 | \end{lstlisting} 
 | |
| 1299 | ||
| 1300 | \noindent | |
| 1301 | Such function arguments are quite frequently used for ``generic'' functions. | |
| 1302 | For example it is easy to count odd elements in a list or find the first | |
| 1303 | even number in a list: | |
| 1304 | ||
| 1305 | \begin{lstlisting}[numbers=none]
 | |
| 1306 | scala> lst.count(odd) | |
| 1307 | 5 | |
| 1308 | scala> lst.find(even) | |
| 1309 | Some(2) | |
| 1310 | \end{lstlisting} 
 | |
| 1311 | ||
| 1312 | \noindent | |
| 1313 | Recall that the return type of \code{even} and \code{odd} are booleans.
 | |
| 1314 | Such function are sometimes called predicates, because they determine | |
| 1315 | what should be true for an element and what false, and then performing | |
| 1316 | some operation according to this boolean. Such predicates are quite useful. | |
| 1317 | Say you want to sort the \code{lst}-list in ascending and descending order. 
 | |
| 1318 | For this you can write | |
| 1319 | ||
| 1320 | \begin{lstlisting}[numbers=none]
 | |
| 1321 | lst.sortWith(_ < _) | |
| 1322 | lst.sortWith(_ > _) | |
| 1323 | \end{lstlisting} 
 | |
| 1324 | ||
| 1325 | \noindent where \code{sortWith} expects a predicate as argument. The
 | |
| 1326 | construction \code{_ < _} stands for a function that takes two arguments
 | |
| 1327 | and returns true when the first one is smaller than the second. You can | |
| 1328 | think of this as elegant shorthand notation for | |
| 1329 | ||
| 1330 | \begin{lstlisting}[numbers=none]
 | |
| 1331 | def smaller(x: Int, y: Int) : Boolean = x < y | |
| 1332 | lst.sortWith(smaller) | |
| 1333 | \end{lstlisting} 
 | |
| 1334 | ||
| 1335 | \noindent | |
| 1336 | Say you want to find in \code{lst} the first odd number greater than 2.
 | |
| 1337 | For this you need to write a function that specifies exactly this | |
| 1338 | condition. To do this you can use a slight variant of the shorthand | |
| 1339 | notation above | |
| 1340 | ||
| 1341 | \begin{lstlisting}[numbers=none]
 | |
| 1342 | scala> lst.find(n => odd(n) && n > 2) | |
| 1343 | Some(3) | |
| 1344 | \end{lstlisting} 
 | |
| 1345 | ||
| 1346 | \noindent | |
| 1347 | Here \code{n => ...} specifies a function that takes \code{n} as
 | |
| 1348 | argument and uses this argument in whatever comes after the double | |
| 1349 | arrow. If you want to use this mechanism for looking for an element that | |
| 1350 | is both even and odd, then of course you out of luck. | |
| 1351 | ||
| 1352 | \begin{lstlisting}[numbers=none]
 | |
| 1353 | scala> lst.find(n => odd(n) && even(n)) | |
| 1354 | None | |
| 1355 | \end{lstlisting} 
 | |
| 1356 | ||
| 1357 | While functions taking functions as arguments seems a rather useful | |
| 1358 | feature, the utility of returning a function might not be so clear. | |
| 1359 | I admit the following example is a bit contrived, but believe me | |
| 1360 | sometims functions produce other functions in a very meaningful way. | |
| 1361 | Say we want to generate functions according to strings, as in | |
| 1362 | ||
| 1363 | \begin{lstlisting}[numbers=none]
 | |
| 1364 | def mkfn(s: String) : (Int => Boolean) = | |
| 1365 | if (s == "even") even else odd | |
| 1366 | \end{lstlisting}
 | |
| 1367 | ||
| 1368 | \noindent | |
| 1369 | With this we can generate the required function for \code{filter}
 | |
| 1370 | according to a string: | |
| 1371 | ||
| 1372 | \begin{lstlisting}[numbers=none]
 | |
| 1373 | scala> lst.filter(mkfn("even"))
 | |
| 1374 | List(2, 4, 6, 8, 10) | |
| 1375 | scala> lst.filter(mkfn("foo"))
 | |
| 1376 | List(1, 3, 5, 7, 9) | |
| 1377 | \end{lstlisting}
 | |
| 1378 | ||
| 1379 | \noindent | |
| 1380 | As said, this is example is a bit contrived---I was not able to think | |
| 1381 | of anything simple, but for example in the Compiler module next year I | |
| 1382 | show a compilation functions that needs to generate functions as | |
| 1383 | intermediate result. Anyway, notice the interesting type we had to | |
| 467 | 1384 | annotate to \code{mkfn}. The types in Scala are described next.
 | 
| 301 | 1385 | |
| 274 | 1386 | |
| 123 | 1387 | \subsection*{Types}
 | 
| 1388 | ||
| 1389 | In most functional programming languages, types play an | |
| 467 | 1390 | essential role. Scala is such a language. You have already | 
| 123 | 1391 | seen built-in types, like \code{Int}, \code{Boolean},
 | 
| 1392 | \code{String} and \code{BigInt}, but also user-defined ones,
 | |
| 195 | 1393 | like \code{Rexp} (see coursework). Unfortunately, types can be a thorny
 | 
| 123 | 1394 | subject, especially in Scala. For example, why do we need to | 
| 1395 | give the type to \code{toSet[Int]}, but not to \code{toList}?
 | |
| 1396 | The reason is the power of Scala, which sometimes means it | |
| 1397 | cannot infer all necessary typing information. At the | |
| 195 | 1398 | beginning, while getting familiar with Scala, I recommend a | 
| 123 | 1399 | ``play-it-by-ear-approach'' to types. Fully understanding | 
| 1400 | type-systems, especially complicated ones like in Scala, can | |
| 1401 | take a module on their own.\footnote{Still, such a study can
 | |
| 1402 | be a rewarding training: If you are in the business of | |
| 1403 | designing new programming languages, you will not be able to | |
| 1404 | turn a blind eye to types. They essentially help programmers | |
| 1405 | to avoid common programming errors and help with maintaining | |
| 1406 | code.} | |
| 1407 | ||
| 1408 | In Scala, types are needed whenever you define an inductive | |
| 1409 | datatype and also whenever you define functions (their | |
| 1410 | arguments and their results need a type). Base types are types | |
| 1411 | that do not take any (type)arguments, for example \code{Int}
 | |
| 1412 | and \code{String}. Compound types take one or more arguments,
 | |
| 1413 | which as seen earlier need to be given in angle-brackets, for | |
| 1414 | example \code{List[Int]} or \code{Set[List[String]]} or 
 | |
| 1415 | \code{Map[Int, Int]}.
 | |
| 1416 | ||
| 467 | 1417 | Scala provides a basic mechanism to check the type of a (closed) | 
| 1418 | expression---closed means that all parts are already known to Scala. | |
| 1419 | Then you can use the command \code{:type} and check in the REPL:
 | |
| 1420 | ||
| 1421 | \begin{lstlisting}[ numbers=none]
 | |
| 1422 | scala> :type (1, List(3), Set(4,5), "hello") | |
| 1423 | (Int, List[Int], Set[Int], String) | |
| 1424 | \end{lstlisting}
 | |
| 1425 | ||
| 1426 | \noindent | |
| 1427 | If Scala can calculate the type of the given expression, then it | |
| 1428 | will print it. Unfortunately, this way of finding out a type is almost | |
| 1429 | unusable: for `things' where the type is pretty obvious, it gives an | |
| 1430 | answer; but for `things' that are actually of interest (such as | |
| 1431 | what is the type of a pre-defined function), it gives up with | |
| 1432 | an error message. | |
| 1433 | ||
| 123 | 1434 | There are a few special type-constructors that fall outside | 
| 1435 | this pattern. One is for tuples, where the type is written | |
| 1436 | with parentheses. For example | |
| 1437 | ||
| 1438 | \begin{lstlisting}[ numbers=none]
 | |
| 1439 | (Int, Int, String) | |
| 1440 | \end{lstlisting}
 | |
| 1441 | ||
| 1442 | \noindent is for a triple (a tuple with three components---two | |
| 1443 | integers and a string). Tuples are helpful if you want to | |
| 1444 | define functions with multiple results, say the function | |
| 270 
38e13601cb1b
updated
 Christian Urban <christian dot urban at kcl dot ac dot uk> parents: 
269diff
changeset | 1445 | returning the quotient and remainder of two numbers. For this | 
| 123 | 1446 | you might define: | 
| 1447 | ||
| 1448 | ||
| 1449 | \begin{lstlisting}[ numbers=none]
 | |
| 301 | 1450 | def quo_rem(m: Int, n: Int) : (Int, Int) = | 
| 1451 | (m / n, m % n) | |
| 123 | 1452 | \end{lstlisting}
 | 
| 1453 | ||
| 1454 | \noindent Since this function returns a pair of integers, its | |
| 277 | 1455 | \emph{return type} needs to be of type \code{(Int, Int)}. Incidentally,
 | 
| 1456 | this is also the \emph{input type} of this function. For this notice
 | |
| 1457 | \code{quo_rem} takes \emph{two} arguments, namely \code{m} and \code{n},
 | |
| 1458 | both of which are integers. They are ``packaged'' in a pair. | |
| 1459 | Consequently the complete type of \code{quo_rem} is
 | |
| 123 | 1460 | |
| 1461 | \begin{lstlisting}[ numbers=none]
 | |
| 1462 | (Int, Int) => (Int, Int) | |
| 1463 | \end{lstlisting}
 | |
| 1464 | ||
| 301 | 1465 | \noindent | 
| 277 | 1466 | This uses another special type-constructor, written as the arrow | 
| 301 | 1467 | \code{=>}. This is sometimes also called \emph{function arrow}.  For
 | 
| 1468 | example, the type \code{Int => String} is for a function that takes an
 | |
| 1469 | integer as input argument and produces a string as result. A function | |
| 1470 | of this type is for instance | |
| 123 | 1471 | |
| 1472 | \begin{lstlisting}[numbers=none]
 | |
| 1473 | def mk_string(n: Int) : String = n match {
 | |
| 1474 | case 0 => "zero" | |
| 1475 | case 1 => "one" | |
| 1476 | case 2 => "two" | |
| 1477 | case _ => "many" | |
| 1478 | } | |
| 1479 | \end{lstlisting}
 | |
| 1480 | ||
| 1481 | \noindent It takes an integer as input argument and returns a | |
| 301 | 1482 | string. The type of the function generated in \code{mkfn} above, is
 | 
| 1483 | \code{Int => Boolean}.
 | |
| 277 | 1484 | |
| 1485 | Unfortunately, unlike other functional programming languages, there is | |
| 1486 | in Scala no easy way to find out the types of existing functions, except | |
| 1487 | by looking into the documentation | |
| 123 | 1488 | |
| 1489 | \begin{quote}
 | |
| 468 | 1490 | \url{https://dotty.epfl.ch/api/index.html}
 | 
| 123 | 1491 | \end{quote}
 | 
| 1492 | ||
| 1493 | The function arrow can also be iterated, as in | |
| 1494 | \code{Int => String => Boolean}. This is the type for a function
 | |
| 1495 | taking an integer as first argument and a string as second, | |
| 1496 | and the result of the function is a boolean. Though silly, a | |
| 1497 | function of this type would be | |
| 1498 | ||
| 1499 | ||
| 1500 | \begin{lstlisting}[numbers=none]
 | |
| 1501 | def chk_string(n: Int)(s: String) : Boolean = | |
| 1502 | mk_string(n) == s | |
| 1503 | \end{lstlisting}
 | |
| 1504 | ||
| 1505 | ||
| 1506 | \noindent which checks whether the integer \code{n}
 | |
| 1507 | corresponds to the name \code{s} given by the function
 | |
| 1508 | \code{mk\_string}. Notice the unusual way of specifying the
 | |
| 1509 | arguments of this function: the arguments are given one after | |
| 1510 | the other, instead of being in a pair (what would be the type | |
| 1511 | of this function then?). This way of specifying the arguments | |
| 1512 | can be useful, for example in situations like this | |
| 1513 | ||
| 1514 | \begin{lstlisting}[numbers=none]
 | |
| 1515 | scala> List("one", "two", "three", "many").map(chk_string(2))
 | |
| 1516 | res4 = List(false, true, false, false) | |
| 1517 | ||
| 1518 | scala> List("one", "two", "three", "many").map(chk_string(3))
 | |
| 1519 | res5 = List(false, false, false, true) | |
| 1520 | \end{lstlisting}
 | |
| 1521 | ||
| 1522 | \noindent In each case we can give to \code{map} a specialised
 | |
| 1523 | version of \code{chk_string}---once specialised to 2 and once
 | |
| 1524 | to 3. This kind of ``specialising'' a function is called | |
| 1525 | \emph{partial application}---we have not yet given to this
 | |
| 1526 | function all arguments it needs, but only some of them. | |
| 1527 | ||
| 1528 | Coming back to the type \code{Int => String => Boolean}. The
 | |
| 1529 | rule about such function types is that the right-most type | |
| 1530 | specifies what the function returns (a boolean in this case). | |
| 1531 | The types before that specify how many arguments the function | |
| 1532 | expects and what their type is (in this case two arguments, | |
| 1533 | one of type \code{Int} and another of type \code{String}).
 | |
| 1534 | Given this rule, what kind of function has type | |
| 1535 | \mbox{\code{(Int => String) => Boolean}}? Well, it returns a
 | |
| 1536 | boolean. More interestingly, though, it only takes a single | |
| 1537 | argument (because of the parentheses). The single argument | |
| 1538 | happens to be another function (taking an integer as input and | |
| 1539 | returning a string). Remember that \code{mk_string} is just 
 | |
| 1540 | such a function. So how can we use it? For this define | |
| 1541 | the somewhat silly function \code{apply_3}:
 | |
| 1542 | ||
| 1543 | \begin{lstlisting}[numbers=none]
 | |
| 1544 | def apply_3(f: Int => String): Bool = f(3) == "many" | |
| 1545 | ||
| 1546 | scala> apply_3(mk_string) | |
| 1547 | res6 = true | |
| 1548 | \end{lstlisting}
 | |
| 1549 | ||
| 1550 | You might ask: Apart from silly functions like above, what is | |
| 1551 | the point of having functions as input arguments to other | |
| 467 | 1552 | functions? | 
| 1553 | %In Java there is indeed no need of this kind of | |
| 1554 | %feature: at least in the past it did not allow such | |
| 1555 | %constructions. I think, the point of Java 8 and successors was to lift this | |
| 1556 | %restriction. | |
| 1557 | Well, in all functional programming languages, | |
| 123 | 1558 | including Scala, it is really essential to allow functions as | 
| 301 | 1559 | input argument. Above you have already seen \code{map} and
 | 
| 1560 | \code{foreach} which need this feature. Consider the functions
 | |
| 123 | 1561 | \code{print} and \code{println}, which both print out strings,
 | 
| 1562 | but the latter adds a line break. You can call \code{foreach}
 | |
| 1563 | with either of them and thus changing how, for example, five | |
| 1564 | numbers are printed. | |
| 1565 | ||
| 1566 | ||
| 1567 | \begin{lstlisting}[numbers=none]
 | |
| 1568 | scala> (1 to 5).toList.foreach(print) | |
| 1569 | 12345 | |
| 1570 | scala> (1 to 5).toList.foreach(println) | |
| 1571 | 1 | |
| 1572 | 2 | |
| 1573 | 3 | |
| 1574 | 4 | |
| 1575 | 5 | |
| 1576 | \end{lstlisting}
 | |
| 1577 | ||
| 1578 | ||
| 1579 | \noindent This is actually one of the main design principles | |
| 1580 | in functional programming. You have generic functions like | |
| 1581 | \code{map} and \code{foreach} that can traverse data containers,
 | |
| 1582 | like lists or sets. They then take a function to specify what | |
| 1583 | should be done with each element during the traversal. This | |
| 1584 | requires that the generic traversal functions can cope with | |
| 1585 | any kind of function (not just functions that, for example, | |
| 1586 | take as input an integer and produce a string like above). | |
| 1587 | This means we cannot fix the type of the generic traversal | |
| 1588 | functions, but have to keep them | |
| 181 | 1589 | \emph{polymorphic}.\footnote{Another interesting topic about
 | 
| 123 | 1590 | types, but we omit it here for the sake of brevity.} | 
| 1591 | ||
| 301 | 1592 | There is one more type constructor that is rather special. It is | 
| 1593 | called \code{Unit}. Recall that \code{Boolean} has two values, namely
 | |
| 1594 | \code{true} and \code{false}. This can be used, for example, to test
 | |
| 1595 | something and decide whether the test succeeds or not. In contrast the | |
| 1596 | type \code{Unit} has only a single value, written \code{()}. This
 | |
| 1597 | seems like a completely useless type and return value for a function, | |
| 1598 | but is actually quite useful. It indicates when the function does not | |
| 1599 | return any result. The purpose of these functions is to cause | |
| 1600 | something being written on the screen or written into a file, for | |
| 1601 | example. This is what is called they cause a \emph{side-effect}, for
 | |
| 1602 | example new content displayed on the screen or some new data in a | |
| 1603 | file. Scala uses the \code{Unit} type to indicate that a function does
 | |
| 1604 | not have a result, but potentially causes a side-effect. Typical | |
| 1605 | examples are the printing functions, like \code{print}.
 | |
| 123 | 1606 | |
| 301 | 1607 | |
| 1608 | %%\subsection*{User-Defined Types}
 | |
| 123 | 1609 | |
| 143 | 1610 | % \subsection*{Cool Stuff}
 | 
| 123 | 1611 | |
| 143 | 1612 | % The first wow-moment I had with Scala was when I came across | 
| 1613 | % the following code-snippet for reading a web-page. | |
| 123 | 1614 | |
| 1615 | ||
| 143 | 1616 | % \begin{lstlisting}[ numbers=none]
 | 
| 1617 | % import io.Source | |
| 1618 | % val url = """http://www.inf.kcl.ac.uk/staff/urbanc/""" | |
| 1619 | % Source.fromURL(url)("ISO-8859-1").take(10000).mkString
 | |
| 1620 | % \end{lstlisting}
 | |
| 123 | 1621 | |
| 1622 | ||
| 143 | 1623 | % \noindent These three lines return a string containing the | 
| 1624 | % HTML-code of my webpage. It actually already does something | |
| 1625 | % more sophisticated, namely only returns the first 10000 | |
| 1626 | % characters of a webpage in case it is too large. Why is that | |
| 1627 | % code-snippet of any interest? Well, try implementing | |
| 1628 | % reading-from-a-webpage in Java. I also like the possibility of | |
| 1629 | % triple-quoting strings, which I have only seen in Scala so | |
| 1630 | % far. The idea behind this is that in such a string all | |
| 1631 | % characters are interpreted literally---there are no escaped | |
| 1632 | % characters, like \verb|\n| for newlines. | |
| 123 | 1633 | |
| 143 | 1634 | % My second wow-moment I had with a feature of Scala that other | 
| 1635 | % functional programming languages do not have. This feature is | |
| 1636 | % about implicit type conversions. If you have regular | |
| 1637 | % expressions and want to use them for language processing you | |
| 1638 | % often want to recognise keywords in a language, for example | |
| 1639 | % \code{for},{} \code{if},{} \code{yield} and so on. But the
 | |
| 1640 | % basic regular expression \code{CHAR} can only recognise a
 | |
| 1641 | % single character. In order to recognise a whole string, like | |
| 1642 | % \code{for}, you have to put many of those together using
 | |
| 1643 | % \code{SEQ}:
 | |
| 123 | 1644 | |
| 1645 | ||
| 143 | 1646 | % \begin{lstlisting}[numbers=none]
 | 
| 1647 | % SEQ(CHAR('f'), SEQ(CHAR('o'), CHAR('r')))
 | |
| 1648 | % \end{lstlisting}
 | |
| 123 | 1649 | |
| 143 | 1650 | % \noindent This gets quickly unreadable when the strings and | 
| 1651 | % regular expressions get more complicated. In other functional | |
| 1652 | % programming languages, you can explicitly write a conversion | |
| 1653 | % function that takes a string, say \dq{\pcode{for}}, and
 | |
| 1654 | % generates the regular expression above. But then your code is | |
| 1655 | % littered with such conversion functions. | |
| 123 | 1656 | |
| 143 | 1657 | % In Scala you can do better by ``hiding'' the conversion | 
| 1658 | % functions. The keyword for doing this is \code{implicit} and
 | |
| 1659 | % it needs a built-in library called | |
| 123 | 1660 | |
| 143 | 1661 | % \begin{lstlisting}[numbers=none]
 | 
| 1662 | % scala.language.implicitConversions | |
| 1663 | % \end{lstlisting}
 | |
| 123 | 1664 | |
| 143 | 1665 | % \noindent | 
| 1666 | % Consider the code | |
| 123 | 1667 | |
| 1668 | ||
| 143 | 1669 | % \begin{lstlisting}[language=Scala]
 | 
| 1670 | % import scala.language.implicitConversions | |
| 123 | 1671 | |
| 143 | 1672 | % def charlist2rexp(s: List[Char]) : Rexp = s match {
 | 
| 1673 | % case Nil => EMPTY | |
| 1674 | % case c::Nil => CHAR(c) | |
| 1675 | % case c::s => SEQ(CHAR(c), charlist2rexp(s)) | |
| 1676 | % } | |
| 123 | 1677 | |
| 143 | 1678 | % implicit def string2rexp(s: String) : Rexp = | 
| 1679 | % charlist2rexp(s.toList) | |
| 1680 | % \end{lstlisting}
 | |
| 123 | 1681 | |
| 1682 | ||
| 143 | 1683 | % \noindent where the first seven lines implement a function | 
| 1684 | % that given a list of characters generates the corresponding | |
| 1685 | % regular expression. In Lines 9 and 10, this function is used | |
| 1686 | % for transforming a string into a regular expression. Since the | |
| 1687 | % \code{string2rexp}-function is declared as \code{implicit},
 | |
| 1688 | % the effect will be that whenever Scala expects a regular | |
| 1689 | % expression, but I only give it a string, it will automatically | |
| 1690 | % insert a call to the \code{string2rexp}-function. I can now
 | |
| 1691 | % write for example | |
| 123 | 1692 | |
| 143 | 1693 | % \begin{lstlisting}[numbers=none]
 | 
| 1694 | % scala> ALT("ab", "ac")
 | |
| 1695 | % res9 = ALT(SEQ(CHAR(a),CHAR(b)),SEQ(CHAR(a),CHAR(c))) | |
| 1696 | % \end{lstlisting}
 | |
| 123 | 1697 | |
| 143 | 1698 | % \noindent Recall that \code{ALT} expects two regular
 | 
| 1699 | % expressions as arguments, but I only supply two strings. The | |
| 1700 | % implicit conversion function will transform the string into a | |
| 1701 | % regular expression. | |
| 123 | 1702 | |
| 143 | 1703 | % Using implicit definitions, Scala allows me to introduce | 
| 1704 | % some further syntactic sugar for regular expressions: | |
| 123 | 1705 | |
| 1706 | ||
| 143 | 1707 | % \begin{lstlisting}[ numbers=none]
 | 
| 1708 | % implicit def RexpOps(r: Rexp) = new {
 | |
| 1709 | % def | (s: Rexp) = ALT(r, s) | |
| 1710 | % def ~ (s: Rexp) = SEQ(r, s) | |
| 1711 | % def % = STAR(r) | |
| 1712 | % } | |
| 123 | 1713 | |
| 143 | 1714 | % implicit def stringOps(s: String) = new {
 | 
| 1715 | % def | (r: Rexp) = ALT(s, r) | |
| 1716 | % def | (r: String) = ALT(s, r) | |
| 1717 | % def ~ (r: Rexp) = SEQ(s, r) | |
| 1718 | % def ~ (r: String) = SEQ(s, r) | |
| 1719 | % def % = STAR(s) | |
| 1720 | % } | |
| 1721 | % \end{lstlisting}
 | |
| 123 | 1722 | |
| 1723 | ||
| 143 | 1724 | % \noindent This might seem a bit overly complicated, but its effect is | 
| 1725 | % that I can now write regular expressions such as $ab + ac$ | |
| 1726 | % simply as | |
| 123 | 1727 | |
| 1728 | ||
| 143 | 1729 | % \begin{lstlisting}[numbers=none]
 | 
| 1730 | % scala> "ab" | "ac" | |
| 1731 | % res10 = ALT(SEQ(CHAR(a),CHAR(b)),SEQ(CHAR(a),CHAR(c))) | |
| 1732 | % \end{lstlisting}
 | |
| 123 | 1733 | |
| 1734 | ||
| 143 | 1735 | % \noindent I leave you to figure out what the other | 
| 1736 | % syntactic sugar in the code above stands for. | |
| 123 | 1737 | |
| 143 | 1738 | % One more useful feature of Scala is the ability to define | 
| 1739 | % functions with varying argument lists. This is a feature that | |
| 1740 | % is already present in old languages, like C, but seems to have | |
| 1741 | % been forgotten in the meantime---Java does not have it. In the | |
| 1742 | % context of regular expressions this feature comes in handy: | |
| 1743 | % Say you are fed up with writing many alternatives as | |
| 123 | 1744 | |
| 1745 | ||
| 143 | 1746 | % \begin{lstlisting}[numbers=none]
 | 
| 1747 | % ALT(..., ALT(..., ALT(..., ...))) | |
| 1748 | % \end{lstlisting}
 | |
| 123 | 1749 | |
| 1750 | ||
| 143 | 1751 | % \noindent To make it difficult, you do not know how deep such | 
| 1752 | % alternatives are nested. So you need something flexible that | |
| 1753 | % can take as many alternatives as needed. In Scala one can | |
| 1754 | % achieve this by adding a \code{*} to the type of an argument.
 | |
| 1755 | % Consider the code | |
| 123 | 1756 | |
| 1757 | ||
| 143 | 1758 | % \begin{lstlisting}[language=Scala]
 | 
| 1759 | % def Alts(rs: List[Rexp]) : Rexp = rs match {
 | |
| 1760 | % case Nil => NULL | |
| 1761 | % case r::Nil => r | |
| 1762 | % case r::rs => ALT(r, Alts(rs)) | |
| 1763 | % } | |
| 123 | 1764 | |
| 143 | 1765 | % def ALTS(rs: Rexp*) = Alts(rs.toList) | 
| 1766 | % \end{lstlisting}
 | |
| 123 | 1767 | |
| 1768 | ||
| 143 | 1769 | % \noindent The function in Lines 1 to 5 takes a list of regular | 
| 1770 | % expressions and converts it into an appropriate alternative | |
| 1771 | % regular expression. In Line 7 there is a wrapper for this | |
| 1772 | % function which uses the feature of varying argument lists. The | |
| 1773 | % effect of this code is that I can write the regular | |
| 1774 | % expression for keywords as | |
| 123 | 1775 | |
| 1776 | ||
| 143 | 1777 | % \begin{lstlisting}[numbers=none]
 | 
| 1778 | % ALTS("for", "def", "yield", "implicit", "if", "match", "case")
 | |
| 1779 | % \end{lstlisting}
 | |
| 123 | 1780 | |
| 1781 | ||
| 143 | 1782 | % \noindent Again I leave it to you to find out how much this | 
| 1783 | % simplifies the regular expression in comparison with if I had | |
| 1784 | % to write this by hand using only the ``plain'' regular | |
| 1785 | % expressions from the inductive datatype. | |
| 1786 | ||
| 197 | 1787 | %\bigskip\noindent | 
| 1788 | %\textit{More TBD.}
 | |
| 123 | 1789 | |
| 197 | 1790 | %\subsection*{Coursework}
 | 
| 181 | 1791 | |
| 395 | 1792 | \begin{figure}[p]
 | 
| 1793 | \begin{boxedminipage}{\textwidth}  
 | |
| 1794 | \textbf{Scala Syntax for Java Developers}\bigskip
 | |
| 195 | 1795 | |
| 395 | 1796 | \noindent | 
| 343 | 1797 | Scala compiles to the JVM, like the Java language. Because of this, | 
| 352 | 1798 | it can re-use many libraries. Here are a few hints how some Java code | 
| 1799 | tranlsates to Scala code:\bigskip | |
| 343 | 1800 | |
| 352 | 1801 | \noindent | 
| 1802 | Variable declaration: | |
| 343 | 1803 | \begin{lstlisting}[language=Java]
 | 
| 352 | 1804 | Drink coke = getCoke();/*!\annotation{Java}!*/
 | 
| 343 | 1805 | \end{lstlisting}
 | 
| 1806 | ||
| 1807 | \begin{lstlisting}[language=Scala]
 | |
| 352 | 1808 | val coke : Drink = getCoke()/*!\annotation{Scala}!*/
 | 
| 343 | 1809 | \end{lstlisting}
 | 
| 1810 | ||
| 352 | 1811 | \noindent | 
| 395 | 1812 | or even | 
| 1813 | ||
| 1814 | \begin{lstlisting}[language=Scala]
 | |
| 1815 | val coke = getCoke()/*!\annotation{Scala}!*/
 | |
| 1816 | \end{lstlisting}\bigskip
 | |
| 1817 | ||
| 1818 | \noindent | |
| 343 | 1819 | Unit means void: | 
| 1820 | ||
| 1821 | \begin{lstlisting}[language=Java]
 | |
| 352 | 1822 | public void output(String s) {/*!\annotation{Java}!*/
 | 
| 343 | 1823 | System.out.println(s); | 
| 1824 | } | |
| 1825 | \end{lstlisting}
 | |
| 1826 | ||
| 1827 | \begin{lstlisting}[language=Scala]
 | |
| 352 | 1828 | def output(s: String): Unit = println(s)/*!\annotation{Scala}!*/
 | 
| 395 | 1829 | \end{lstlisting}\bigskip
 | 
| 343 | 1830 | |
| 352 | 1831 | \noindent | 
| 467 | 1832 | Compound types, say the type for list of Strings: | 
| 343 | 1833 | |
| 1834 | \begin{lstlisting}[language=Java]
 | |
| 352 | 1835 | List<String>/*!\annotation{Java}!*/
 | 
| 343 | 1836 | \end{lstlisting}
 | 
| 1837 | ||
| 1838 | \begin{lstlisting}[language=Scala]
 | |
| 352 | 1839 | List[String]/*!\annotation{Scala}!*/
 | 
| 395 | 1840 | \end{lstlisting}\bigskip
 | 
| 343 | 1841 | |
| 352 | 1842 | \noindent | 
| 343 | 1843 | String interpolations | 
| 1844 | ||
| 1845 | \begin{lstlisting}[language=Java]
 | |
| 352 | 1846 | System.out.println("Hello, "+ first + " "+ last + "!");
 | 
| 1847 | /*!\annotation{Java}!*/
 | |
| 343 | 1848 | \end{lstlisting}
 | 
| 1849 | ||
| 1850 | \begin{lstlisting}[language=Scala]
 | |
| 352 | 1851 | println(s"Hello, $first $last!")/*!\annotation{Scala}!*/
 | 
| 395 | 1852 | \end{lstlisting}\bigskip
 | 
| 343 | 1853 | |
| 352 | 1854 | \noindent | 
| 395 | 1855 | Java provides some syntactic sugar when constructing anonymous functions: | 
| 343 | 1856 | |
| 1857 | \begin{lstlisting}[language=Java]
 | |
| 1858 | list.foreach(item -> System.out.println("* " + item));
 | |
| 352 | 1859 | /*!\annotation{Java}!*/
 | 
| 343 | 1860 | \end{lstlisting}
 | 
| 1861 | ||
| 352 | 1862 | \noindent | 
| 438 | 1863 | In Scala, we use the \code{=>} symbol for the same:
 | 
| 343 | 1864 | |
| 1865 | \begin{lstlisting}[language=Scala]
 | |
| 352 | 1866 | list.foreach(item => println(s"* $item"))/*!\annotation{Scala}!*/
 | 
| 1867 | \end{lstlisting}%$
 | |
| 395 | 1868 | \end{boxedminipage}
 | 
| 1869 | \end{figure}
 | |
| 343 | 1870 | |
| 352 | 1871 | %%new / vs case classes | 
| 343 | 1872 | |
| 195 | 1873 | |
| 123 | 1874 | \subsection*{More Info}
 | 
| 1875 | ||
| 1876 | There is much more to Scala than I can possibly describe in | |
| 467 | 1877 | this short document and teach in the lectures. Fortunately there are a | 
| 197 | 1878 | number of free books | 
| 123 | 1879 | about Scala and of course lots of help online. For example | 
| 1880 | ||
| 1881 | \begin{itemize}
 | |
| 400 | 1882 | %%\item \url{http://www.scala-lang.org/docu/files/ScalaByExample.pdf}
 | 
| 1883 | %%\item \url{http://www.scala-lang.org/docu/files/ScalaTutorial.pdf}
 | |
| 123 | 1884 | \item \url{https://www.youtube.com/user/ShadowofCatron}
 | 
| 1885 | \item \url{http://docs.scala-lang.org/tutorials}
 | |
| 1886 | \item \url{https://www.scala-exercises.org}
 | |
| 188 | 1887 | \item \url{https://twitter.github.io/scala_school}
 | 
| 123 | 1888 | \end{itemize}
 | 
| 188 | 1889 | |
| 197 | 1890 | \noindent There is also an online course at Coursera on Functional | 
| 123 | 1891 | Programming Principles in Scala by Martin Odersky, the main | 
| 1892 | developer of the Scala language. And a document that explains | |
| 1893 | Scala for Java programmers | |
| 1894 | ||
| 1895 | \begin{itemize}
 | |
| 1896 | \item \small\url{http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html}
 | |
| 1897 | \end{itemize}
 | |
| 1898 | ||
| 1899 | While I am quite enthusiastic about Scala, I am also happy to | |
| 467 | 1900 | admit that it has more than its fair share of faults. | 
| 1901 | %The | |
| 1902 | %problem seen earlier of having to give an explicit type to | |
| 1903 | %\code{toSet}, but not \code{toList} is one of them. There are
 | |
| 1904 | %also many ``deep'' ideas about types in Scala, which even to | |
| 1905 | %me as seasoned functional programmer are puzzling. | |
| 1906 | For example, whilst | |
| 123 | 1907 | implicits are great, they can also be a source of great | 
| 1908 | headaches, for example consider the code: | |
| 1909 | ||
| 1910 | \begin{lstlisting}[numbers=none]
 | |
| 1911 | scala> List (1, 2, 3) contains "your mom" | |
| 1912 | res1: Boolean = false | |
| 1913 | \end{lstlisting}
 | |
| 1914 | ||
| 1915 | \noindent Rather than returning \code{false}, this code should
 | |
| 1916 | throw a typing-error. There are also many limitations Scala | |
| 1917 | inherited from the JVM that can be really annoying. For | |
| 1918 | example a fixed stack size. One can work around this | |
| 1919 | particular limitation, but why does one have to? | |
| 1920 | More such `puzzles' can be found at | |
| 1921 | ||
| 1922 | \begin{center}
 | |
| 1923 |   \url{http://scalapuzzlers.com} and
 | |
| 1924 |   \url{http://latkin.org/blog/2017/05/02/when-the-scala-compiler-doesnt-help/}
 | |
| 1925 | \end{center}
 | |
| 191 | 1926 | |
| 1927 | Even if Scala has been a success in several high-profile companies, | |
| 1928 | there is also a company (Yammer) that first used Scala in their | |
| 1929 | production code, but then moved away from it. Allegedly they did not | |
| 1930 | like the steep learning curve of Scala and also that new versions of | |
| 1931 | Scala often introduced incompatibilities in old code. Also the Java | |
| 468 | 1932 | language is lately developing at lightening speed (in comparison to | 
| 1933 | the past) taking on many features of Scala and other languages, and it | |
| 1934 | seems it even introduces new features on its own. So there is | |
| 1935 | seemingly even more incentive to stick with the old stuff you | |
| 1936 | know. Still, the goal of this part of PEP is to bend your mind about | |
| 1937 | what programming is\ldots{}namely functional programming. I promise
 | |
| 1938 | you, this will be useful no matter with which programming language you | |
| 1939 | will work. | |
| 123 | 1940 | |
| 333 | 1941 | |
| 1942 | Scala is deep: After many years, I still continue to learn new technique | |
| 467 | 1943 | for writing more elegant code. | 
| 1944 | %Unfortunately, I have not yet managed to | |
| 1945 | %switch over my code to Scala 3.0 due to time constraints. | |
| 1946 | Scala 3 seems | |
| 438 | 1947 | to iron out a number of snags from Scala 2, but why on earth are they | 
| 439 | 1948 | introducing Python-esque indentation and why on earth are they | 
| 438 | 1949 | re-introducing the \texttt{then}-keyword in Scala 3, when I just about got
 | 
| 1950 | comfortable without it? | |
| 333 | 1951 | |
| 152 | 1952 | %So all in all, Scala might not be a great teaching language, | 
| 1953 | %but I hope this is mitigated by the fact that I never require | |
| 1954 | %you to write any Scala code. You only need to be able to read | |
| 1955 | %it. In the coursework you can use any programming language you | |
| 1956 | %like. If you want to use Scala for this, then be my guest; if | |
| 1957 | %you do not want, stick with the language you are most familiar | |
| 1958 | %with. | |
| 123 | 1959 | |
| 1960 | ||
| 191 | 1961 | \subsection*{Conclusion}
 | 
| 1962 | ||
| 480 | 1963 | I hope you liked the short journey through the Scala language---but | 
| 1964 | remember we like you to take on board the functional programming point | |
| 1965 | of view, rather than just learning another language: Immutable | |
| 1966 | functions are easier to trust, because they the same output on the | |
| 1967 | same input. For the same reason they are easier to test and debug. | |
| 1968 | There is an interesting blog article about Scala by a convert: | |
| 198 | 1969 | |
| 1970 | \begin{center}
 | |
| 1971 | \url{https://www.skedulo.com/tech-blog/technology-scala-programming/}
 | |
| 1972 | \end{center}  
 | |
| 1973 | ||
| 1974 | \noindent | |
| 1975 | He makes pretty much the same arguments about functional programming and | |
| 1976 | immutability (one section is teasingly called \textit{``Where Did all
 | |
| 1977 | the Bugs Go?''}). If you happen to moan about all the idiotic features | |
| 468 | 1978 | of Scala (3), well, I guess this is part of the package according to this | 
| 198 | 1979 | quote:\bigskip | 
| 197 | 1980 | |
| 1981 | %\begin{itemize}
 | |
| 1982 | %\item no exceptions....there two kinds, one ``global'' exceptions, like | |
| 1983 | %out of memory (not much can be done about this by the ``individual'' | |
| 1984 | %programmer); and ``local one'' open a file that might not exists - in | |
| 1985 | %the latter you do not want to use exceptions, but Options | |
| 1986 | %\end{itemize}
 | |
| 123 | 1987 | |
| 182 | 1988 | \begin{flushright}\it
 | 
| 1989 | There are only two kinds of languages: the ones people complain | |
| 1990 | about\\ and the ones nobody uses.\smallskip\\ | |
| 1991 | \mbox{}\hfill\small{}---Bjarne Stroustrup (the inventor of C++)
 | |
| 1992 | \end{flushright}
 | |
| 1993 | ||
| 123 | 1994 | \end{document}
 | 
| 1995 | ||
| 1996 | %%% Local Variables: | |
| 1997 | %%% mode: latex | |
| 1998 | %%% TeX-master: t | |
| 1999 | %%% End: |