author | Christian Urban <christian dot urban at kcl dot ac dot uk> |
Tue, 26 Aug 2014 17:26:06 +0100 | |
changeset 229 | 00c4fda3d6c5 |
parent 228 | 4df4404455d0 |
child 230 | 0fd668d7b619 |
permissions | -rw-r--r-- |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
1 |
\documentclass{article} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
2 |
\usepackage{hyperref} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
3 |
\usepackage{amssymb} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
4 |
\usepackage{alltt} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
5 |
\usepackage{menukeys} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
6 |
\usepackage{amsmath} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
7 |
\usepackage{../langs} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
8 |
\usepackage{mathpazo} |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
9 |
\usepackage[scaled=.9]{helvet} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
10 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
11 |
\newcommand{\dn}{\stackrel{\mbox{\scriptsize def}}{=}}% |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
12 |
\definecolor{codegray}{gray}{0.9} |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
13 |
\newcommand{\code}[1]{\colorbox{codegray}{\texttt{#1}}} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
14 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
15 |
\begin{document} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
16 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
17 |
\section*{A Crash-Course on Scala} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
18 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
19 |
Scala is programming language that combines functional and |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
20 |
object-oriented programming-styles, and has received in the |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
21 |
last five years quite a bit of attention. One reason for this |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
22 |
attention is that, like the Java programming language, Scala |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
23 |
compiles to the Java Virtual Machine (JVM) and therefore can |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
24 |
run under MacOSX, Linux and Windows.\footnote{There are also |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
25 |
experimental backends for Android and JavaScript.} Unlike |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
26 |
Java, however, Scala often allows programmers to write concise |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
27 |
and elegant code. Some therefore say Scala is the much better |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
28 |
Java. If you want to try it out yourself, the Scala compiler |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
29 |
can be downloaded from |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
30 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
31 |
\begin{quote} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
32 |
\url{http://www.scala-lang.org} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
33 |
\end{quote} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
34 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
35 |
Why do I use Scala in the AFL course? Actually, you can do |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
36 |
\emph{any} part of the programming coursework in \emph{any} |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
37 |
programming language you like. I use Scala for showing you |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
38 |
code during the lectures because its functional |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
39 |
programming-style allows me to implement the functions we will |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
40 |
discuss with very small code-snippets. Since the compiler is |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
41 |
free, you can download them and run every example I give. But |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
42 |
if you prefer, you can also easily translate the code-snippets |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
43 |
into any other functional language, for example Haskell, ML, |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
44 |
F\# and so on. |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
45 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
46 |
Writing programs in Scala can be done with the Eclipse IDE and |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
47 |
also with IntelliJ, but for the small programs I will develop |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
48 |
the good old Emacs-editor is adequate for me and I will run |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
49 |
the programs on the command line. One advantage of Scala over Java |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
50 |
is that it includes an interpreter (a REPL, or |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
51 |
Read-Eval-Print-Loop) with which you can run and test small |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
52 |
code-snippets without the need of the compiler. This helps a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
53 |
lot with interactively developing programs. Once you installed |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
54 |
Scala correctly, you can start the interpreter by typing |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
55 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
56 |
|
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
57 |
\begin{alltt} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
58 |
$ scala\small |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
59 |
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM). |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
60 |
Type in expressions to have them evaluated. |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
61 |
Type :help for more information.\normalsize |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
62 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
63 |
scala> |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
64 |
\end{alltt} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
65 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
66 |
\noindent The precise response may vary due to the platform |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
67 |
where you installed Scala. At the scala prompt you can type |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
68 |
things like {\tt 2 + 3} \keys{Ret} and the output will be |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
69 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
70 |
\begin{alltt} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
71 |
scala> 2 + 3 |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
72 |
res0: Int = 5 |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
73 |
\end{alltt} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
74 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
75 |
\noindent indicating that the result of the addition is of |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
76 |
type {\tt Int} and the actual result is {\tt 5}. Another |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
77 |
classic example you can try out is |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
78 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
79 |
\begin{alltt} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
80 |
scala> print ("hello world") |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
81 |
hello world |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
82 |
\end{alltt} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
83 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
84 |
\noindent Note that in this case there is no result: the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
85 |
reason is that {\tt print} does not actually produce a result |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
86 |
(there is no {\tt resXX}), rather it is a function that causes |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
87 |
the \emph{side-effect} of printing out a string. Once you are |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
88 |
more familiar with the functional programming-style, you will |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
89 |
know what the difference is between a function that returns a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
90 |
result, like addition, and a function that causes a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
91 |
side-effect, like {\tt print}. We shall come back to this |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
92 |
point in due course, but if you are curious now, the latter |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
93 |
kind of functions always have as return type {\tt Unit}. |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
94 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
95 |
If you want to write a stand-alone app, you can implement |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
96 |
an object that is an instance of {\tt App}, say |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
97 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
98 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
99 |
\begin{lstlisting}[language=Scala] |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
100 |
object Hello extends App { |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
101 |
println ("hello world") |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
102 |
} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
103 |
\end{lstlisting} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
104 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
105 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
106 |
\noindent save it in a file, say {\tt hellow-world.scala}, and |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
107 |
then run the compiler and runtime environment: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
108 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
109 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
110 |
$ scalac hello-world.scala |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
111 |
$ scala Hello |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
112 |
hello world |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
113 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
114 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
115 |
As mentioned above, Scala targets the JVM and |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
116 |
consequently Scala programs can also be executed by the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
117 |
bog-standard Java runtime. This only requires the inclusion of |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
118 |
{\tt scala-library.jar}, which on my computer can be done as |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
119 |
follows: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
120 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
121 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
122 |
$ scalac hello-world.scala |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
123 |
$ java -cp /usr/local/src/scala/lib/scala-library.jar:. Hello |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
124 |
hello world |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
125 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
126 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
127 |
|
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
128 |
\subsection*{Inductive Datatypes} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
129 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
130 |
The elegance and conciseness of Scala programs are often a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
131 |
result of inductive datatypes that can be easily defined. For |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
132 |
example in ``every-day mathematics'' we would define regular |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
133 |
expressions simply by giving the grammar |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
134 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
135 |
\begin{center} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
136 |
\begin{tabular}{r@{\hspace{2mm}}r@{\hspace{2mm}}l@{\hspace{13mm}}l} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
137 |
$r$ & $::=$ & $\varnothing$ & null\\ |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
138 |
& $\mid$ & $\epsilon$ & empty string\\ |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
139 |
& $\mid$ & $c$ & single character\\ |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
140 |
& $\mid$ & $r_1 \cdot r_2$ & sequence\\ |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
141 |
& $\mid$ & $r_1 + r_2$ & alternative / choice\\ |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
142 |
& $\mid$ & $r^*$ & star (zero or more)\\ |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
143 |
\end{tabular} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
144 |
\end{center} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
145 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
146 |
\noindent This grammar specifies what regular expressions are |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
147 |
(essentially a kind of tree-structure with three kinds of |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
148 |
inner nodes---sequence, alternative and star---and three kinds |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
149 |
of leave nodes---null, empty and character). If you are |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
150 |
familiar with Java, it might be an instructive exercise to |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
151 |
define this kind of inductive datatypes in |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
152 |
Java.\footnote{Happy programming! ;o)} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
153 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
154 |
Implementing the regular expressions from above in Scala is |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
155 |
very simple: It first requires an \emph{abstract class}, say, |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
156 |
{\tt Rexp}. This will act as the type for regular expressions. |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
157 |
Second, it requires some instances. The cases for |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
158 |
$\varnothing$ and $\epsilon$ do not have any arguments, while |
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
159 |
in all the other cases we do have arguments. For example the |
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
160 |
character regular expression needs to take as an argument the |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
161 |
character it is supposed to recognise. In Scala, the cases |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
162 |
without arguments are called \emph{case objects}, while the |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
163 |
ones with arguments are \emph{case classes}. The corresponding |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
164 |
code is as follows: |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
165 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
166 |
\begin{quote} |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
167 |
\begin{lstlisting}[language=Scala] |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
168 |
abstract class Rexp |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
169 |
case object NULL extends Rexp |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
170 |
case object EMPTY extends Rexp |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
171 |
case class CHAR (c: Char) extends Rexp |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
172 |
case class SEQ (r1: Rexp, r2: Rexp) extends Rexp |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
173 |
case class ALT (r1: Rexp, r2: Rexp) extends Rexp |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
174 |
case class STAR (r: Rexp) extends Rexp |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
175 |
\end{lstlisting} |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
176 |
\end{quote} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
177 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
178 |
\noindent In order to be an instance of {\tt Rexp}, each case |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
179 |
object and case class needs to extend {\tt Rexp}. Given the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
180 |
grammar above, I hope you can see the underlying pattern. If |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
181 |
you want to play further with such definitions, feel free to |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
182 |
define for example binary trees. |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
183 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
184 |
Once you make a definition like the one above, you can |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
185 |
represent, for example, the regular expression for $a + b$ in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
186 |
Scala as {\tt ALT(CHAR('a'), CHAR('b'))}. Expressions such as |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
187 |
{\tt 'a'} stand for ASCII characters. If you want to assign |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
188 |
this regular expression to a variable, you can use the keyword |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
189 |
{\tt val} and type |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
190 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
191 |
\begin{alltt} |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
192 |
scala> val r = ALT(CHAR('a'), CHAR('b')) |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
193 |
r: ALT = ALT(CHAR(a),CHAR(b)) |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
194 |
\end{alltt} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
195 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
196 |
\noindent As you can see, in order to make such assignments, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
197 |
no constructor is required in the class (as in Java). However, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
198 |
if there is the need for some non-standard initialisation, you |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
199 |
can of course define such a constructor in Scala. But we omit |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
200 |
this here. |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
201 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
202 |
Note that Scala in its response says the variable {\tt r} is |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
203 |
of type {\tt ALT}, not {\tt Rexp}. This might be a bit |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
204 |
unexpected, but can be explained as follows: Scala always |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
205 |
tries to find the most general type that is needed for a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
206 |
variable or expression, but does not ``over-generalise''. In |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
207 |
this case there is no need to give {\tt r} the more general |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
208 |
type of {\tt Rexp}. This is different if you want to form a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
209 |
list of regular expressions, for example |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
210 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
211 |
\begin{alltt} |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
212 |
scala> val ls = List(ALT(CHAR('a'), CHAR('b')), NULL) |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
213 |
ls: List[Rexp] = List(ALT(CHAR(a),CHAR(b)), NULL) |
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
214 |
\end{alltt} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
215 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
216 |
\noindent In this case Scala needs to assign a common type to |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
217 |
the regular expressions, so that it is compatible with the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
218 |
fact that lists can only contain elements of a single type, in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
219 |
this case the type is {\tt Rexp}.\footnote{If you type in this |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
220 |
example, you will notice that the type contains some further |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
221 |
information, but lets ignore this for the moment.} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
222 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
223 |
For types like {\tt List[...]} the general rule is that when a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
224 |
type takes another type as argument, then this is written in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
225 |
angle-brackets. This can also contain nested types as in {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
226 |
List[Set[Rexp]]}, which is a list of sets each of which |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
227 |
contains regular expressions. |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
228 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
229 |
\subsection*{Functions and Pattern-Matching} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
230 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
231 |
I mentioned above that Scala is a very elegant programming |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
232 |
language for the code we will write in this module. This |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
233 |
elegance mainly stems from the fact that functions can be |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
234 |
implemented very easily in Scala. Lets first consider a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
235 |
problem from number theory, called the \emph{Collatz-series}, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
236 |
which corresponds to a famous unsolved problem in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
237 |
mathematics.\footnote{See for example |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
238 |
\url{http://mathworld.wolfram.com/CollatzProblem.html}.} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
239 |
Mathematician define this series as: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
240 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
241 |
\[ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
242 |
collatz_{n + 1} \dn |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
243 |
\begin{cases} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
244 |
\frac{1}{2} * collatz_n & \text{if $collatz_n$ is even}\\ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
245 |
3 * collatz_n + 1 & \text{if $collatz_n$ is odd} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
246 |
\end{cases} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
247 |
\] |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
248 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
249 |
\noindent The famous unsolved question is whether this |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
250 |
series started with any $n > 0$ as $collaz_0$ will always |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
251 |
return to $1$. This is obvious when started with $1$, and also |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
252 |
with $2$, but already needs a bit of head-scratching for the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
253 |
case of $3$. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
254 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
255 |
If we want to avoid the head-scratching, we could implement |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
256 |
this as the following function in Scala: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
257 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
258 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
259 |
\lstinputlisting[language=Scala]{../progs/collatz.scala} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
260 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
261 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
262 |
\noindent The keyword for function definitions is {\tt def} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
263 |
followed by the name of the function. After that you have a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
264 |
list of arguments (enclosed in parentheses and separated by |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
265 |
commas). Each argument in this list needs its type annotated. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
266 |
In this case we only have one argument, which is of type {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
267 |
BigInt}. This type stands for arbitrary precision integers. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
268 |
After the arguments comes the type of what the function |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
269 |
returns---a Boolean in this case for indicating that the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
270 |
function has reached {\tt 1}. Finally, after the {\tt =} comes |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
271 |
the \emph{body} of the function implementing what the function |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
272 |
is supposed to do. What the {\tt collatz} function does should |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
273 |
be pretty self-explanatory: the function first tests whether |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
274 |
{\tt n} is equal to $1$ in which case it returns {\tt true} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
275 |
and so on. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
276 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
277 |
Notice a quirk in Scala's syntax for {\tt if}s: The condition |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
278 |
needs to be enclosed in parentheses and the then-case comes |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
279 |
right after the condition---there is no {\tt then} keyword in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
280 |
Scala. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
281 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
282 |
The real power of Scala comes, however, from the ability to |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
283 |
define functions by \emph{pattern matching}. In the {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
284 |
collatz} function above we need to test each case using a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
285 |
sequence of {\tt if}s. This can be very cumbersome and brittle |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
286 |
if there are many cases. If we wanted to define a function |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
287 |
over regular expressions in say Java, which does not have |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
288 |
pattern-matching, the resulting code would just be awkward. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
289 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
290 |
Mathematicians already use the power of pattern-matching, for |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
291 |
example, when they define the function that takes a regular |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
292 |
expression and produces another regular expression that can |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
293 |
recognise the reversed strings. The resulting recursive |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
294 |
function is often defined as follows: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
295 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
296 |
\begin{center} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
297 |
\begin{tabular}{r@{\hspace{1mm}}c@{\hspace{1mm}}l} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
298 |
$rev(\varnothing)$ & $\dn$ & $\varnothing$\\ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
299 |
$rev(\epsilon)$ & $\dn$ & $\epsilon$\\ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
300 |
$rev(c)$ & $\dn$ & $c$\\ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
301 |
$rev(r_1 + r_2)$ & $\dn$ & $rev(r_1) + rev(r_2)$\\ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
302 |
$rev(r_1 \cdot r_2)$ & $\dn$ & $rev(r_2) \cdot rev(r_1)$\\ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
303 |
$rev(r^*)$ & $\dn$ & $rev(r)^*$\\ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
304 |
\end{tabular} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
305 |
\end{center} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
306 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
307 |
\noindent The corresponding Scala code looks very similar |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
308 |
to this definition, thanks to pattern-matching. |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
309 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
310 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
311 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
312 |
\lstinputlisting[language=Scala]{../progs/rev.scala} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
313 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
314 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
315 |
\noindent The keyword for starting a pattern-match is {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
316 |
match} followed by a list of {\tt case}s. Before the match |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
317 |
can be another pattern, but often as in the case above, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
318 |
it is just a variable you want to pattern-match. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
319 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
320 |
In the {\tt rev}-function above, each case follows the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
321 |
structure of how we defined regular expressions as inductive |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
322 |
datatype. For example the case in Line 3 you can read as: if |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
323 |
the regular expression {\tt r} is of the form {\tt EMPTY} then |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
324 |
do whatever follows the {\tt =>} (in this case just return |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
325 |
{\tt EMPTY}). Line 5 reads as: if the regular expression |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
326 |
{\tt r} is of the form {\tt ALT(r1, r2)}, where the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
327 |
left-branch of the alternative is matched by the variable {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
328 |
r1} and the right-branch by {\tt r2} then do ``something''. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
329 |
The ``something'' can now use the variables {\tt r1} and {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
330 |
r2} from the match. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
331 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
332 |
If you want to play with this function, call, it for |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
333 |
example, with the regular expression $ab + ac$. This regular |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
334 |
expression can recognise the strings $ab$ and $ac$. The |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
335 |
function {\tt rev} produces the result $ba + ca$, which |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
336 |
can recognise the reversed strings $ba$ and $ca$. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
337 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
338 |
In Scala each pattern-match can also be guarded as in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
339 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
340 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
341 |
\begin{lstlisting}[language=Scala, numbers=none] |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
342 |
case Pattern if Condition => Do_Something |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
343 |
\end{lstlisting} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
344 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
345 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
346 |
\noindent This allows us, for example, to re-write the {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
347 |
collatz}-function from above as follows: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
348 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
349 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
350 |
\lstinputlisting[language=Scala]{../progs/collatz2.scala} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
351 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
352 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
353 |
\noindent Although in this case the pattern-match does not |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
354 |
improve the code in any way. The underscore in the last case |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
355 |
indicates that we do not care what the pattern looks like. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
356 |
Thus Line 4 acts like a default case whenever the cases above |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
357 |
did not match. Cases are always tried out from top to bottom. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
358 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
359 |
\subsection*{Loops} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
360 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
361 |
Coming from Java or C, you might be surprised that Scala does |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
362 |
not really have loops. It has instead, what is in functional |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
363 |
programming called \emph{maps}. To illustrate how they work, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
364 |
lets assume you have a list of numbers from 1 to 10 and want to |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
365 |
build the list of squares. The list of numbers from 1 to 10 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
366 |
can be constructed in Scala as follows: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
367 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
368 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
369 |
scala> (1 to 10).toList |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
370 |
res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
371 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
372 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
373 |
\noindent Generating from this list the list of squares in a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
374 |
non-functional language (e.g.~Java), you would assume the list |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
375 |
is given as a kind of array. You would then iterate, or loop, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
376 |
an index over this array and replace each entry in the array |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
377 |
by the square. Right? In Scala, and in other functional |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
378 |
programming languages, you use maps to achieve the same. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
379 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
380 |
Maps essentially take a function that describes how each |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
381 |
element is transformed (for example squaring) and a list over |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
382 |
which this function should work. There are two forms to |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
383 |
express maps in Scala. The first way is in a {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
384 |
for}-construction. Squaring the numbers from 1 to 10 would |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
385 |
look in this form as follows: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
386 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
387 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
388 |
scala> for (n <- (1 to 10).toList) yield n * n |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
389 |
res2: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
390 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
391 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
392 |
\noindent The keywords are {\tt for} and {\tt yield}. This |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
393 |
{\tt for}-construction roughly says that from the list of |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
394 |
numbers we draw {\tt n}s and compute the result of {\tt n * |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
395 |
n}. In consequence we specified the list where each {\tt n} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
396 |
comes from, namely {\tt (1 to 10).toList}, and how each |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
397 |
element needs to be transformed. This can also be expressed |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
398 |
in a second way by using directly {\tt map} as follows: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
399 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
400 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
401 |
scala> (1 to 10).toList.map(n => n * n) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
402 |
res3 = List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
403 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
404 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
405 |
\noindent In this way the expression {\tt n => n * n} stands |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
406 |
for the function that calculates the square (this is how the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
407 |
{\tt n}s are transformed). This expression for functions might |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
408 |
remind you on your lessons about the lambda-calculus where |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
409 |
this would have been written as $\lambda n.\,n * n$. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
410 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
411 |
It might not be obvious, but {\tt for}-constructions are just |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
412 |
syntactic sugar: when compiling, Scala translates them into |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
413 |
equivalent maps. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
414 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
415 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
416 |
The very charming feature of Scala is that such maps or {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
417 |
for}-constructions can be written for any kind of data |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
418 |
collection, such as lists, sets, vectors and so on. For |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
419 |
example if we instead compute the reminders modulo $3$ of this |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
420 |
list, we can write |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
421 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
422 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
423 |
scala> (1 to 10).toList.map(n => n \% 3) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
424 |
res4 = List(1, 2, 0, 1, 2, 0, 1, 2, 0, 1) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
425 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
426 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
427 |
\noindent If we, however, transform the numbers 1 to 10 not |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
428 |
into a list, but into a set, and then compute the reminders |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
429 |
modulo $3$ we obtain |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
430 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
431 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
432 |
scala> (1 to 10).toSet[Int].map(n => n \% 3) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
433 |
res5 = Set(2, 1, 0) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
434 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
435 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
436 |
\noindent This is the correct result for sets, as there are |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
437 |
only 3 equivalence classes of integers modulo 3. Note that we |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
438 |
need to ``help'' Scala in this example to transform the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
439 |
numbers into a set of integers by explicitly annotating the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
440 |
type {\tt Int}. Since maps and {\tt for}-construction are just |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
441 |
syntactic variants of each other, the latter can also be |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
442 |
written as |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
443 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
444 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
445 |
scala> for (n <- (1 to 10).toSet[Int]) yield n \% 3 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
446 |
res5 = Set(2, 1, 0) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
447 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
448 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
449 |
While hopefully this all looks reasonable, there is one |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
450 |
complication: In the examples above we always wanted to |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
451 |
transform one list into another list (e.g.~list of squares), |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
452 |
or one set into another set (set of numbers into set of |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
453 |
reminders modulo 3). What happens if we just want to print out |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
454 |
a list of integers? Then actually the {\tt for}-construction |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
455 |
needs to be modified. The reason is that {\tt print}, you |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
456 |
guessed it, does not produce any result, but only produces, in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
457 |
the functional-programming-lingo, a side-effect. Printing out |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
458 |
the list of numbers from 1 to 5 would look as follows |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
459 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
460 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
461 |
scala> for (n <- (1 to 5).toList) println(n) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
462 |
1 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
463 |
2 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
464 |
3 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
465 |
4 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
466 |
5 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
467 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
468 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
469 |
\noindent |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
470 |
where you need to omit the keyword {\tt yield}. You can |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
471 |
also do more elaborate calculations such as |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
472 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
473 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
474 |
scala> for (n <- (1 to 5).toList) \{ |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
475 |
val square_n = n * n |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
476 |
println(s"$n * $n = $square_n") |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
477 |
\} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
478 |
1 * 1 = 1 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
479 |
2 * 2 = 4 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
480 |
3 * 3 = 9 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
481 |
4 * 4 = 16 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
482 |
5 * 5 = 25 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
483 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
484 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
485 |
\noindent |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
486 |
In this code I use a \emph{string interpolation}, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
487 |
written {\tt s"..."} in order to print out an equation. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
488 |
This string interpolation allows me to refer to the integer |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
489 |
values {\tt n} and {\tt square\_n} inside a string. This |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
490 |
is very convenient for printing out ``things''. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
491 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
492 |
The corresponding map construction for functions with |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
493 |
side-effexts is in Scala called {\tt foreach}. So you |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
494 |
could also write |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
495 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
496 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
497 |
scala> (1 to 5).toList.foreach(n => println(n)) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
498 |
1 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
499 |
2 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
500 |
3 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
501 |
4 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
502 |
5 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
503 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
504 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
505 |
\noindent or even just |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
506 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
507 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
508 |
scala> (1 to 5).toList.foreach(println) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
509 |
1 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
510 |
2 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
511 |
3 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
512 |
4 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
513 |
5 |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
514 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
515 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
516 |
\noindent If you want to find out more maps and functions |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
517 |
with side-efffects, you can ponder about the response Scala |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
518 |
gives if you replace {\tt foreach} by {\tt map} in the |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
519 |
expression above. Scala will still allow {\tt map}, but |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
520 |
then reacts with an interesting result. |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
521 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
522 |
\subsection*{Types} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
523 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
524 |
In most functional programming languages types play an |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
525 |
important role. Scala is such a language. You have already |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
526 |
seen built-in types, like {\tt Int}, {\tt Boolean}, {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
527 |
String} and {\tt BigInt}, but also user-defined ones, like {\tt Rexp}. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
528 |
Unfortunately, types can be a thorny subject, especially in |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
529 |
Scala. For example, why do we need to give the type to {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
530 |
toSet[Int]} but not to {\tt toList}? The reason is the power |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
531 |
of Scala, which sometimes means it cannot infer all necessary |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
532 |
typing information. At the beginning while getting familiar |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
533 |
with Scala, I recommend a ``play-it-by-ear-approach'' to |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
534 |
types. Fully understanding type-systems, especially compicated |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
535 |
ones like in Scala, can take a module on their |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
536 |
own.\footnote{Still, such a study can be a rewarding training: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
537 |
If you are in the business of designing new programming |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
538 |
languages, you will not be able to turn a blind eye to types. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
539 |
They essentially help programmers to avoid common programming |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
540 |
errors and help with maintaining code.} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
541 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
542 |
In Scala, types are needed whenever you define an inductive |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
543 |
datatype and also whenever you define functions (their |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
544 |
arguments and their results need a type). Base types are types |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
545 |
that do not take any (type)arguments, for example {\tt Int} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
546 |
and {\tt String}. Compound types take one or more arguments, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
547 |
which need to be given in angle-brackets, for example {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
548 |
List[Int]} or {\tt Set[List[String]]} or {\tt Map[Int, Int]}. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
549 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
550 |
There are e few special type-constructors. One is for tuples, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
551 |
which is written with parentheses. For example {\tt (Int, Int, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
552 |
String)} for a triple consisting of two integers and a string. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
553 |
Tuples are helpful if you want to define a function with |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
554 |
multiple results, say the function returning the quotient and |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
555 |
reminder of two numbers. For this you might define: |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
556 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
557 |
\begin{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
558 |
def quo_rem(m: Int, n: Int) : (Int, Int) = (m \verb|/| n, m \% n) |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
559 |
\end{alltt} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
560 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
561 |
\noindent |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
562 |
Since this function returns a pair of integers, its type |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
563 |
needs to be {\tt (Int, Int)}. |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
564 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
565 |
Another special type-constructor is for functions, written |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
566 |
{\tt =>}. For example, the type {\tt Int => String} stands |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
567 |
for a function that takes an integer as argument and produces |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
568 |
a string. A function of this type is for instance |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
569 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
570 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
571 |
\begin{lstlisting}[language=Scala] |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
572 |
def mk_string(n: Int) : String = n match { |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
573 |
case 0 => "zero" |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
574 |
case 1 => "one" |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
575 |
case 2 => "two" |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
576 |
case _ => "many" |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
577 |
} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
578 |
\end{lstlisting} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
579 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
580 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
581 |
\noindent Unlike other functional programming languages, there |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
582 |
is no easy way to find out the types of existing functions |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
583 |
except for looking into the documentation |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
584 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
585 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
586 |
\url{http://www.scala-lang.org/api/current/} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
587 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
588 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
589 |
\noindent The function arrow can also be iterated, as in {\tt |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
590 |
Int => String => Boolean}. This is the type for a function |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
591 |
taking an integer as first argument and a string as second, |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
592 |
and the result of the function is a boolean. Though silly, a |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
593 |
function of this type is |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
594 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
595 |
\begin{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
596 |
\begin{lstlisting}[language=Scala] |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
597 |
def chk_string(n: Int, s: String) : Boolean = |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
598 |
mk_string(n) == s |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
599 |
\end{lstlisting} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
600 |
\end{quote} |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
601 |
|
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
602 |
\noindent |
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
603 |
|
228
4df4404455d0
more on scala
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
227
diff
changeset
|
604 |
\subsection*{Cool Stuff} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
605 |
|
229
00c4fda3d6c5
updated
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
228
diff
changeset
|
606 |
\subsection*{More Info} |
227
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
607 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
608 |
\end{document} |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
609 |
|
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
610 |
%%% Local Variables: |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
611 |
%%% mode: latex |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
612 |
%%% TeX-master: t |
93bd75031ced
added handout
Christian Urban <christian dot urban at kcl dot ac dot uk>
parents:
diff
changeset
|
613 |
%%% End: |