handouts/scala-ho.tex
changeset 235 bc460179148c
parent 234 bf7eecc9cefe
child 236 34e901c529ce
equal deleted inserted replaced
234:bf7eecc9cefe 235:bc460179148c
    43 \emph{any} part of the coursework in \emph{any} programming
    43 \emph{any} part of the coursework in \emph{any} programming
    44 language you like. I use Scala for showing you code during the
    44 language you like. I use Scala for showing you code during the
    45 lectures because its functional programming-style allows me to
    45 lectures because its functional programming-style allows me to
    46 implement the functions we will discuss with very small
    46 implement the functions we will discuss with very small
    47 code-snippets. If I had to do this in Java, for example, I
    47 code-snippets. If I had to do this in Java, for example, I
    48 would first have to run through heaps of boilerplate code.
    48 would first have to run through heaps of boilerplate code and
    49 Since the Scala compiler is free, you can download the
    49 the code-snippets would not look pretty. Since the Scala
    50 code-snippets and run every example I give. But if you prefer,
    50 compiler is free, you can download the code-snippets and run
    51 you can also easily translate them into any other functional
    51 every example I give. But if you prefer, you can also easily
    52 language, for example Haskell, Standard ML, F$^\#$, Ocaml and
    52 translate them into any other functional language, for example
    53 so on.
    53 Haskell, Standard ML, F$^\#$, Ocaml and so on.
    54 
    54 
    55 Developing programs in Scala can be done with the Eclipse IDE
    55 Developing programs in Scala can be done with the Eclipse IDE
    56 and also with IntelliJ IDE, but for the small programs I will
    56 and also with IntelliJ IDE, but for the small programs I will
    57 develop the good old Emacs-editor is adequate for me and I
    57 develop the good old Emacs-editor is adequate for me and I
    58 will run the programs on the command line. One advantage of
    58 will run the programs on the command line. One advantage of
    90 hello world
    90 hello world
    91 \end{lstlisting}
    91 \end{lstlisting}
    92 
    92 
    93 \noindent Note that in this case there is no result. The
    93 \noindent Note that in this case there is no result. The
    94 reason is that \code{print} does not actually produce a result
    94 reason is that \code{print} does not actually produce a result
    95 (there is no \code{resXX}), rather it is a function that
    95 (there is no \code{resXX} and no type), rather it is a
    96 causes the \emph{side-effect} of printing out a string. Once
    96 function that causes the \emph{side-effect} of printing out a
    97 you are more familiar with the functional programming-style,
    97 string. Once you are more familiar with the functional
    98 you will know what the difference is between a function that
    98 programming-style, you will know what the difference is
    99 returns a result, like addition, and a function that causes a
    99 between a function that returns a result, like addition, and a
   100 side-effect, like \code{print}. We shall come back to this
   100 function that causes a side-effect, like \code{print}. We
   101 point later, but if you are curious now, the latter kind of
   101 shall come back to this point later, but if you are curious
   102 functions always have as return type \code{Unit}.
   102 now, the latter kind of functions always have as return type
       
   103 \code{Unit}.
   103 
   104 
   104 If you want to write a stand-alone app in Scala, you can
   105 If you want to write a stand-alone app in Scala, you can
   105 implement an object that is an instance of \code{App}, say
   106 implement an object that is an instance of \code{App}, say
   106 
   107 
   107 \begin{lstlisting}[language=Scala,numbers=none]
   108 \begin{lstlisting}[language=Scala,numbers=none]
   190 
   191 
   191 Once you make a definition like the one above in Scala, you
   192 Once you make a definition like the one above in Scala, you
   192 can represent, for example, the regular expression for $a + b$
   193 can represent, for example, the regular expression for $a + b$
   193 as \code{ALT(CHAR('a'), CHAR('b'))}. Expressions such as
   194 as \code{ALT(CHAR('a'), CHAR('b'))}. Expressions such as
   194 \code{'a'} stand for ASCII characters, though in the output
   195 \code{'a'} stand for ASCII characters, though in the output
   195 syntax the quotes are omitted. If you want to assign this
   196 syntax, as you can see below, the quotes are omitted. In a
   196 regular expression to a variable, you can use the keyword
   197 later section we will see how we can support the more
   197 \code{val} and type
   198 mathematical infix notation for regular expression operators
       
   199 in Scala. If you want to assign this regular expression to a
       
   200 variable, you can use the keyword \code{val} and type
   198 
   201 
   199 \begin{lstlisting}[language=Scala,numbers=none]
   202 \begin{lstlisting}[language=Scala,numbers=none]
   200 scala> val r = ALT(CHAR('a'), CHAR('b'))
   203 scala> val r = ALT(CHAR('a'), CHAR('b'))
   201 r: ALT = ALT(CHAR(a),CHAR(b))
   204 r: ALT = ALT(CHAR(a),CHAR(b))
   202 \end{lstlisting}
   205 \end{lstlisting}
   217 abstract class. But in this case there is no need to give
   220 abstract class. But in this case there is no need to give
   218 \code{r} the more general type of \code{Rexp}. This is
   221 \code{r} the more general type of \code{Rexp}. This is
   219 different if you want to form a list of regular expressions,
   222 different if you want to form a list of regular expressions,
   220 for example
   223 for example
   221 
   224 
   222 
       
   223 \begin{lstlisting}[language=Scala,numbers=none]
   225 \begin{lstlisting}[language=Scala,numbers=none]
   224 scala> val ls = List(ALT(CHAR('a'), CHAR('b')), NULL)
   226 scala> val ls = List(ALT(CHAR('a'), CHAR('b')), NULL)
   225 ls: List[Rexp] = List(ALT(CHAR(a),CHAR(b)), NULL)
   227 ls: List[Rexp] = List(ALT(CHAR(a),CHAR(b)), NULL)
   226 \end{lstlisting}
   228 \end{lstlisting}
   227 
       
   228 
   229 
   229 \noindent In this case, Scala needs to assign a common type to
   230 \noindent In this case, Scala needs to assign a common type to
   230 the regular expressions so that it is compatible with the
   231 the regular expressions so that it is compatible with the
   231 fact that lists can only contain elements of a single type. In
   232 fact that lists can only contain elements of a single type. In
   232 this case the first common type is \code{Rexp}.\footnote{If you
   233 this case the first common type is \code{Rexp}.\footnote{If you
   465 elements can be guarded. For example if we want to pair up
   466 elements can be guarded. For example if we want to pair up
   466 the numbers 1 to 4 with the letters a to c, we can write
   467 the numbers 1 to 4 with the letters a to c, we can write
   467 
   468 
   468 \begin{lstlisting}[language=Scala,numbers=none]
   469 \begin{lstlisting}[language=Scala,numbers=none]
   469 scala> for (n <- (1 to 4).toList; 
   470 scala> for (n <- (1 to 4).toList; 
   470      c <- ('a' to 'c').toList) yield (n, c)
   471             l <- ('a' to 'c').toList) yield (n, l)
   471 res6 = List((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), 
   472 res6 = List((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), 
   472             (3,a), (3,b), (3,c), (4,a), (4,b), (4,c))
   473             (3,a), (3,b), (3,c), (4,a), (4,b), (4,c))
   473 \end{lstlisting}
   474 \end{lstlisting}
   474 
   475 
   475 \noindent 
   476 \noindent 
   608 results, say the function returning the quotient and reminder
   609 results, say the function returning the quotient and reminder
   609 of two numbers. For this you might define:
   610 of two numbers. For this you might define:
   610 
   611 
   611 
   612 
   612 \begin{lstlisting}[language=Scala, numbers=none]
   613 \begin{lstlisting}[language=Scala, numbers=none]
   613 def quo_rem(m: Int, n: Int) : (Int, Int) = (m / n, m \% n)
   614 def quo_rem(m: Int, n: Int) : (Int, Int) = (m / n, m % n)
   614 \end{lstlisting}
   615 \end{lstlisting}
   615 
   616 
   616 
   617 
   617 \noindent
   618 \noindent
   618 Since this function returns a pair of integers, its type
   619 Since this function returns a pair of integers, its type
   632   case _ => "many" 
   633   case _ => "many" 
   633 } 
   634 } 
   634 \end{lstlisting}
   635 \end{lstlisting}
   635 
   636 
   636 
   637 
   637 \noindent Unlike other functional programming languages, there
   638 \noindent It takes an integer as argument and returns a
       
   639 string. Unlike other functional programming languages, there
   638 is in Scala no easy way to find out the types of existing
   640 is in Scala no easy way to find out the types of existing
   639 functions, except by looking into the documentation
   641 functions, except by looking into the documentation
   640 
   642 
   641 \begin{quote}
   643 \begin{quote}
   642 \url{http://www.scala-lang.org/api/current/}
   644 \url{http://www.scala-lang.org/api/current/}
   725 like \code{print}.
   727 like \code{print}.
   726 
   728 
   727 
   729 
   728 \subsection*{Cool Stuff}
   730 \subsection*{Cool Stuff}
   729 
   731 
   730 The first wow-moment I had with Scala when I came across the
   732 The first wow-moment I had with Scala was when I came across
   731 following code-snippet for reading a web-page. 
   733 the following code-snippet for reading a web-page. 
   732 
   734 
   733 
   735 
   734 \begin{lstlisting}[language=Scala, numbers=none]
   736 \begin{lstlisting}[language=Scala, numbers=none]
   735 import io.Source
   737 import io.Source
   736 val url = """http://www.inf.kcl.ac.uk/staff/urbanc/"""
   738 val url = """http://www.inf.kcl.ac.uk/staff/urbanc/"""
   741 \noindent These three lines return a string containing the
   743 \noindent These three lines return a string containing the
   742 HTML-code of my webpage. It actually already does something
   744 HTML-code of my webpage. It actually already does something
   743 more sophisticated, namely only returns the first 10000
   745 more sophisticated, namely only returns the first 10000
   744 characters of a webpage in case a ``webpage'' is too large.
   746 characters of a webpage in case a ``webpage'' is too large.
   745 Why is that code-snippet of any interest? Well, try
   747 Why is that code-snippet of any interest? Well, try
   746 implementing reading from a webpage in Java. I also like the
   748 implementing reading-from-a-webpage in Java. I also like the
   747 possibility of triple-quoting strings, which I have only seen
   749 possibility of triple-quoting strings, which I have only seen
   748 in Scala so far. The idea behind this is that in such a string 
   750 in Scala so far. The idea behind this is that in such a string 
   749 all characters are interpreted literally---there are no 
   751 all characters are interpreted literally---there are no 
   750 escaped characters, like \verb|\n| for newlines.
   752 escaped characters, like \verb|\n| for newlines.
   751 
   753 
   752 My second wow-moment I had with a feature of Scala that other
   754 My second wow-moment I had with a feature of Scala that other
   753 functional programming languages do not have. This feature is 
   755 functional programming languages also do not have. This
   754 about implicit type conversions. If you have regular 
   756 feature is about implicit type conversions. If you have
   755 expressions and want to use them for language processing you 
   757 regular expressions and want to use them for language
   756 often want to recognise keywords in a language, for example 
   758 processing you often want to recognise keywords in a language,
   757 \code{for}, \code{if}, \code{yield} and so on. But the basic 
   759 for example \code{for}, \code{if}, \code{yield} and so on. But
   758 regular expression, \code{CHAR}, can only recognise a single 
   760 the basic regular expression, \code{CHAR}, can only recognise
   759 character. In order to recognise a whole string, like \code{
   761 a single character. In order to recognise a whole string, like
   760 for}, you have to put many of those together using \code{SEQ}:
   762 \code{ for}, you have to put many of those together using
       
   763 \code{SEQ}:
   761 
   764 
   762 
   765 
   763 \begin{lstlisting}[language=Scala,numbers=none]
   766 \begin{lstlisting}[language=Scala,numbers=none]
   764 SEQ(CHAR('f'), SEQ(CHAR('o'), CHAR('r')))
   767 SEQ(CHAR('f'), SEQ(CHAR('o'), CHAR('r')))
   765 \end{lstlisting}
   768 \end{lstlisting}
   770 programming language, you can explicitly write a conversion
   773 programming language, you can explicitly write a conversion
   771 function that takes a string, say \code{for}, and generates the
   774 function that takes a string, say \code{for}, and generates the
   772 regular expression above. But then your code is littered with
   775 regular expression above. But then your code is littered with
   773 such conversion function.
   776 such conversion function.
   774 
   777 
   775 In Scala you can do better by ``hiding'' the conversion 
   778 In Scala you can do better by ``hiding'' the conversion
   776 functions. The keyword for doing this is \code{implicit}.
   779 functions. The keyword for doing this is \code{implicit} and
       
   780 it needs a built-in library called \code{implicitConversions}.
   777 Consider the code
   781 Consider the code
   778 
   782 
   779 
   783 
   780 \begin{lstlisting}[language=Scala]
   784 \begin{lstlisting}[language=Scala]
   781 import scala.language.implicitConversions
   785 import scala.language.implicitConversions
   799 effect will be that whenever Scala expects a regular
   803 effect will be that whenever Scala expects a regular
   800 expression, but I only give it a string, it will automatically
   804 expression, but I only give it a string, it will automatically
   801 insert a call to the \code{string2rexp}-function. I can now
   805 insert a call to the \code{string2rexp}-function. I can now
   802 write for example
   806 write for example
   803 
   807 
   804 
       
   805 \begin{lstlisting}[language=Scala,numbers=none]
   808 \begin{lstlisting}[language=Scala,numbers=none]
   806 scala> ALT("ab", "ac")
   809 scala> ALT("ab", "ac")
   807 res9: ALT = ALT(SEQ(CHAR(a),CHAR(b)),SEQ(CHAR(a),CHAR(c)))
   810 res9: ALT = ALT(SEQ(CHAR(a),CHAR(b)),SEQ(CHAR(a),CHAR(c)))
   808 \end{lstlisting}
   811 \end{lstlisting}
   809 
   812 
   810 
   813 \noindent \code{ALT} expects two regular expressions
       
   814 as arguments, but I only supply two strings. The implicit
       
   815 conversion function will transform the string into
       
   816 a regular expression.
   811 
   817 
   812 Using implicit definitions, Scala allows me to introduce
   818 Using implicit definitions, Scala allows me to introduce
   813 some further syntactic sugar for regular expressions:
   819 some further syntactic sugar for regular expressions:
   814 
   820 
   815 
   821 
   922 
   928 
   923 
   929 
   924 \noindent Rather than returning \code{false}, this code should
   930 \noindent Rather than returning \code{false}, this code should
   925 throw a typing-error. There are also many limitations Scala
   931 throw a typing-error. There are also many limitations Scala
   926 inherited from the JVM that can be really annoying. For
   932 inherited from the JVM that can be really annoying. For
   927 example a fixed stack size. 
   933 example a fixed stack size. One can work around this
       
   934 particular limitation, but why does one have to?
   928 
   935 
   929 Even if Scala has been a success in several high-profile
   936 Even if Scala has been a success in several high-profile
   930 companies, there is also a company (Yammer) that first used
   937 companies, there is also a company (Yammer) that first used
   931 Scala in their production code, but then moved away from it.
   938 Scala in their production code, but then moved away from it.
   932 Allegedly they did not like the steep learning curve of Scala
   939 Allegedly they did not like the steep learning curve of Scala