handouts/scala-ho.tex
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--
updated
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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: