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 |
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 |