122 \definecolor{cellbackground}{HTML}{F7F7F7} |
122 \definecolor{cellbackground}{HTML}{F7F7F7} |
123 |
123 |
124 |
124 |
125 |
125 |
126 \begin{document} |
126 \begin{document} |
127 \fnote{\copyright{} Christian Urban, King's College London, 2017, 2018, 2019, 2020, 2021, 2022} |
127 \fnote{\copyright{} Christian Urban, King's College London, 2017, 2018, 2019, 2020, 2021, 2022, 2023} |
128 |
128 |
129 %\begin{tcolorbox}[breakable,size=fbox,boxrule=1pt,pad at break*=1mm,colback=cellbackground,colframe=cellborder] |
129 %\begin{tcolorbox}[breakable,size=fbox,boxrule=1pt,pad at break*=1mm,colback=cellbackground,colframe=cellborder] |
130 % abd |
130 % abd |
131 %\end{tcolorbox} |
131 %\end{tcolorbox} |
132 |
132 |
133 \section*{A Crash-Course in Scala} |
133 \section*{A Crash-Course in Scala} |
134 |
134 |
135 \mbox{}\hfill\textit{``Scala --- \underline{S}lowly \underline{c}ompiled |
135 \mbox{}\hfill\textit{``Scala --- \underline{S}lowly \underline{c}ompiled |
136 \underline{a}cademic \underline{la}nguage''}\smallskip\\ |
136 \underline{a}cademic \underline{la}nguage''}\smallskip\\ |
137 \mbox{}\hfill\textit{ --- a joke(?) found on Twitter}\bigskip |
137 \mbox{}\hfill\textit{ --- a joke(?) found on Twitter}\bigskip |
|
138 |
|
139 \mbox{}\hfill\textit{``Life is too short for \texttt{malloc}.''}\smallskip\\ |
|
140 \mbox{}\hfill\textit{ --- said Neal Ford at Oscon'13}\;\hr{https://www.youtube.com/watch?v=7aYS9PcAITQ}\bigskip\\ |
|
141 |
138 |
142 |
139 \subsection*{Introduction} |
143 \subsection*{Introduction} |
140 |
144 |
141 \noindent |
145 \noindent |
142 Scala is a programming language that combines functional and |
146 Scala is a programming language that combines functional and |
148 the myriads of Java libraries. Unlike Java, however, Scala often allows |
152 the myriads of Java libraries. Unlike Java, however, Scala often allows |
149 programmers to write very concise and elegant code. Some therefore say |
153 programmers to write very concise and elegant code. Some therefore say |
150 ``Scala is the better Java''.\footnote{from |
154 ``Scala is the better Java''.\footnote{from |
151 \url{https://www.slideshare.net/maximnovak/joy-of-scala}} |
155 \url{https://www.slideshare.net/maximnovak/joy-of-scala}} |
152 |
156 |
153 A number of companies---the Guardian, Twitter, Coursera, FourSquare, |
157 A number of companies---the Guardian, Dualingo, Coursera, FourSquare, |
154 Netflix, LinkedIn, ITV to name a few---either use Scala exclusively in |
158 Netflix, LinkedIn, ITV to name a few---either use Scala exclusively in |
155 production code, or at least to some substantial degree. Scala seems |
159 production code, or at least to some substantial degree. Scala seems |
156 also useful in job-interviews (especially in data science) according to |
160 also useful in job-interviews (especially in data science) according to |
157 this anecdotal report |
161 this anecdotal report |
158 |
162 |
166 \begin{quote} |
170 \begin{quote} |
167 \url{http://www.scala-lang.org}\medskip |
171 \url{http://www.scala-lang.org}\medskip |
168 \end{quote} |
172 \end{quote} |
169 |
173 |
170 \noindent\alert |
174 \noindent\alert |
171 Just make sure you are downloading the ``battle tested'' version of |
175 Just make sure you are using the version 3(!) of Scala. This is |
172 Scala \textbf{2.13} This is the one I am going to use in the lectures and |
176 the version I am going to use in the lectures and in the coursework. This |
173 in the coursework. The newer Scala 3.1 \& 3.2 still have some |
177 can be any version of Scala 3.X where $X=\{1,2,3\}$. Also the minor |
174 features not fully implemented.\bigskip |
178 number does not matter. Note that this will be the first year I am |
175 |
179 using this version -- so some hiccups are bound to happen. Apologies |
176 \noindent |
180 in advance!\bigskip |
177 If you are interested, there are also experimental backends of Scala |
181 |
178 for producing code under Android (\url{http://scala-android.org}); for |
182 \noindent |
179 generating JavaScript code (\url{https://www.scala-js.org}); and there |
183 If you are interested, there are also experimental backend of Scala |
180 is work under way to have a native Scala compiler generating X86-code |
184 for generating JavaScript code (\url{https://www.scala-js.org}), and |
181 (\url{http://www.scala-native.org}). Though be warned these backends |
185 there is work under way to have a native Scala compiler generating |
182 are still rather beta or even alpha. |
186 X86-code (\url{http://www.scala-native.org}). There are also some |
|
187 tricks you can play with Scala programms running as native |
|
188 GraalVM~\hr{https://scala-cli.virtuslab.org/docs/cookbooks/native-images/} |
|
189 images. Though be warned these backends are still rather beta or even |
|
190 alpha. |
183 |
191 |
184 \subsection*{VS Code and Scala} |
192 \subsection*{VS Code and Scala} |
185 |
193 |
186 I found a convenient IDE for writing Scala programs is Microsoft's |
194 I found a convenient IDE for writing Scala programs is Microsoft's |
187 \textit{Visual Studio Code} (VS Code) which runs under MacOSX, Linux and |
195 \textit{Visual Studio Code} (VS Code) which runs under MacOSX, Linux and |
261 \noindent |
270 \noindent |
262 Also IntelliJ includes plugins for Scala. \underline{\textbf{BUT}}, |
271 Also IntelliJ includes plugins for Scala. \underline{\textbf{BUT}}, |
263 I do \textbf{not} recommend the usage of either Eclipse or IntelliJ for PEP: these IDEs |
272 I do \textbf{not} recommend the usage of either Eclipse or IntelliJ for PEP: these IDEs |
264 seem to make your life harder, rather than easier, for the small |
273 seem to make your life harder, rather than easier, for the small |
265 programs that we will write in this module. They are really meant to be used |
274 programs that we will write in this module. They are really meant to be used |
266 when you have a million-lines codebase than with our small |
275 when you have a million-lines codebase instead of our small |
267 ``toy-programs''\ldots{}for example why on earth am I required to create a |
276 ``toy-programs''\ldots{}for example why on earth am I required to create a |
268 completely new project with several subdirectories when I just want to |
277 completely new project with several subdirectories when I just want to |
269 try out 20-lines of Scala code? Your mileage may vary though.~\texttt{;o)} |
278 try out 20-lines of Scala code? Your mileage may vary though.~\texttt{;o)} |
270 |
279 |
271 \subsection*{Why Functional Programming?} |
280 \subsection*{Why Functional Programming?} |
285 %Your friendly lecturer just |
294 %Your friendly lecturer just |
286 %happens to like Scala and the Department agreed that it is a good idea |
295 %happens to like Scala and the Department agreed that it is a good idea |
287 %to inflict Scala upon you. |
296 %to inflict Scala upon you. |
288 |
297 |
289 Very likely writing programs in a functional programming language is |
298 Very likely writing programs in a functional programming language is |
290 quite different from what you are used to in your study so far. It |
299 quite different from what you are used to in your study so far. It |
291 might even be totally alien to you. The reason is that functional |
300 might even be totally alien to you. The reason is that functional |
292 programming seems to go against the core principles of |
301 programming seems to go against the core principles of |
293 \textit{imperative programming} (which is what you do in Java and C/C++ |
302 \textit{imperative programming} (which is what you do in Java and |
294 for example). The main idea of imperative programming is that you have |
303 C/C++ for example). The main idea of imperative programming is that |
295 some form of \emph{state} in your program and you continuously change |
304 you have some form of \emph{state} in your program and you |
296 this state by issuing some commands---for example for updating a field |
305 continuously change this state by issuing some commands---for example |
297 in an array or for adding one to a variable and so on. The classic |
306 for updating a field in an array or for adding one to a variable |
298 example for this style of programming is a \texttt{for}-loop in C/C++. |
307 stored in memory and so on. The classic example for this style of |
299 Consider the snippet: |
308 programming is a \texttt{for}-loop in C/C++. Consider the snippet: |
300 |
309 |
301 \begin{lstlisting}[language=C,numbers=none] |
310 \begin{lstlisting}[language=C,numbers=none] |
302 for (int i = 10; i < 20; i++) { |
311 for (int i = 10; i < 20; i++) { |
303 //...do something with i... |
312 //...do something with i... |
304 } |
313 } |
305 \end{lstlisting} |
314 \end{lstlisting} |
306 |
315 |
307 \noindent Here the integer variable \texttt{i} embodies the state, which |
316 \noindent Here the integer variable \texttt{i} embodies part of the |
308 is first set to \texttt{10} and then increased by one in each |
317 state of the program, which is first set to \texttt{10} and then |
309 loop-iteration until it reaches \texttt{20} at which point the loop |
318 increased by one in each loop-iteration until it reaches \texttt{20} |
310 exits. When this code is compiled and actually runs, there will be some |
319 at which point the loop exits. When this code is compiled and actually |
311 dedicated space reserved for \texttt{i} in memory. This space of |
320 runs, there will be some dedicated space reserved for \texttt{i} in |
312 typically 32 bits contains \texttt{i}'s current value\ldots\texttt{10} |
321 memory. This space of typically 32 bits contains \texttt{i}'s current |
313 at the beginning, and then the content will be overwritten with |
322 value\ldots\texttt{10} at the beginning, and then the content will be |
314 new content in every iteration. The main point here is that this kind of |
323 overwritten with new content in every iteration. The main point here |
315 updating, or overwriting, of memory is 25.806\ldots or \textbf{THE ROOT OF |
324 is that this kind of updating, or overwriting, of memory is |
316 ALL EVIL}!! |
325 25.806\ldots or \textbf{THE ROOT OF ALL EVIL}!! |
317 |
326 |
318 \begin{center} |
327 \begin{center} |
319 \includegraphics[scale=0.25]{../pics/root-of-all-evil.png} |
328 \includegraphics[scale=0.25]{../pics/root-of-all-evil.png} |
320 \end{center} |
329 \end{center} |
321 |
330 |
334 Unfortunately this does not happen any more nowadays. To get you out of |
343 Unfortunately this does not happen any more nowadays. To get you out of |
335 this dreadful situation, CPU producers pile more and more cores into |
344 this dreadful situation, CPU producers pile more and more cores into |
336 CPUs in order to make them more powerful and potentially make software |
345 CPUs in order to make them more powerful and potentially make software |
337 faster. The task for you as developer is to take somehow advantage of |
346 faster. The task for you as developer is to take somehow advantage of |
338 these cores by running as much of your code as possible in parallel on |
347 these cores by running as much of your code as possible in parallel on |
339 as many cores you have available (typically 4 or more in modern laptops |
348 as many cores you have available (typically 4-8 or even more in modern laptops |
340 and sometimes much more on high-end machines). In this situation |
349 and sometimes much more on high-end machines). In this situation |
341 \textit{mutable} variables like \texttt{i} in the C-code above are evil, |
350 \textit{mutable} variables like \texttt{i} in the C-code above are evil, |
342 or at least a major nuisance: Because if you want to distribute some of |
351 or at least a major nuisance: Because if you want to distribute some of |
343 the loop-iterations over several cores that are currently idle in your |
352 the loop-iterations over several cores that are currently idle in your |
344 system, you need to be extremely careful about who can read and |
353 system, you need to be extremely careful about who can read and |
469 interest, borrows many ideas from functional programming from |
478 interest, borrows many ideas from functional programming from |
470 yesteryear.}\medskip |
479 yesteryear.}\medskip |
471 |
480 |
472 \noindent |
481 \noindent |
473 If you need any after-work distractions, you might have fun reading |
482 If you need any after-work distractions, you might have fun reading |
474 this about FP (functional programming) --- you |
483 the following article about FP (functional programming) --- you |
475 might have to disable your browser cookies though if you want to read |
484 might have to disable your browser cookies though if you want to read |
476 it for free. And spoiler alert: This is tongue-in-cheek \texttt{;o)} |
485 it for free. And spoiler alert: This is tongue-in-cheek \texttt{;o)} |
477 |
486 |
478 \begin{quote} |
487 \begin{quote} |
479 \url{https://betterprogramming.pub/fp-toy-7f52ea0a947e} |
488 \url{https://archive.ph/vrofC} |
480 \end{quote} |
489 \end{quote} |
481 |
490 |
482 \subsection*{The Very Basics} |
491 \subsection*{The Very Basics} |
483 |
492 |
484 One advantage of Scala over Java is that it includes an interpreter (a |
493 Let us get back to Scala: One advantage of Scala over Java is that it |
485 REPL, or |
494 includes an interpreter (a REPL, or |
486 \underline{R}ead-\underline{E}val-\underline{P}rint-\underline{L}oop) |
495 \underline{R}ead-\underline{E}val-\underline{P}rint-\underline{L}oop) |
487 with which you can run and test small code snippets without the need |
496 with which you can run and test small code snippets without the need |
488 of a compiler. This helps a lot with interactively developing |
497 of a compiler. This helps a lot with interactively developing |
489 programs. It is my preferred way of writing small Scala |
498 programs. It is my preferred way of writing small Scala programs. Once |
490 programs. Once you installed Scala, you can start the interpreter by |
499 you installed Scala, you can start the interpreter by typing on the |
491 typing on the command line: |
500 command line: |
492 |
501 |
493 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
502 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
494 $ scala |
503 $ scala |
495 Welcome to Scala 2.13.9 (OpenJDK 64-Bit Server VM, Java 17.0.1). |
504 Welcome to Scala 3.3.1 (17.0.8.1, Java OpenJDK 64-Bit Server VM). |
496 Type in expressions for evaluation. Or try :help. |
505 Type in expressions for evaluation. Or try :help. |
497 |
506 |
498 scala> |
507 scala> |
499 \end{lstlisting}%$ |
508 \end{lstlisting}%$ |
500 |
509 |
501 |
|
502 |
|
503 \noindent The precise response may vary depending |
510 \noindent The precise response may vary depending |
504 on the version and platform where you installed Scala. At the Scala |
511 on the version and platform where you installed Scala. Make sure |
|
512 you have installed Scala version 3. At the Scala |
505 prompt you can type things like \code{2 + 3}\;\keys{Ret} and |
513 prompt you can type things like \code{2 + 3}\;\keys{Ret} and |
506 the output will be |
514 the output will be |
507 |
515 |
508 \begin{lstlisting}[numbers=none] |
516 \begin{lstlisting}[numbers=none,language={}] |
509 scala> 2 + 3 |
517 scala> 2 + 3 |
510 res0: Int = 5 |
518 val res0: Int = 5 |
511 \end{lstlisting} |
519 \end{lstlisting} |
512 |
520 |
513 \noindent The answer means that he result of the addition is of type |
521 \noindent The answer means that he result of the addition is of type |
514 \code{Int} and the actual result is 5; \code{res0} is a name that |
522 \code{Int} and the actual result is 5; \code{res0} is a name that |
515 Scala gives automatically to the result. You can reuse this name later |
523 Scala gives automatically to the result. You can reuse this name later |
516 on, for example |
524 on, for example |
517 |
525 |
518 \begin{lstlisting}[numbers=none] |
526 \begin{lstlisting}[numbers=none,language={}] |
519 scala> res0 + 4 |
527 scala> res0 + 4 |
520 res1: Int = 9 |
528 val res1: Int = 9 |
521 \end{lstlisting} |
529 \end{lstlisting} |
522 |
530 |
523 \noindent |
531 \noindent |
524 Another classic example you can try out is |
532 Another classic example you can try out is |
525 |
533 |
526 \begin{lstlisting}[numbers=none] |
534 \begin{lstlisting}[numbers=none,language={}] |
527 scala> print("hello world") |
535 scala> print("hello world") |
528 hello world |
536 hello world |
529 \end{lstlisting} |
537 \end{lstlisting} |
530 |
538 |
531 \noindent Note that in this case there is no result. The |
539 \noindent Note that in this case there is no result. The |
618 \noindent You might need to adapt the path to where you have |
626 \noindent You might need to adapt the path to where you have |
619 installed Scala. |
627 installed Scala. |
620 |
628 |
621 \subsection*{Values} |
629 \subsection*{Values} |
622 |
630 |
|
631 \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black] |
|
632 Do not use \code{var} in your code for PEP! This declares a mutable variable. |
|
633 Only use \code{val}! |
|
634 \end{tcolorbox}\medskip |
|
635 |
|
636 \noindent |
623 In the lectures I will try to avoid as much as possible the term |
637 In the lectures I will try to avoid as much as possible the term |
624 \emph{variables} familiar from other programming languages. The reason |
638 \emph{variables} familiar from other programming languages. The reason |
625 is that Scala has \emph{values}, which can be seen as abbreviations of |
639 is that Scala has \emph{values}, which can be seen as abbreviations of |
626 larger expressions. The keyword for defining values is \code{val}. |
640 larger expressions. The keyword for defining values is \code{val}. |
627 For example |
641 For example |
628 |
642 |
629 \begin{lstlisting}[numbers=none] |
643 \begin{lstlisting}[numbers=none] |
630 scala> val x = 42 |
644 scala> val x = 42 |
631 x: Int = 42 |
645 val x: Int = 42 |
632 |
646 |
633 scala> val y = 3 + 4 |
647 scala> val y = 3 + 4 |
634 y: Int = 7 |
648 val y: Int = 7 |
635 |
649 |
636 scala> val z = x / y |
650 scala> val z = x / y |
637 z: Int = 6 |
651 val z: Int = 6 |
638 \end{lstlisting} |
652 \end{lstlisting} |
639 |
653 |
640 \noindent |
654 \noindent |
641 As can be seen, we first define \code{x} and {y} with admittedly some silly |
655 As can be seen, we first define \code{x} and {y} with admittedly some silly |
642 expressions, and then reuse these values in the definition of \code{z}. |
656 expressions, and then reuse these values in the definition of \code{z}. |
707 |
724 |
708 \noindent |
725 \noindent |
709 where each argument, \texttt{arg1}, \texttt{arg2} and so on, requires |
726 where each argument, \texttt{arg1}, \texttt{arg2} and so on, requires |
710 its type and the result type of the |
727 its type and the result type of the |
711 function, \code{rty}, should also be given. If the body of the function is |
728 function, \code{rty}, should also be given. If the body of the function is |
712 more complex, then it can be enclosed in braces, like above. If it it |
729 more complex, then it can be enclosed in braces, like above. If it |
713 is just a simple expression, like \code{x + 1}, you can omit the |
730 is just a simple expression, like \code{x + 1}, you can omit the |
714 braces. Very often functions are recursive (that is call themselves), |
731 braces. Very often functions are recursive (that is call themselves), |
715 like the venerable factorial function: |
732 like the venerable factorial function: |
716 |
733 |
717 \begin{lstlisting}[numbers=none] |
734 \begin{lstlisting}[numbers=none] |
718 def fact(n: Int) : Int = |
735 def fact(n: Int) : Int = |
719 if (n == 0) 1 else n * fact(n - 1) |
736 if (n == 0) 1 else n * fact(n - 1) |
720 \end{lstlisting} |
737 \end{lstlisting} |
721 |
738 |
722 \noindent |
739 \noindent |
723 We could also have written this with braces as |
740 where we have to give the return type \code{Int}. Note we could also |
|
741 have written this with braces as |
724 |
742 |
725 \begin{lstlisting}[numbers=none] |
743 \begin{lstlisting}[numbers=none] |
726 def fact(n: Int) : Int = { |
744 def fact(n: Int) : Int = { |
727 if (n == 0) 1 |
745 if (n == 0) 1 |
728 else n * fact(n - 1) |
746 else n * fact(n - 1) |
729 } |
747 } |
730 \end{lstlisting} |
748 \end{lstlisting} |
731 |
749 |
732 \noindent |
750 \noindent |
733 but this seems a bit overkill for a small function like \code{fact}. |
751 but this seems a bit overkill for a small function like \code{fact}. |
734 Note that Scala does not have a \code{then}-keyword in an |
752 Notice that Scala does not have a \code{then}-keyword in an |
735 \code{if}-statement. Also important is that there should be always an |
753 \code{if}-statement. Also important is that there should be always an |
736 \code{else}-branch. Never write an \code{if} without an \code{else}, |
754 \code{else}-branch. Never write an \code{if} without an \code{else}, |
737 unless you know what you are doing! While \code{def} is the main |
755 unless you know what you are doing! While \code{def} is the main |
738 mechanism for defining functions, there are a few other ways for doing |
756 mechanism for defining functions, there are a few other ways for doing |
739 this. We will see some of them in the next sections. |
757 this. We will see some of them in the next sections. |
818 \end{lstlisting} |
837 \end{lstlisting} |
819 |
838 |
820 \noindent |
839 \noindent |
821 which still satisfies the rule-of-thumb. |
840 which still satisfies the rule-of-thumb. |
822 |
841 |
|
842 \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black] |
|
843 Do not use \code{return} in your code to indicate what a function |
|
844 produces as a result! It has a different meaning in Scala than in |
|
845 Java. It can change the meaning of your program, and you should |
|
846 never use it. |
|
847 \end{tcolorbox} |
|
848 |
823 |
849 |
824 \subsection*{Loops, or Better the Absence Thereof} |
850 \subsection*{Loops, or Better the Absence Thereof} |
825 |
851 |
826 Coming from Java or C/C++, you might be surprised that Scala does |
852 Coming from Java or C/C++, you might be surprised that Scala does |
827 not really have loops. It has instead, what is in functional |
853 not really have loops. It has instead, what is in functional |
828 programming called, \emph{maps}. To illustrate how they work, |
854 programming called, \emph{maps}. To illustrate how they work, |
829 let us assume you have a list of numbers from 1 to 8 and want to |
855 let us assume you have a list of numbers from 1 to 8 and want to |
830 build the list of squares. The list of numbers from 1 to 8 |
856 build the list of squares. The list of numbers from 1 to 8 |
831 can be constructed in Scala as follows: |
857 can be constructed in Scala as follows: |
832 |
858 |
833 \begin{lstlisting}[numbers=none] |
859 \begin{lstlisting}[numbers=none,language={}] |
834 scala> (1 to 8).toList |
860 scala> (1 to 8).toList |
835 res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8) |
861 val res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8) |
836 \end{lstlisting} |
862 \end{lstlisting} |
837 |
863 |
838 \noindent Generating from this list the list of corresponding |
864 \noindent Generating from this list the list of corresponding |
839 squares in a programming language such as Java, you would assume |
865 squares in a programming language such as Java, you would assume |
840 the list is given as a kind of array. You would then iterate, or loop, |
866 the list is given as a kind of array. You would then iterate, or loop, |
902 \code{yield}. Squaring the numbers from 1 to 8 with a for-comprehension |
928 \code{yield}. Squaring the numbers from 1 to 8 with a for-comprehension |
903 would look as follows: |
929 would look as follows: |
904 |
930 |
905 \begin{lstlisting}[numbers=none] |
931 \begin{lstlisting}[numbers=none] |
906 scala> for (n <- (1 to 8).toList) yield n * n |
932 scala> for (n <- (1 to 8).toList) yield n * n |
907 res2: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) |
933 val res2: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) |
908 \end{lstlisting} |
934 \end{lstlisting} |
909 |
935 |
910 \noindent This for-comprehension states that from the list of numbers |
936 \noindent This for-comprehension states that from the list of numbers |
911 we draw some elements. We use the name \code{n} to range over these |
937 we draw some elements. We use the name \code{n} to range over these |
912 elements (whereby the name is arbitrary; we could use something more |
938 elements (whereby the name is arbitrary; we could use something more |
922 scala> for (n <- (1 to 8).toList) yield { |
948 scala> for (n <- (1 to 8).toList) yield { |
923 val i = n + 1 |
949 val i = n + 1 |
924 val j = n - 1 |
950 val j = n - 1 |
925 i * j + 1 |
951 i * j + 1 |
926 } |
952 } |
927 res3: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) |
953 val res3: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) |
928 \end{lstlisting} |
954 \end{lstlisting} |
929 |
955 |
930 As you can see in for-comprehensions above, we specified the list where |
956 Let us come back to the simple example of squaring a list of numbers. |
931 each \code{n} comes from, namely \code{(1 to 8).toList}, and how each |
957 As you can see in the for-comprehensions above, we specified the list |
932 element needs to be transformed. This can also be expressed in a second |
958 where each \code{n} comes from, namely \code{(1 to 8).toList}, and how |
933 way in Scala by using directly the function \code{map} as follows: |
959 each element needs to be transformed, the expression after the |
934 |
960 \code{yield}. This can also be expressed in a second way in Scala by |
935 \begin{lstlisting}[numbers=none] |
961 using directly the function \code{map} as follows: |
|
962 |
|
963 \begin{lstlisting}[numbers=none,language={}] |
936 scala> (1 to 8).toList.map(n => n * n) |
964 scala> (1 to 8).toList.map(n => n * n) |
937 res3 = List(1, 4, 9, 16, 25, 36, 49, 64) |
965 val res3 = List(1, 4, 9, 16, 25, 36, 49, 64) |
938 \end{lstlisting} |
966 \end{lstlisting} |
939 |
967 |
940 \noindent In this way, the expression \code{n => n * n} stands for the |
968 \noindent In this way, the expression \code{n => n * n} stands for the |
941 function that calculates the square (this is how the \code{n}s are |
969 function that calculates the square (this is how the \code{n}s are |
942 transformed by the map). It might not be obvious, but |
970 transformed by the map). It might not be obvious, but |
947 The very charming feature of Scala is that such maps or |
975 The very charming feature of Scala is that such maps or |
948 for-comprehensions can be written for any kind of data collection, such |
976 for-comprehensions can be written for any kind of data collection, such |
949 as lists, sets, vectors, options and so on. For example if we instead |
977 as lists, sets, vectors, options and so on. For example if we instead |
950 compute the remainders modulo 3 of this list, we can write |
978 compute the remainders modulo 3 of this list, we can write |
951 |
979 |
952 \begin{lstlisting}[numbers=none] |
980 \begin{lstlisting}[numbers=none,language={}] |
953 scala> (1 to 8).toList.map(n => n % 3) |
981 scala> (1 to 8).toList.map(n => n % 3) |
954 res4 = List(1, 2, 0, 1, 2, 0, 1, 2) |
982 val res4 = List(1, 2, 0, 1, 2, 0, 1, 2) |
955 \end{lstlisting} |
983 \end{lstlisting} |
956 |
984 |
957 \noindent If we, however, transform the numbers 1 to 8 not |
985 \noindent If we, however, transform the numbers 1 to 8 not |
958 into a list, but into a set, and then compute the remainders |
986 into a list, but into a set, and then compute the remainders |
959 modulo 3 we obtain |
987 modulo 3 we obtain |
960 |
988 |
961 \begin{lstlisting}[numbers=none] |
989 \begin{lstlisting}[numbers=none,language={}] |
962 scala> (1 to 8).toSet[Int].map(n => n % 3) |
990 scala> (1 to 8).toSet.map(n => n % 3) |
963 res5 = Set(2, 1, 0) |
991 val res5 = Set(2, 1, 0) |
964 \end{lstlisting} |
992 \end{lstlisting} |
965 |
993 |
966 \noindent This\footnote{This returns actually \code{HashSet(2, 1, 3)}, |
994 \noindent This\footnote{This returns actually \code{HashSet(1, 2, 3)}, |
967 but this is just an implementation detail of how sets are implemented in |
995 but this is just an implementation detail of how sets are implemented in |
968 Scala.} is the correct result for sets, as there are only three |
996 Scala.} is the correct result for sets, as there are only three |
969 equivalence classes of integers modulo 3. Note that in this example we |
997 equivalence classes of integers modulo 3. Since maps and |
970 need to ``help'' Scala to transform the numbers into a set of integers |
|
971 by explicitly annotating the type \code{Int}. Since maps and |
|
972 for-comprehensions are just syntactic variants of each other, the latter |
998 for-comprehensions are just syntactic variants of each other, the latter |
973 can also be written as |
999 can also be written as |
974 |
1000 |
975 \begin{lstlisting}[numbers=none] |
1001 \begin{lstlisting}[numbers=none] |
976 scala> for (n <- (1 to 8).toSet[Int]) yield n % 3 |
1002 scala> for (n <- (1 to 8).toSet) yield n % 3 |
977 res5 = Set(2, 1, 0) |
1003 val res5 = Set(2, 1, 0) |
978 \end{lstlisting} |
1004 \end{lstlisting} |
979 |
1005 |
980 For-comprehensions can also be nested and the selection of |
1006 For-comprehensions can also be nested and the selection of |
981 elements can be guarded. For example if we want to pair up |
1007 elements can be guarded (or filtered). For example if we want to pair up |
982 the numbers 1 to 4 with the letters a to c, we can write |
1008 the numbers 1 to 4 with the letters a to c, we can write |
983 |
1009 |
984 \begin{lstlisting}[numbers=none] |
1010 \begin{lstlisting}[numbers=none] |
985 scala> for (n <- (1 to 4).toList; |
1011 scala> for (n <- (1 to 4).toList; |
986 m <- ('a' to 'c').toList) yield (n, m) |
1012 m <- ('a' to 'c').toList) yield (n, m) |
987 res6 = List((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), |
1013 val res6 = List((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), |
988 (3,a), (3,b), (3,c), (4,a), (4,b), (4,c)) |
1014 (3,a), (3,b), (3,c), (4,a), (4,b), (4,c)) |
989 \end{lstlisting} |
1015 \end{lstlisting} |
990 |
1016 |
991 \noindent |
1017 \noindent |
992 In this example the for-comprehension ranges over two lists, and |
1018 In this example the for-comprehension ranges over two lists, and |
993 produces a list of pairs as output. Or, if we want to find all pairs of |
1019 produces a list of pairs as output. Or, if we want to find all pairs of |
995 |
1021 |
996 \begin{lstlisting}[numbers=none] |
1022 \begin{lstlisting}[numbers=none] |
997 scala> for (n <- (1 to 3).toList; |
1023 scala> for (n <- (1 to 3).toList; |
998 m <- (1 to 3).toList; |
1024 m <- (1 to 3).toList; |
999 if (n + m) % 2 == 0) yield (n, m) |
1025 if (n + m) % 2 == 0) yield (n, m) |
1000 res7 = List((1,1), (1,3), (2,2), (3,1), (3,3)) |
1026 val res7 = List((1,1), (1,3), (2,2), (3,1), (3,3)) |
1001 \end{lstlisting} |
1027 \end{lstlisting} |
1002 |
1028 |
1003 \noindent The \code{if}-condition in this for-comprehension filters out |
1029 \noindent The \code{if}-condition in this for-comprehension filters out |
1004 all pairs where the sum is not even (therefore \code{(1, 2)}, \code{(2, |
1030 all pairs where the sum is not even (therefore \code{(1, 2)}, \code{(2, |
1005 1)} and \code{(3, 2)} are not in the result because their sum is odd). |
1031 1)} and \code{(3, 2)} are not in the result because their sum is odd). |
1011 |
1037 |
1012 \begin{lstlisting}[numbers=none] |
1038 \begin{lstlisting}[numbers=none] |
1013 scala> val cs = ('a' to 'h').toList |
1039 scala> val cs = ('a' to 'h').toList |
1014 scala> for (n <- (0 until cs.length).toList) |
1040 scala> for (n <- (0 until cs.length).toList) |
1015 yield cs(n).capitalize |
1041 yield cs(n).capitalize |
1016 res8: List[Char] = List(A, B, C, D, E, F, G, H) |
1042 val res8: List[Char] = List(A, B, C, D, E, F, G, H) |
1017 \end{lstlisting} |
1043 \end{lstlisting} |
1018 |
1044 |
1019 \noindent |
1045 \noindent |
1020 This is accepted Scala-code, but utterly bad style (it is more like |
1046 This is accepted Scala-code, but utterly bad style (it is more like |
1021 Java). It can be written much clearer as: |
1047 Java). It can be written much clearer as: |
1022 |
1048 |
1023 \begin{lstlisting}[numbers=none] |
1049 \begin{lstlisting}[numbers=none] |
1024 scala> val cs = ('a' to 'h').toList |
1050 scala> val cs = ('a' to 'h').toList |
1025 scala> for (c <- cs) yield c.capitalize |
1051 scala> for (c <- cs) yield c.capitalize |
1026 res9: List[Char] = List(A, B, C, D, E, F, G, H) |
1052 val res9: List[Char] = List(A, B, C, D, E, F, G, H) |
1027 \end{lstlisting} |
1053 \end{lstlisting} |
1028 |
1054 |
1029 \subsection*{Results and Side-Effects} |
1055 \subsection*{Results and Side-Effects} |
1030 |
1056 |
1031 While hopefully all this about maps looks reasonable, there is one |
1057 While hopefully all this about maps looks reasonable, there is one |
1267 \noindent |
1293 \noindent |
1268 As said, this is example is a bit contrived---I was not able to think |
1294 As said, this is example is a bit contrived---I was not able to think |
1269 of anything simple, but for example in the Compiler module next year I |
1295 of anything simple, but for example in the Compiler module next year I |
1270 show a compilation functions that needs to generate functions as |
1296 show a compilation functions that needs to generate functions as |
1271 intermediate result. Anyway, notice the interesting type we had to |
1297 intermediate result. Anyway, notice the interesting type we had to |
1272 annotate to \code{mkfn}. Types of Scala are described next. |
1298 annotate to \code{mkfn}. The types in Scala are described next. |
1273 |
1299 |
1274 |
1300 |
1275 \subsection*{Types} |
1301 \subsection*{Types} |
1276 |
1302 |
1277 In most functional programming languages, types play an |
1303 In most functional programming languages, types play an |
1278 important role. Scala is such a language. You have already |
1304 essential role. Scala is such a language. You have already |
1279 seen built-in types, like \code{Int}, \code{Boolean}, |
1305 seen built-in types, like \code{Int}, \code{Boolean}, |
1280 \code{String} and \code{BigInt}, but also user-defined ones, |
1306 \code{String} and \code{BigInt}, but also user-defined ones, |
1281 like \code{Rexp} (see coursework). Unfortunately, types can be a thorny |
1307 like \code{Rexp} (see coursework). Unfortunately, types can be a thorny |
1282 subject, especially in Scala. For example, why do we need to |
1308 subject, especially in Scala. For example, why do we need to |
1283 give the type to \code{toSet[Int]}, but not to \code{toList}? |
1309 give the type to \code{toSet[Int]}, but not to \code{toList}? |
1300 and \code{String}. Compound types take one or more arguments, |
1326 and \code{String}. Compound types take one or more arguments, |
1301 which as seen earlier need to be given in angle-brackets, for |
1327 which as seen earlier need to be given in angle-brackets, for |
1302 example \code{List[Int]} or \code{Set[List[String]]} or |
1328 example \code{List[Int]} or \code{Set[List[String]]} or |
1303 \code{Map[Int, Int]}. |
1329 \code{Map[Int, Int]}. |
1304 |
1330 |
|
1331 Scala provides a basic mechanism to check the type of a (closed) |
|
1332 expression---closed means that all parts are already known to Scala. |
|
1333 Then you can use the command \code{:type} and check in the REPL: |
|
1334 |
|
1335 \begin{lstlisting}[ numbers=none] |
|
1336 scala> :type (1, List(3), Set(4,5), "hello") |
|
1337 (Int, List[Int], Set[Int], String) |
|
1338 \end{lstlisting} |
|
1339 |
|
1340 \noindent |
|
1341 If Scala can calculate the type of the given expression, then it |
|
1342 will print it. Unfortunately, this way of finding out a type is almost |
|
1343 unusable: for `things' where the type is pretty obvious, it gives an |
|
1344 answer; but for `things' that are actually of interest (such as |
|
1345 what is the type of a pre-defined function), it gives up with |
|
1346 an error message. |
|
1347 |
1305 There are a few special type-constructors that fall outside |
1348 There are a few special type-constructors that fall outside |
1306 this pattern. One is for tuples, where the type is written |
1349 this pattern. One is for tuples, where the type is written |
1307 with parentheses. For example |
1350 with parentheses. For example |
1308 |
1351 |
1309 \begin{lstlisting}[ numbers=none] |
1352 \begin{lstlisting}[ numbers=none] |
1418 res6 = true |
1461 res6 = true |
1419 \end{lstlisting} |
1462 \end{lstlisting} |
1420 |
1463 |
1421 You might ask: Apart from silly functions like above, what is |
1464 You might ask: Apart from silly functions like above, what is |
1422 the point of having functions as input arguments to other |
1465 the point of having functions as input arguments to other |
1423 functions? In Java there is indeed no need of this kind of |
1466 functions? |
1424 feature: at least in the past it did not allow such |
1467 %In Java there is indeed no need of this kind of |
1425 constructions. I think, the point of Java 8 and successors was to lift this |
1468 %feature: at least in the past it did not allow such |
1426 restriction. But in all functional programming languages, |
1469 %constructions. I think, the point of Java 8 and successors was to lift this |
|
1470 %restriction. |
|
1471 Well, in all functional programming languages, |
1427 including Scala, it is really essential to allow functions as |
1472 including Scala, it is really essential to allow functions as |
1428 input argument. Above you have already seen \code{map} and |
1473 input argument. Above you have already seen \code{map} and |
1429 \code{foreach} which need this feature. Consider the functions |
1474 \code{foreach} which need this feature. Consider the functions |
1430 \code{print} and \code{println}, which both print out strings, |
1475 \code{print} and \code{println}, which both print out strings, |
1431 but the latter adds a line break. You can call \code{foreach} |
1476 but the latter adds a line break. You can call \code{foreach} |
1764 \begin{itemize} |
1809 \begin{itemize} |
1765 \item \small\url{http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html} |
1810 \item \small\url{http://docs.scala-lang.org/tutorials/scala-for-java-programmers.html} |
1766 \end{itemize} |
1811 \end{itemize} |
1767 |
1812 |
1768 While I am quite enthusiastic about Scala, I am also happy to |
1813 While I am quite enthusiastic about Scala, I am also happy to |
1769 admit that it has more than its fair share of faults. The |
1814 admit that it has more than its fair share of faults. |
1770 problem seen earlier of having to give an explicit type to |
1815 %The |
1771 \code{toSet}, but not \code{toList} is one of them. There are |
1816 %problem seen earlier of having to give an explicit type to |
1772 also many ``deep'' ideas about types in Scala, which even to |
1817 %\code{toSet}, but not \code{toList} is one of them. There are |
1773 me as seasoned functional programmer are puzzling. Whilst |
1818 %also many ``deep'' ideas about types in Scala, which even to |
|
1819 %me as seasoned functional programmer are puzzling. |
|
1820 For example, whilst |
1774 implicits are great, they can also be a source of great |
1821 implicits are great, they can also be a source of great |
1775 headaches, for example consider the code: |
1822 headaches, for example consider the code: |
1776 |
1823 |
1777 \begin{lstlisting}[numbers=none] |
1824 \begin{lstlisting}[numbers=none] |
1778 scala> List (1, 2, 3) contains "your mom" |
1825 scala> List (1, 2, 3) contains "your mom" |
1797 like the steep learning curve of Scala and also that new versions of |
1844 like the steep learning curve of Scala and also that new versions of |
1798 Scala often introduced incompatibilities in old code. Also the Java |
1845 Scala often introduced incompatibilities in old code. Also the Java |
1799 language is lately developing at lightening speed (in comparison to the past) |
1846 language is lately developing at lightening speed (in comparison to the past) |
1800 taking on many |
1847 taking on many |
1801 features of Scala and other languages, and it seems it even introduces |
1848 features of Scala and other languages, and it seems it even introduces |
1802 new features on its own. |
1849 new features on its own. So there is seemingly even more incentive to |
|
1850 stick with the old stuff you know. |
1803 |
1851 |
1804 |
1852 |
1805 Scala is deep: After many years, I still continue to learn new technique |
1853 Scala is deep: After many years, I still continue to learn new technique |
1806 for writing more elegant code. Unfortunately, I have not yet managed to |
1854 for writing more elegant code. |
1807 switch over my code to Scala 3.0 due to time constraints. Scala 3 seems |
1855 %Unfortunately, I have not yet managed to |
|
1856 %switch over my code to Scala 3.0 due to time constraints. |
|
1857 Scala 3 seems |
1808 to iron out a number of snags from Scala 2, but why on earth are they |
1858 to iron out a number of snags from Scala 2, but why on earth are they |
1809 introducing Python-esque indentation and why on earth are they |
1859 introducing Python-esque indentation and why on earth are they |
1810 re-introducing the \texttt{then}-keyword in Scala 3, when I just about got |
1860 re-introducing the \texttt{then}-keyword in Scala 3, when I just about got |
1811 comfortable without it? |
1861 comfortable without it? |
1812 |
1862 |