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