70 % new_prices.push(prices[i] * 1.06); |
70 % new_prices.push(prices[i] * 1.06); |
71 % } |
71 % } |
72 % |
72 % |
73 % We can achieve the same results using .map(): |
73 % We can achieve the same results using .map(): |
74 % |
74 % |
75 % const prices = [19.99, 4.95, 25, 3.50]; |
75 % const prices = [19.99, 4.95, 25, 3.50]; |
76 % let new_prices = prices.map(price => price * 1.06); |
76 % let new_prices = prices.map(price => price * 1.06); |
77 % |
77 % |
78 % The syntax above is condensed so let’s walk through it a bit. The |
78 % The syntax above is condensed so let’s walk through it a bit. The |
79 % .map() method takes a callback, which can be thought of as a function. |
79 % .map() method takes a callback, which can be thought of as a function. |
80 % That’s what is between the parentheses. The variable price is the name |
80 % That’s what is between the parentheses. The variable price is the name |
81 % that will be used to identify each value. Since there’s only one |
81 % that will be used to identify each value. Since there’s only one |
82 % input, we can omit the usual parentheses around the parameters. |
82 % input, we can omit the usual parentheses around the parameters. |
83 |
83 |
84 % potentially a worked example? Tetris in scala.js |
84 % potentially a worked example? Tetris in scala.js |
85 % |
85 % |
86 % https://medium.com/@michael.karen/learning-modern-javascript-with-tetris-92d532bcd057 |
86 % https://medium.com/@michael.karen/learning-modern-javascript-with-tetris-92d532bcd057 |
87 % |
87 % |
88 % Scala videos |
88 % Scala videos |
89 % https://www.youtube.com/user/DrMarkCLewis |
89 % https://www.youtube.com/user/DrMarkCLewis |
90 |
90 |
91 |
91 |
92 %% https://alvinalexander.com/downloads/HelloScala-FreePreview.pdf |
92 %% https://alvinalexander.com/downloads/HelloScala-FreePreview.pdf |
93 %% |
93 %% |
94 %% Section 10 about strings; interpolations and multiline strings |
94 %% Section 10 about strings; interpolations and multiline strings |
95 |
95 |
96 % Easy installation |
96 % Easy installation |
97 %https://alexarchambault.github.io/posts/2020-09-21-cs-setup.html |
97 %https://alexarchambault.github.io/posts/2020-09-21-cs-setup.html |
98 |
98 |
120 \definecolor{outcolor}{HTML}{D84315} |
120 \definecolor{outcolor}{HTML}{D84315} |
121 \definecolor{cellborder}{HTML}{CFCFCF} |
121 \definecolor{cellborder}{HTML}{CFCFCF} |
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, 2023, 2024} |
127 \fnote{\copyright{} Christian Urban, King's College London, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024} |
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 |
138 |
139 \mbox{}\hfill\textit{``Life is too short for \texttt{malloc}.''}\smallskip\\ |
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\\ |
140 \mbox{}\hfill\textit{ --- said Neal Ford at Oscon'13}\;\hr{https://www.youtube.com/watch?v=7aYS9PcAITQ}\bigskip\\ |
141 |
141 |
142 % In 1982, James or Jim Morris wrote: |
142 % In 1982, James or Jim Morris wrote: |
143 % |
143 % |
144 % Functional languages are unnatural to use; but so are knives and |
144 % Functional languages are unnatural to use; but so are knives and |
145 % forks, diplomatic protocols, double-entry bookkeeping, and a host of |
145 % forks, diplomatic protocols, double-entry bookkeeping, and a host of |
162 Linux and Windows. Because of this it has also access to |
162 Linux and Windows. Because of this it has also access to |
163 the myriads of Java libraries. Unlike Java, however, Scala often allows |
163 the myriads of Java libraries. Unlike Java, however, Scala often allows |
164 programmers to write very concise and elegant code. Some therefore say |
164 programmers to write very concise and elegant code. Some therefore say |
165 ``Scala is the better Java''.\footnote{from |
165 ``Scala is the better Java''.\footnote{from |
166 \url{https://www.slideshare.net/maximnovak/joy-of-scala}, though this might |
166 \url{https://www.slideshare.net/maximnovak/joy-of-scala}, though this might |
167 be outdated as latest versions of Java are catching up somewhat} |
167 be outdated as latest versions of Java are catching up somewhat} |
168 |
168 |
169 A number of companies---the Guardian, Duolingo, Coursera, FourSquare, |
169 A number of companies---the Guardian, Duolingo, Coursera, FourSquare, |
170 Netflix, LinkedIn, ITV to name a few---either use Scala exclusively in |
170 Netflix, LinkedIn, ITV, Disney to name a few---either use Scala exclusively in |
171 production code, or at least to some substantial degree. Scala seems |
171 production code, or at least to some substantial degree. Scala seems |
172 also useful in job-interviews (especially in data science) according to |
172 also useful in job-interviews (especially in data science) according to |
173 this anecdotal report |
173 this anecdotal report |
174 |
174 |
175 \begin{quote} |
175 \begin{quote} |
192 in advance!\bigskip |
192 in advance!\bigskip |
193 |
193 |
194 \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black] |
194 \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black] |
195 I will be using the \textbf{\texttt{scala-cli}} REPL for Scala 3, rather |
195 I will be using the \textbf{\texttt{scala-cli}} REPL for Scala 3, rather |
196 than the ``plain'' Scala REPL. This is a batteries included version of |
196 than the ``plain'' Scala REPL. This is a batteries included version of |
197 Scala 3 and is easier to use and install. In fact |
197 Scala 3 and is easier to use and to install. In fact |
198 \texttt{scala-cli} is designated to replace |
198 \texttt{scala-cli} is designated to replace |
199 the ``plain'' Scala REPL in future versions of Scala. |
199 the ``plain'' Scala REPL in future versions of Scala. |
200 So why not using it now? |
200 So why not using it now? |
201 It can be downloaded from: |
201 It can be downloaded from: |
202 |
202 |
203 \begin{center} |
203 \begin{center} |
204 \url{https://scala-cli.virtuslab.org} |
204 \url{https://scala-cli.virtuslab.org} |
205 \end{center} |
205 \end{center} |
206 \end{tcolorbox}\medskip |
206 \end{tcolorbox}\medskip |
207 |
207 |
208 |
208 |
209 \noindent |
209 \noindent |
210 If you are interested, there are also experimental backends for Scala |
210 If you are interested, there are also experimental backends for Scala |
211 for generating JavaScript code (\url{https://www.scala-js.org}), and |
211 for generating JavaScript code (\url{https://www.scala-js.org}), and |
240 \textit{Marketplace} from which a multitude of extensions can be |
240 \textit{Marketplace} from which a multitude of extensions can be |
241 downloaded that make editing and running Scala code a little easier (see |
241 downloaded that make editing and running Scala code a little easier (see |
242 Figure~\ref{vscode} for my setup). |
242 Figure~\ref{vscode} for my setup). |
243 |
243 |
244 \begin{figure}[t] |
244 \begin{figure}[t] |
245 \begin{boxedminipage}{\textwidth} |
245 \begin{boxedminipage}{\textwidth} |
246 \begin{center} |
246 \begin{center} |
247 \includegraphics[scale=0.15]{../pics/vscode.png}\\[-10mm]\mbox{} |
247 \includegraphics[scale=0.15]{../pics/vscode.png}\\[-10mm]\mbox{} |
248 \end{center} |
248 \end{center} |
249 \caption{My installation of VS Code / Codium includes the |
249 \caption{My installation of VS Code / Codium includes the |
250 package \textbf{Scala Syntax (official)} 0.5.7 from Marketplace. |
250 package \textbf{Scala Syntax (official)} 0.5.7 from Marketplace. |
251 I have also bound the keys \keys{Ctrl} \keys{Ret} to the |
251 I have also bound the keys \keys{Ctrl} \keys{Ret} to the |
252 action ``Run-Selected-Text-In-Active-Terminal'' in order to quickly |
252 action ``Run-Selected-Text-In-Active-Terminal'' in order to quickly |
253 evaluate small code snippets in the Scala REPL. I use Codium's internal |
253 evaluate small code snippets in the Scala REPL. I use Codium's internal |
254 terminal to run \texttt{scala-cli} version 1.0.5 which |
254 terminal to run \texttt{scala-cli} version 1.0.5 which |
255 uses Scala 3.3.1.\label{vscode}} |
255 uses Scala 3.3.1.\label{vscode}} |
256 \end{boxedminipage} |
256 \end{boxedminipage} |
257 \end{figure} |
257 \end{figure} |
258 |
258 |
259 Actually \alert last year I switched to VS Codium as IDE for writing Scala programs. VS Codium is VS Code |
259 Actually \alert last year I switched to VS Codium as IDE for writing Scala programs. VS Codium is VS Code |
260 minus all the telemetry that is normally sent to Microsoft. Apart from |
260 minus all the telemetry data that is normally sent to Microsoft. Apart from |
261 the telemetry (and Copilot, which you are not supposed to use anyway), |
261 the telemetry (and Copilot, which you are not supposed to use anyway), |
262 it works pretty much the same way as the original but is driven by a |
262 it works pretty much the same way as the original but is driven by a |
263 dedicated community, rather than a big company. You can download VS |
263 dedicated community, rather than a big company. You can download VS |
264 Codium from |
264 Codium from |
265 |
265 |
274 you might do with \texttt{g++} in the second part of PEP). For |
274 you might do with \texttt{g++} in the second part of PEP). For |
275 the lazybones among us, there are even online editors and environments |
275 the lazybones among us, there are even online editors and environments |
276 for developing and running Scala programs: for example \textit{Scastie} |
276 for developing and running Scala programs: for example \textit{Scastie} |
277 is one of them. It requires zero setup |
277 is one of them. It requires zero setup |
278 (assuming you have a browser handy). You can access it at |
278 (assuming you have a browser handy). You can access it at |
279 |
279 |
280 \begin{quote} |
280 \begin{quote} |
281 \url{https://scastie.scala-lang.org} |
281 \url{https://scastie.scala-lang.org} |
282 \end{quote} |
282 \end{quote} |
283 |
283 |
284 \noindent |
284 \noindent |
285 But you should be careful if you use them for your coursework: they |
285 But you should be careful if you use them for your coursework: they |
286 are meant to play around, not really for serious work. Make |
286 are meant to play around, not really for serious work. Therefore make |
287 sure your \texttt{scala-cli} works on your own machine ASAP! |
287 sure \texttt{scala-cli} works on your own machine ASAP! |
288 |
288 |
289 As one might expect, Scala can be used with the heavy-duty IDEs |
289 As one might expect, Scala can be used with the heavy-duty IDEs |
290 Eclipse and IntelliJ. For example IntelliJ includes plugins for |
290 Eclipse and IntelliJ. For example IntelliJ includes plugins for |
291 Scala |
291 Scala |
292 |
292 |
374 into CPUs in order to make them more powerful and potentially make |
374 into CPUs in order to make them more powerful and potentially make |
375 software faster. The task for you as developer is to take somehow |
375 software faster. The task for you as developer is to take somehow |
376 advantage of these cores by running as much of your code as possible |
376 advantage of these cores by running as much of your code as possible |
377 in parallel on as many cores you have available (typically 4-8 or even |
377 in parallel on as many cores you have available (typically 4-8 or even |
378 more in modern laptops and sometimes much more on high-end |
378 more in modern laptops and sometimes much more on high-end |
379 machines---and we conveniently ignore how many cores are on modern |
379 machines---and we conveniently ignore here how many cores are on modern |
380 GPUs). In this situation \textit{mutable} variables like \texttt{i} in |
380 GPUs, which can be hundreds or even thousands). In this situation |
|
381 \textit{mutable} variables like \texttt{i} in |
381 the for-loop above are evil, or at least a major nuisance: Because if |
382 the for-loop above are evil, or at least a major nuisance: Because if |
382 you want to distribute some of the loop-iterations over several cores |
383 you want to distribute some of the loop-iterations over several cores |
383 that are currently idle in your system, you need to be extremely |
384 that are currently idle in your system, you need to be extremely |
384 careful about who can read and overwrite the variable |
385 careful about who can read and overwrite the variable |
385 \texttt{i}.\footnote{If you are of the mistaken belief that nothing |
386 \texttt{i}.\footnote{If you are of the mistaken belief that nothing |
386 nasty can happen to \texttt{i} inside the \texttt{for}-loop, then |
387 nasty can happen to \texttt{i} inside the \texttt{for}-loop, then |
387 you will have to be extra careful with the C++ material.} |
388 you will have to be extra careful with the C++ material.} |
388 Especially the writing operation is critical because you do not want |
389 Especially the writing operation is critical because you do not want |
389 that conflicting writes mess about with \texttt{i}. Take my word: an |
390 that conflicting writes mess about with \texttt{i}. Take my word: an |
390 untold amount of misery has arisen from this problem. The catch is |
391 untold amount of misery has arisen from this problem. The catch is |
391 that if you try to solve this problem in C/C++ or Java, and be as |
392 that if you try to solve this problem in languages like C/C++ or Java, and be as |
392 defensive as possible about reads and writes to \texttt{i}, then you |
393 defensive as possible about reads and writes to \texttt{i}, then you |
393 need to synchronise access to it. The result is that very often your |
394 need to synchronise access to it. The result is that very often your |
394 program waits more than it runs, thereby defeating the point of trying |
395 program waits more than it runs, thereby defeating the point of trying |
395 to run the program in parallel in the first place. If you are less |
396 to run the program in parallel in the first place. If you are less |
396 defensive, then usually all hell breaks loose by seemingly obtaining |
397 defensive, then usually all hell breaks loose by seemingly obtaining |
397 random results. And forget the idea of being able to debug such |
398 random results. And forget the idea of being able to debug such |
398 code. If you want to watch a 5-minute video of horror stories, feel |
399 code. If you want to watch a 5-minute video of horror stories, feel |
399 free to follow \ldots{} |
400 free to follow \ldots{} |
400 \hr{https://www.youtube.com/watch?v=LdLUgCJkiHY} (I love the fact, he |
401 \hr{https://www.youtube.com/watch?v=LdLUgCJkiHY} \raisebox{-0.7mm}{\emoji{rofl}} (I love the fact, he |
401 says at 4:02 that he does not understand how the JVM really |
402 says at 4:02 mins that he does not understand how the JVM really |
402 works\ldots{} I always assumed I am the only idiot who does not |
403 works\ldots{} I always assumed I am the only idiot who does not |
403 understand how threads work on the JVM. Apparently not. \raisebox{-0.7mm}{\emoji{rofl}})\bigskip |
404 understand how threads work on the JVM. Apparently not. |
|
405 But the point is that I am a functional programmer: I do not care -- I do not have to |
|
406 understand them.)\bigskip |
404 |
407 |
405 \noindent |
408 \noindent |
406 The central idea of functional programming is to eliminate any state |
409 The central idea of functional programming is to eliminate any state |
407 and mutable variables from programs---or at least from the ``interesting bits'' of the |
410 and all mutable variables from programs---or at least from the ``interesting bits'' of the |
408 programs. Because then it is easy to parallelise the resulting |
411 programs. Because then it is easy to parallelise the resulting |
409 programs: if you do not have any state, then once created, all memory |
412 programs: if you do not have any state, then once created, all memory |
410 content stays unchanged and reads to such memory are absolutely safe |
413 content stays unchanged and reads to such memory are absolutely safe |
411 without the need of any synchronisation. An example is given in |
414 without the need of any synchronisation. An example is given in |
412 Figure~\ref{mand} where in the absence of the annoying state, Scala |
415 Figure~\ref{mand} where in the absence of the annoying state, Scala |
439 {\hfill\includegraphics[scale=0.11]{../pics/mand3.png}\hfill} \\ |
442 {\hfill\includegraphics[scale=0.11]{../pics/mand3.png}\hfill} \\ |
440 |
443 |
441 {\footnotesize\begin{lstlisting}[xleftmargin=-1mm] |
444 {\footnotesize\begin{lstlisting}[xleftmargin=-1mm] |
442 for (y <- (0 until H)) { |
445 for (y <- (0 until H)) { |
443 for (x <- (0 until W)) { |
446 for (x <- (0 until W)) { |
444 |
447 |
445 val c = start + |
448 val c = start + |
446 (x * d_x + y * d_y * i) |
449 (x * d_x + y * d_y * i) |
447 val iters = iterations(c, max) |
450 val iters = iterations(c, max) |
448 val colour = |
451 val colour = |
449 if (iters == max) black |
452 if (iters == max) black |
450 else colours(iters % 16) |
453 else colours(iters % 16) |
451 |
454 |
452 pixel(x, y, colour) |
455 pixel(x, y, colour) |
453 } |
456 } |
454 viewer.updateUI() |
457 viewer.updateUI() |
455 } |
458 } |
456 \end{lstlisting}} |
459 \end{lstlisting}} |
457 & |
460 & |
458 {\footnotesize\begin{lstlisting}[xleftmargin=0mm] |
461 {\footnotesize\begin{lstlisting}[xleftmargin=0mm] |
459 for (y <- (0 until H).par) { |
462 for (y <- (0 until H).par) { |
460 for (x <- (0 until W).par) { |
463 for (x <- (0 until W).par) { |
461 |
464 |
462 val c = start + |
465 val c = start + |
463 (x * d_x + y * d_y * i) |
466 (x * d_x + y * d_y * i) |
464 val iters = iterations(c, max) |
467 val iters = iterations(c, max) |
465 val colour = |
468 val colour = |
466 if (iters == max) black |
469 if (iters == max) black |
467 else colours(iters % 16) |
470 else colours(iters % 16) |
468 |
471 |
469 pixel(x, y, colour) |
472 pixel(x, y, colour) |
470 } |
473 } |
471 viewer.updateUI() |
474 viewer.updateUI() |
472 } |
475 } |
473 \end{lstlisting}}\\[-2mm] |
476 \end{lstlisting}}\\[-2mm] |
474 |
477 |
475 \centering\includegraphics[scale=0.5]{../pics/cpu2.png} & |
478 \centering\includegraphics[scale=0.5]{../pics/cpu2.png} & |
476 \centering\includegraphics[scale=0.5]{../pics/cpu1.png} |
479 \centering\includegraphics[scale=0.5]{../pics/cpu1.png} |
477 \end{tabular} |
480 \end{tabular} |
479 \caption{The code of the two ``main'' loops in my version of the mandelbrot program. |
482 \caption{The code of the two ``main'' loops in my version of the mandelbrot program. |
480 The parallel version differs only in \texttt{.par} being added to the |
483 The parallel version differs only in \texttt{.par} being added to the |
481 ``ranges'' of the x and y coordinates. As can be seen from the CPU loads, in |
484 ``ranges'' of the x and y coordinates. As can be seen from the CPU loads, in |
482 the sequential version there is a lower peak for an extended period, |
485 the sequential version there is a lower peak for an extended period, |
483 while in the parallel version there is a short sharp burst for |
486 while in the parallel version there is a short sharp burst for |
484 essentially the same workload\ldots{}meaning you get more work done |
487 essentially the same workload\ldots{}meaning you get more work done |
485 in a shorter amount of time. This easy \emph{parallelisation} |
488 in a shorter amount of time. This easy \emph{parallelisation} |
486 only works reliably with immutable programs. |
489 only works reliably with immutable programs. |
487 \label{mand}} |
490 \label{mand}} |
488 \end{boxedminipage} |
491 \end{boxedminipage} |
489 \end{figure} |
492 \end{figure} |
490 |
493 |
491 But remember this easy parallelisation of code requires that we have no |
494 But remember this easy parallelisation of code requires that we have no |
492 state in our programs\ldots{}that is no counters like \texttt{i} in |
495 state in our programs\ldots{}that is \emph{no} counters like \texttt{i} in |
493 \texttt{for}-loops. You might then ask, how do I write loops without |
496 \texttt{for}-loops. You might then ask, how do I write loops without |
494 such counters? Well, teaching you that this is possible is one of the |
497 such counters? Well, teaching you that this is possible is one of the |
495 main points of the Scala-part in PEP. I can assure you it is possible, |
498 main points of the Scala-part in PEP. I can assure you it \emph{is} possible, |
496 but you have to get your head around it. Once you have mastered this, it |
499 but you have to get your head around it. Once you have mastered this, it |
497 will be fun to have no state in your programs (a side product is that it |
500 will be fun to have no state in your programs (a side product is that it |
498 much easier to debug state-less code and also more often than not easier |
501 much easier to debug state-less code and it is also more often than not easier |
499 to understand). So have fun with Scala!\footnote{If you are still not |
502 to understand). So have fun with Scala!\footnote{If you are still not |
500 convinced about the function programming ``thing'', there are a few more |
503 convinced about the function programming ``thing'', there are a few more |
501 arguments: a lot of research in programming languages happens to take |
504 arguments: a lot of research in programming languages happens to take |
502 place in functional programming languages. This has resulted in |
505 place in functional programming languages. This has resulted in |
503 ultra-useful features such as pattern-matching, strong type-systems, |
506 ultra-useful features such as pattern-matching, strong type-systems, |
575 \begin{lstlisting}[numbers=none,language={}] |
581 \begin{lstlisting}[numbers=none,language={}] |
576 scala> println("hello world") |
582 scala> println("hello world") |
577 hello world |
583 hello world |
578 \end{lstlisting} |
584 \end{lstlisting} |
579 |
585 |
580 \noindent Note that in this case there is no result. The |
586 \noindent Note that in this case there is no result! The |
581 reason is that \code{println} does not actually produce a result |
587 reason is that \code{println} does not actually produce a result |
582 (there is no \code{resX} and no type), rather it is a |
588 (there is no \code{resX} and no type), rather it is a |
583 function that causes the \emph{side-effect} of printing out a |
589 function that causes the \emph{side-effect} of printing out a |
584 string. Once you are more familiar with the functional |
590 string. Once you are more familiar with the functional |
585 programming-style, you will know what the difference is |
591 programming-style, you will know what the difference is |
586 between a function that returns a result, like addition, and a |
592 between a function that returns a result, like addition, and a |
587 function that causes a side-effect, like \code{println}. We |
593 function that causes a side-effect, like \code{println}. We |
588 shall come back to this point later, but if you are curious |
594 shall come back to this point later, but if you are curious |
589 now, the latter kind of functions always has \code{Unit} as |
595 now, the latter kind of functions always has \code{Unit} as |
590 return type. It is just not printed by Scala. |
596 return type. It is just not printed by Scala. |
591 |
597 |
592 You can try more examples with the \texttt{scala-cli} REPL, but feel free to |
598 You can try more examples with the \texttt{scala-cli} REPL, but feel free to |
593 first guess what the result is (not all answers by Scala are obvious): |
599 first guess what the result is (not all answers by Scala are obvious): |
594 |
600 |
595 \begin{lstlisting}[numbers=none,language={}] |
601 \begin{lstlisting}[numbers=none,language={}] |
606 scala> List(1,2,1).size |
612 scala> List(1,2,1).size |
607 scala> Set(1,2,1).size |
613 scala> Set(1,2,1).size |
608 scala> List(1) == List(1) |
614 scala> List(1) == List(1) |
609 scala> Array(1) == Array(1) |
615 scala> Array(1) == Array(1) |
610 scala> Array(1).sameElements(Array(1)) |
616 scala> Array(1).sameElements(Array(1)) |
611 \end{lstlisting} |
617 scala> 0.1 + 0.2 == 0.3 |
612 |
618 \end{lstlisting} |
613 \noindent |
619 |
614 Also observe carefully what Scala responds in the following |
620 \noindent |
615 three instances involving the constant \lstinline!1!---can |
621 If you think Scala's answer in the last line is braindamaged, try the |
|
622 same in your own favourite language. |
|
623 Also observe carefully what Scala responds in the following |
|
624 three instances involving the constant \lstinline!1!---can |
616 you explain the differences? |
625 you explain the differences? |
617 |
626 |
618 |
627 |
619 \begin{lstlisting}[numbers=none] |
628 \begin{lstlisting}[numbers=none] |
620 scala> 1 |
629 scala> 1 |
634 If you want to write a standalone app in Scala, you can |
643 If you want to write a standalone app in Scala, you can |
635 implement a function \texttt{hello} and annotate the tag |
644 implement a function \texttt{hello} and annotate the tag |
636 \texttt{@main}. For example write |
645 \texttt{@main}. For example write |
637 |
646 |
638 \begin{lstlisting}[numbers=none] |
647 \begin{lstlisting}[numbers=none] |
639 @main |
648 @main |
640 def Hello() = println("hello world") |
649 def Hello() = println("hello world") |
641 \end{lstlisting} |
650 \end{lstlisting} |
642 |
651 |
643 %object Hello extends App { |
652 %object Hello extends App { |
644 % println("hello world") |
653 % println("hello world") |
645 %} |
654 %} |
646 |
655 |
647 \noindent save it in a file, say {\tt hello-world.scala}, and |
656 \noindent save it in a file, say {\tt hello-world.scala}, and |
648 then use \texttt{scala-cli run} (which internally compiles the |
657 then use \texttt{scala-cli} (which compiles the |
649 scala file and runs it): |
658 scala file and runs it): |
650 |
659 |
651 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
660 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small] |
652 $ scala-cli run hello-world.scala |
661 $ scala-cli hello-world.scala |
653 hello world |
662 hello world |
654 \end{lstlisting} |
663 \end{lstlisting} |
655 |
664 |
656 \noindent |
665 \noindent |
657 Like Java, Scala targets the JVM and consequently |
666 Like Java, Scala targets the JVM and consequently |
713 |
722 |
714 \begin{lstlisting}[numbers=none] |
723 \begin{lstlisting}[numbers=none] |
715 scala> val x = 42 |
724 scala> val x = 42 |
716 scala> val z = x / 7 |
725 scala> val z = x / 7 |
717 scala> val x = 70 |
726 scala> val x = 70 |
718 scala> println(z) |
727 scala> println(z) |
719 \end{lstlisting} |
728 \end{lstlisting} |
720 |
729 |
721 \noindent but try to guess what Scala will print out |
730 \noindent but try to guess what Scala will print out |
722 for \code{z}? Will it be \code{6} or \code{10}? A final word about |
731 for \code{z}? Will it be \code{6} or \code{10}? A final word about |
723 values: Try to stick to the convention that names of values should be |
732 values: Try to stick to the convention that names of values should be |
724 lower case, like \code{x}, \code{y}, \code{foo41} and so on. Upper-case |
733 lower case, like \code{x}, \code{y}, \code{foo41} and so on. Upper-case |
725 names you should reserve for what is called \emph{constructors}. And |
734 names you should reserve for what is called \emph{constructors}. And |
726 forgive me when I call values as variables\ldots{}it is just something that |
735 forgive me when I call values as variables\ldots{}it is just something that |
727 has been in imprinted into my developer-DNA during my early days and |
736 has been in imprinted into my developer-DNA during my early years and |
728 is difficult to get rid of.~\texttt{;o)} |
737 is difficult to get rid of.~\texttt{;o)} |
729 |
738 |
730 |
739 |
731 \subsection*{Function Definitions} |
740 \subsection*{Function Definitions} |
732 |
741 |
733 We do functional programming! So defining functions will be our main occupation. |
742 We do functional programming! So defining functions will be our main occupation. |
734 As an example, a function named \code{f} taking a single argument of type |
743 As an example, a function named \code{f} taking a single argument of type |
735 \code{Int} can be defined in Scala as follows: |
744 \code{Int} can be defined in Scala as follows: |
736 |
745 |
737 \begin{lstlisting}[numbers=none] |
746 \begin{lstlisting}[numbers=none] |
738 def f(x: Int) : String = ...EXPR... |
747 def f(x: Int) : String = ...YOUR CODE... |
739 \end{lstlisting} |
748 \end{lstlisting} |
740 |
749 |
741 \noindent |
750 \noindent |
742 This function returns the value resulting from evaluating the expression |
751 This function returns the value resulting from evaluating the expression |
743 \code{EXPR} (whatever is substituted for this). Since we declared |
752 what your code is. Since we declared |
744 \code{String}, the result of this function will be of type |
753 \code{String} after the colon, the result of this function will be of type |
745 \code{String}. It is a good habit to always include this information |
754 \code{String}. It is a good habit to always include this information |
746 about the return type, while it is only strictly necessary to give this |
755 about the return type, while it is only strictly necessary to give this |
747 type in recursive functions (later more on that). Simple examples of Scala functions are: |
756 type in recursive functions (later more on that). Simple examples of Scala functions are: |
748 |
757 |
749 \begin{lstlisting}[numbers=none] |
758 \begin{lstlisting}[numbers=none] |
755 \noindent |
764 \noindent |
756 The general scheme for functions is |
765 The general scheme for functions is |
757 |
766 |
758 \begin{lstlisting}[numbers=none] |
767 \begin{lstlisting}[numbers=none] |
759 def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = { |
768 def fname(arg1: ty1, arg2: ty2,..., argn: tyn): rty = { |
760 ...BODY... |
769 ...BODY_OF_FUNCTION... |
761 } |
770 } |
762 \end{lstlisting} |
771 \end{lstlisting} |
763 |
772 |
764 \noindent |
773 \noindent |
765 where each argument, \texttt{arg1}, \texttt{arg2} and so on, requires |
774 where each argument, \texttt{arg1}, \texttt{arg2} and so on, requires |
766 its type and the result type of the |
775 its type and the result type of the |
767 function, \code{rty}, should also be given. If the body of the function is |
776 function, \code{rty}, should also be given. If the body of the function is |
768 more complex, then it can be enclosed in braces, like above. If it |
777 more complex, then it can be enclosed in braces, like above. If it |
769 is just a simple expression, like \code{x + 1}, you can omit the |
778 is just a simple expression, like \code{x + 1}, you can omit the |
770 braces. Very often functions are recursive (that is call themselves), |
779 braces. Very often functions are recursive (that is call themselves), |
771 like the venerable factorial function: |
780 like the venerable factorial function: |
772 |
781 |
773 \begin{lstlisting}[numbers=none] |
782 \begin{lstlisting}[numbers=none] |
774 def fact(n: Int) : Int = |
783 def fact(n: Int) : Int = |
775 if (n == 0) 1 else n * fact(n - 1) |
784 if (n == 0) 1 else n * fact(n - 1) |
776 \end{lstlisting} |
785 \end{lstlisting} |
777 |
786 |
778 \noindent |
787 \noindent |
779 where we have to give the return type \code{Int}. Note we could also |
788 In this case we have to give the return type \code{Int}. But as said, it is a good |
|
789 habit to give the return type for all functions. Note we could also |
780 have written this with braces as |
790 have written this with braces as |
781 |
791 |
782 \begin{lstlisting}[numbers=none] |
792 \begin{lstlisting}[numbers=none] |
783 def fact(n: Int) : Int = { |
793 def fact(n: Int) : Int = { |
784 if (n == 0) 1 |
794 if (n == 0) 1 |
785 else n * fact(n - 1) |
795 else n * fact(n - 1) |
786 } |
796 } |
787 \end{lstlisting} |
797 \end{lstlisting} |
788 |
798 |
789 \noindent |
799 \noindent |
790 but this seems a bit overkill for a small function like \code{fact}. |
800 but this seems a bit overkill for a small function like \code{fact}. |
791 Notice that I did not use a \code{then}-keyword in the |
801 Notice that I did not use a \code{then}-keyword in the |
794 \code{then} with an \code{if}, but this has been long established |
804 \code{then} with an \code{if}, but this has been long established |
795 syntax for \code{if}-statements. Scala, to my knowledge, was pretty |
805 syntax for \code{if}-statements. Scala, to my knowledge, was pretty |
796 unique in that for nearly 20 years of its existence\ldots{}until Scala |
806 unique in that for nearly 20 years of its existence\ldots{}until Scala |
797 3 came along. While people like me have perfectly adapted to the sight |
807 3 came along. While people like me have perfectly adapted to the sight |
798 of \code{if}s without \code{then}s, it seems the developers of Scala |
808 of \code{if}s without \code{then}s, it seems the developers of Scala |
799 caved in to the special eyesight of Gen-Python people and now allow to |
809 caved in to the special eyesight of Gen-Python people (I am sure that is not you) and now allow to |
800 write the same function also as |
810 write the same function also as |
801 |
811 |
802 \begin{lstlisting}[numbers=none] |
812 \begin{lstlisting}[numbers=none] |
803 def fact(n: Int) : Int = { |
813 def fact(n: Int) : Int = { |
804 if n == 0 |
814 if n == 0 then 1 |
805 then 1 |
|
806 else n * fact(n - 1) |
815 else n * fact(n - 1) |
807 } |
816 } |
808 \end{lstlisting} |
817 \end{lstlisting} |
809 |
818 |
810 \noindent |
819 \noindent |
811 I accept this might look a bit more familiar to beginners of Scala, if |
820 The main difference between both versions is that if you want to drop the \code{then}, then you need to |
812 they come from other languages, like Java or C++. But that we also had |
821 enclose the boolean expression within parentheses. |
|
822 I accept the second version might look a bit more familiar to beginners of Scala, if |
|
823 they come from other languages, like Python, Java or C++. But that we also had |
813 to get rid in Scala 3 of the familiar \texttt{\{\}}-parentheses is |
824 to get rid in Scala 3 of the familiar \texttt{\{\}}-parentheses is |
814 completely beyond me. So in Scala 3 the braces are optional and the |
825 completely beyond me. So in Scala 3 the braces are optional and the |
815 \texttt{fact}-function can even be written as |
826 \texttt{fact}-function can even be written as |
816 |
827 |
817 \begin{lstlisting}[numbers=none] |
828 \begin{lstlisting}[numbers=none] |
818 def fact(n: Int) : Int = |
829 def fact(n: Int) : Int = |
819 if n == 0 |
830 if n == 0 |
820 then 1 |
831 then 1 |
821 else n * fact(n - 1) |
832 else n * fact(n - 1) |
822 \end{lstlisting} |
833 \end{lstlisting} |
823 |
834 |
824 \noindent on the condition that indents now become \emph{meaningful} |
835 \noindent on the condition that indents now become \emph{meaningful} |
825 (as in Python).\raisebox{-0.7mm}{\emoji{face-vomiting}} All versions are now permitted in Scala 3. While you |
836 (as in Python).\raisebox{-0.7mm}{\emoji{face-vomiting}} All versions are now permitted in Scala 3. While you |
826 are free to use any syntax version you want in PEP, or even mix them, |
837 are free to use any syntax version you want in PEP, or even mix them, |
827 I will \textbf{not} show you any of my code in the newfangled |
838 I will \textbf{not} show you any of my code in the newfangled |
828 Pythonesque meaningful-indent-syntax. When necessary, I will always |
839 Pythonesque meaningful-indent-syntax. When necessary, I will always |
829 use braces to indicate the beginning and end of a code block, and I |
840 use braces to indicate the beginning and end of a code block, and I |
830 have not yet get completely get used to the \code{if}s with |
841 have not yet completely got used to the \code{if}s with |
831 \code{then}s. Please forgive me for being still inconsistent with this\footnote{Scala adopted some very fine features of Python, for example string interpolations, but that we had to completely cave in to |
842 \code{then}s. Please forgive me for being still inconsistent with this\footnote{Scala adopted some very fine features of Python, for example string interpolations, but that we had to completely cave in to |
832 the demands of Gen-Python is a bridge too far for my completely |
843 the demands of Gen-Python is a bridge too far for my completely |
833 insignificant opinion. |
844 insignificant opinion. |
834 I always assumed escaping Python's dependency hell |
845 I always assumed escaping Python's dependency hell |
835 is every software developers life goal---apparently not. \emoji{exploding-head}} |
846 is every software developers life goal---apparently not. \emoji{exploding-head}} |
857 \begin{lstlisting}[numbers=none] |
868 \begin{lstlisting}[numbers=none] |
858 def average(xs: List[Int]) : Int = { |
869 def average(xs: List[Int]) : Int = { |
859 val s = xs.sum |
870 val s = xs.sum |
860 val n = xs.length |
871 val n = xs.length |
861 s / n |
872 s / n |
862 } |
873 } |
863 \end{lstlisting} |
874 \end{lstlisting} |
864 |
875 |
865 \noindent In this example the expression \code{s / n} is in the last |
876 \noindent In this example the expression \code{s / n} is in the last |
866 line of the function---so this will be the result the function |
877 line of the function---so this will be the result the function |
867 calculates. The two lines before just calculate intermediate values. |
878 calculates. The two lines before just calculate intermediate values. |
868 This principle of the ``last-line'' comes in handy when you need to |
879 This principle of the ``last-line'' comes in handy when you need to |
869 print out values, for example, for debugging purposes. Suppose you want |
880 print out values, for example, for debugging purposes. Suppose you want |
870 rewrite the function as |
881 rewrite the average function as |
871 |
882 |
872 \begin{lstlisting}[numbers=none] |
883 \begin{lstlisting}[numbers=none] |
873 def average(xs: List[Int]) : Int = { |
884 def average(xs: List[Int]) : Int = { |
874 val s = xs.sum |
885 val s = xs.sum |
875 val n = xs.length |
886 val n = xs.length |
876 val h = xs.head |
887 val h = xs.head |
877 println(s"Input $xs with first element $h") |
888 println(s"Input $xs with first element $h") |
878 s / n |
889 s / n |
879 } |
890 } |
880 \end{lstlisting} |
891 \end{lstlisting} |
881 |
892 |
882 \noindent |
893 \noindent |
883 Here the function still only returns the expression \code{s / n} in |
894 Here the function still only returns the expression \code{s / n} in |
884 the last line. The \code{println} before just prints out some |
895 the last line. The \code{println} before just prints out some |
917 |
928 |
918 \begin{lstlisting}[numbers=none] |
929 \begin{lstlisting}[numbers=none] |
919 def avr_minmax(xs: List[Int]) : (Int, Int, Int) = { |
930 def avr_minmax(xs: List[Int]) : (Int, Int, Int) = { |
920 if (xs.length == 0) (0, 0, 0) |
931 if (xs.length == 0) (0, 0, 0) |
921 else (xs.min, xs.sum / xs.length, xs.max) |
932 else (xs.min, xs.sum / xs.length, xs.max) |
922 } |
933 } |
923 \end{lstlisting} |
934 \end{lstlisting} |
924 |
935 |
925 \noindent |
936 \noindent |
926 which still satisfies the rule-of-thumb. |
937 which still satisfies the rule-of-thumb: The result of the function is the |
|
938 last expression that is run inside the function. |
927 |
939 |
928 \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black] |
940 \begin{tcolorbox}[colback=red!5!white,colframe=red!75!black] |
929 Do not use \code{return} in your code to indicate what a function |
941 Do not use \code{return} in your code to indicate what a function |
930 produces as a result! It has a different meaning in Scala than in |
942 produces as a result! It has a different meaning in Scala than in |
931 Java. It can change the meaning of your program, and you should |
943 Java. It can change the meaning of your program, and you should |
937 |
949 |
938 Coming from Java or C/C++, you might be surprised that Scala does |
950 Coming from Java or C/C++, you might be surprised that Scala does |
939 not really have loops. It has instead, what is in functional |
951 not really have loops. It has instead, what is in functional |
940 programming called, \emph{maps}. To illustrate how they work, |
952 programming called, \emph{maps}. To illustrate how they work, |
941 let us assume you have a list of numbers from 1 to 8 and want to |
953 let us assume you have a list of numbers from 1 to 8 and want to |
942 build the list of squares. The list of numbers from 1 to 8 |
954 build the list of corresponding squares. The list of numbers from 1 to 8 |
943 can be constructed in Scala as follows: |
955 can be constructed in Scala as follows: |
944 |
956 |
945 \begin{lstlisting}[numbers=none,language={}] |
957 \begin{lstlisting}[numbers=none,language={}] |
946 scala> (1 to 8).toList |
958 scala> (1 to 8).toList |
947 val res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8) |
959 val res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8) |
948 \end{lstlisting} |
960 \end{lstlisting} |
949 |
961 |
950 \noindent Generating from this list the list of corresponding |
962 \noindent Like in modern versions of Java, the \code{1 to 8} generates a \code{Range}, which is then |
951 squares in a programming language such as Java, you would assume |
963 transformed into a list by the \code{.toList}. |
|
964 Generating from this list the list of |
|
965 squares in an imperative programming language such as C++, you would assume |
952 the list is given as a kind of array. You would then iterate, or loop, |
966 the list is given as a kind of array. You would then iterate, or loop, |
953 an index over this array and replace each entry in the array |
967 an index over this array and replace each entry in the array |
954 by the square. Right? In Scala, and in other functional |
968 by its square. Right? In Scala, and in other functional |
955 programming languages, you use maps to achieve the same. |
969 programming languages, you use maps to achieve the same. |
956 |
970 |
957 A map essentially takes a function that describes how each element is |
971 A map essentially takes a function that describes how each element is |
958 transformed (in this example the function is $n \rightarrow n * n$) and |
972 transformed (in this example the function is $n \rightarrow n * n$) and |
959 a list over which this function should work. Pictorially you can think |
973 a list over which this function should work. Pictorially you can think |
960 of the idea behind maps as follows: |
974 of the idea behind maps as follows: |
961 |
975 |
962 \begin{center} |
976 \begin{center} |
963 \begin{tikzpicture} |
977 \begin{tikzpicture} |
964 |
978 |
965 \node (A0) at (1.2,0) {\texttt{List(}}; |
979 \node (A0) at (1.2,0) {\texttt{List(}}; |
966 \node (A1) at (2.0,0) {\texttt{1\makebox[0mm]{ ,}}}; |
980 \node (A1) at (2.0,0) {\texttt{1\makebox[0mm]{ ,}}}; |
967 \node (A2) at (2.9,0) {\texttt{2\makebox[0mm]{ ,}}}; |
981 \node (A2) at (2.9,0) {\texttt{2\makebox[0mm]{ ,}}}; |
968 \node (A3) at (3.8,0) {\texttt{3\makebox[0mm]{ ,}}}; |
982 \node (A3) at (3.8,0) {\texttt{3\makebox[0mm]{ ,}}}; |
969 \node (A4) at (4.7,0) {\texttt{4\makebox[0mm]{ ,}}}; |
983 \node (A4) at (4.7,0) {\texttt{4\makebox[0mm]{ ,}}}; |
989 \draw [->,line width=1mm] (A5.south) -- (B5.north); |
1003 \draw [->,line width=1mm] (A5.south) -- (B5.north); |
990 \draw [->,line width=1mm] (A6.south) -- (B6.north); |
1004 \draw [->,line width=1mm] (A6.south) -- (B6.north); |
991 \draw [->,line width=1mm] (A7.south) -- (B7.north); |
1005 \draw [->,line width=1mm] (A7.south) -- (B7.north); |
992 \draw [->,line width=1mm] (A8.south) -- (B8.north); |
1006 \draw [->,line width=1mm] (A8.south) -- (B8.north); |
993 |
1007 |
994 \node [red] (Q0) at (-0.3,-0.3) {\large\texttt{n}}; |
1008 \node [red] (Q0) at (-0.3,-0.3) {\large\texttt{n}}; |
995 \node (Q1) at (-0.3,-0.4) {}; |
1009 \node (Q1) at (-0.3,-0.4) {}; |
996 \node (Q2) at (-0.3,-2.5) {}; |
1010 \node (Q2) at (-0.3,-2.5) {}; |
997 \node [red] (Q3) at (-0.3,-2.65) {\large\texttt{n\,*\,n}}; |
1011 \node [red] (Q3) at (-0.3,-2.65) {\large\texttt{n\,*\,n}}; |
998 \draw [->,red,line width=1mm] (Q1.south) -- (Q2.north); |
1012 \draw [->,red,line width=1mm] (Q1.south) -- (Q2.north); |
999 |
1013 |
1037 i * j + 1 |
1051 i * j + 1 |
1038 } |
1052 } |
1039 val res3: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) |
1053 val res3: List[Int] = List(1, 4, 9, 16, 25, 36, 49, 64) |
1040 \end{lstlisting} |
1054 \end{lstlisting} |
1041 |
1055 |
1042 Let us come back to the simple example of squaring a list of numbers. |
1056 Let us come back to the simple example of squaring a list of numbers from above. |
1043 As you can see in the for-comprehensions above, we specified the list |
1057 As you can see in the for-comprehensions, we specified the list |
1044 where each \code{n} comes from, namely \code{(1 to 8).toList}, and how |
1058 where each \code{n} comes from, namely \code{(1 to 8).toList}, and how |
1045 each element needs to be transformed, the expression after the |
1059 each element needs to be transformed, the expression after the |
1046 \code{yield}. This can also be expressed in a second way in Scala by |
1060 \code{yield}. This can also be expressed in a second way in Scala by |
1047 using directly the function \code{map} as follows: |
1061 using directly the function \code{map} as follows: |
1048 |
1062 |
1082 Scala.} is the correct result for sets, as there are only three |
1096 Scala.} is the correct result for sets, as there are only three |
1083 equivalence classes of integers modulo 3. Since maps and |
1097 equivalence classes of integers modulo 3. Since maps and |
1084 for-comprehensions are just syntactic variants of each other, the latter |
1098 for-comprehensions are just syntactic variants of each other, the latter |
1085 can also be written as |
1099 can also be written as |
1086 |
1100 |
1087 \begin{lstlisting}[numbers=none] |
1101 \begin{lstlisting}[numbers=none,language={}] |
1088 scala> for (n <- (1 to 8).toSet) yield n % 3 |
1102 scala> for (n <- (1 to 8).toSet) yield n % 3 |
1089 val res5 = Set(2, 1, 0) |
1103 val res5 = Set(2, 1, 0) |
1090 \end{lstlisting} |
1104 \end{lstlisting} |
1091 |
1105 |
1092 For-comprehensions can also be nested and the selection of |
1106 For-comprehensions can also be nested and the selection of |
1093 elements can be guarded (or filtered). For example if we want to pair up |
1107 elements can be guarded (or filtered). For example if we want to pair up |
1094 the numbers 1 to 4 with the letters a to c, we can write |
1108 the numbers 1 to 4 with the letters a to c, we can write |
1095 |
1109 |
1096 \begin{lstlisting}[numbers=none] |
1110 \begin{lstlisting}[numbers=none] |
1097 scala> for (n <- (1 to 4).toList; |
1111 scala> for (n <- (1 to 4).toList; |
1098 m <- ('a' to 'c').toList) yield (n, m) |
1112 m <- ('a' to 'c').toList) yield (n, m) |
1099 val res6 = List((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), |
1113 val res6 = List((1,a), (1,b), (1,c), (2,a), (2,b), (2,c), |
1100 (3,a), (3,b), (3,c), (4,a), (4,b), (4,c)) |
1114 (3,a), (3,b), (3,c), (4,a), (4,b), (4,c)) |
1101 \end{lstlisting} |
1115 \end{lstlisting} |
1102 |
1116 |
1103 \noindent |
1117 \noindent |
1104 In this example the for-comprehension ranges over two lists, and |
1118 In this example the for-comprehension ranges over two lists, and |
1105 produces a list of pairs as output. Or, if we want to find all pairs of |
1119 produces a list of pairs as output. Or, if we want to find all pairs of |
1106 numbers between 1 and 3 where the sum is an even number, we can write |
1120 numbers between 1 and 3 where the sum is an even number, we can write |
1107 |
1121 |
1108 \begin{lstlisting}[numbers=none] |
1122 \begin{lstlisting}[numbers=none] |
1109 scala> for (n <- (1 to 3).toList; |
1123 scala> for (n <- (1 to 3).toList; |
1110 m <- (1 to 3).toList; |
1124 m <- (1 to 3).toList; |
1111 if (n + m) % 2 == 0) yield (n, m) |
1125 if (n + m) % 2 == 0) yield (n, m) |
1112 val res7 = List((1,1), (1,3), (2,2), (3,1), (3,3)) |
1126 val res7 = List((1,1), (1,3), (2,2), (3,1), (3,3)) |
1113 \end{lstlisting} |
1127 \end{lstlisting} |
1114 |
1128 |
1115 \noindent The \code{if}-condition in this for-comprehension filters out |
1129 \noindent The \code{if}-condition in this for-comprehension filters out |
1116 all pairs where the sum is not even (therefore \code{(1, 2)}, \code{(2, |
1130 all pairs where the sum is not even (therefore \code{(1, 2)}, \code{(2, |
1117 1)} and \code{(3, 2)} are not in the result because their sum is odd). |
1131 1)} and \code{(3, 2)} are not in the result because their sum is odd). |
1118 |
1132 |
1119 To summarise, maps (or for-comprehensions) transform one collection into |
1133 To summarise, maps (or for-comprehensions) transform one collection into |
1120 another. For example a list of \code{Int}s into a list of squares, and |
1134 another. For example a list of \code{Int}s into a list of squares, and |
1121 so on. There is no need for for-loops in Scala. But please do not be |
1135 so on. There is no need for for-loops in Scala. But please do not be |
1122 tempted to write anything like |
1136 tempted to write anything like |
1123 |
1137 |
1124 \begin{lstlisting}[numbers=none] |
1138 \begin{lstlisting}[numbers=none] |
1125 scala> val cs = ('a' to 'h').toList |
1139 scala> val cs = ('a' to 'h').toList |
1126 scala> for (n <- (0 until cs.length).toList) |
1140 scala> for (n <- (0 until cs.length).toList) |
1127 yield cs(n).capitalize |
1141 yield cs(n).capitalize |
1128 val res8: List[Char] = List(A, B, C, D, E, F, G, H) |
1142 val res8: List[Char] = List(A, B, C, D, E, F, G, H) |
1129 \end{lstlisting} |
1143 \end{lstlisting} |
1130 |
1144 |
1131 \noindent |
1145 \noindent |
1195 \begin{lstlisting}[numbers=none] |
1209 \begin{lstlisting}[numbers=none] |
1196 scala> (1 to 5).toList.foreach(print) |
1210 scala> (1 to 5).toList.foreach(print) |
1197 12345 |
1211 12345 |
1198 \end{lstlisting} |
1212 \end{lstlisting} |
1199 |
1213 |
1200 \noindent |
1214 \noindent |
1201 If you want to find out more about maps and functions with |
1215 If you want to find out more about maps and functions with |
1202 side-effects, you can ponder about the response Scala gives if |
1216 side-effects, you can ponder about the response Scala gives if |
1203 you replace \code{foreach} by \code{map} in the expression |
1217 you replace \code{foreach} by \code{map} in the expression |
1204 above. Scala will still allow \code{map} with side-effect |
1218 above. Scala will still allow \code{map} with side-effect |
1205 functions, but then reacts with a slightly interesting result. |
1219 functions, but then reacts with a slightly interesting result. |
|
1220 If you understand the difference, you are pretty much on the |
|
1221 road of becoming a master-functional programmer. |
1206 |
1222 |
1207 \subsection*{Aggregates} |
1223 \subsection*{Aggregates} |
1208 |
1224 |
1209 There is one more usage of for-loops in Java, C/C++ and the like: |
1225 There is one more usage of for-loops in Java, C/C++ and the like: |
1210 sometimes you want to \emph{aggregate} something about a list, for |
1226 sometimes you want to \emph{aggregate} something about a list, for |
1264 examples are |
1280 examples are |
1265 |
1281 |
1266 \begin{lstlisting}[numbers=none] |
1282 \begin{lstlisting}[numbers=none] |
1267 def even(x: Int) : Boolean = x % 2 == 0 |
1283 def even(x: Int) : Boolean = x % 2 == 0 |
1268 def odd(x: Int) : Boolean = x % 2 == 1 |
1284 def odd(x: Int) : Boolean = x % 2 == 1 |
1269 \end{lstlisting} |
1285 \end{lstlisting} |
1270 |
1286 |
1271 \noindent |
1287 \noindent |
1272 More interestingly, the concept of functions is really pushed to the |
1288 More interestingly, the concept of functions is really pushed to the |
1273 limit in functional programming. Functions can take other functions as |
1289 limit in functional programming. Functions can take other functions as |
1274 arguments and can return a function as a result. This is actually |
1290 arguments and can return a function as a result. This is actually |
1275 quite important for making code generic. Assume a list of 10 elements: |
1291 quite important for making code generic. Assume a list of 10 elements: |
1276 |
1292 |
1277 \begin{lstlisting}[numbers=none] |
1293 \begin{lstlisting}[numbers=none] |
1278 val lst = (1 to 10).toList |
1294 val lst = (1 to 10).toList |
1279 \end{lstlisting} |
1295 \end{lstlisting} |
1280 |
1296 |
1281 \noindent |
1297 \noindent |
1282 Say, we want to filter out all even numbers. For this we can use |
1298 Say, we want to filter out all even numbers. For this we can use |
1283 |
1299 |
1284 \begin{lstlisting}[numbers=none] |
1300 \begin{lstlisting}[numbers=none] |
1285 scala> lst.filter(even) |
1301 scala> lst.filter(even) |
1286 List(2, 4, 6, 8, 10) |
1302 List(2, 4, 6, 8, 10) |
1287 \end{lstlisting} |
1303 \end{lstlisting} |
1288 |
1304 |
1289 \noindent |
1305 \noindent |
1290 where \code{filter} expects a function as argument specifying which |
1306 where \code{filter} expects a function as argument specifying which |
1291 elements of the list should be kept and which should be left out. By |
1307 elements of the list should be kept and which should be left out. By |
1292 allowing \code{filter} to take a function as argument, we can also |
1308 allowing \code{filter} to take a function as argument, we can also |
1293 easily filter out odd numbers as well. |
1309 easily filter out odd numbers as well. |
1294 |
1310 |
1295 \begin{lstlisting}[numbers=none] |
1311 \begin{lstlisting}[numbers=none] |
1296 scala> lst.filter(odd) |
1312 scala> lst.filter(odd) |
1297 List(1, 3, 5, 7, 9) |
1313 List(1, 3, 5, 7, 9) |
1298 \end{lstlisting} |
1314 \end{lstlisting} |
1299 |
1315 |
1300 \noindent |
1316 \noindent |
1301 Such function arguments are quite frequently used for ``generic'' functions. |
1317 Such function arguments are quite frequently used for ``generic'' functions. |
1302 For example it is easy to count odd elements in a list or find the first |
1318 For example it is easy to count odd elements in a list or find the first |
1303 even number in a list: |
1319 even number in a list: |
1305 \begin{lstlisting}[numbers=none] |
1321 \begin{lstlisting}[numbers=none] |
1306 scala> lst.count(odd) |
1322 scala> lst.count(odd) |
1307 5 |
1323 5 |
1308 scala> lst.find(even) |
1324 scala> lst.find(even) |
1309 Some(2) |
1325 Some(2) |
1310 \end{lstlisting} |
1326 \end{lstlisting} |
1311 |
1327 |
1312 \noindent |
1328 \noindent |
1313 Recall that the return type of \code{even} and \code{odd} are booleans. |
1329 Recall that the return type of \code{even} and \code{odd} are booleans. |
1314 Such function are sometimes called predicates, because they determine |
1330 Such function are sometimes called predicates, because they determine |
1315 what should be true for an element and what false, and then performing |
1331 what should be true for an element and what false, and then performing |
1316 some operation according to this boolean. Such predicates are quite useful. |
1332 some operation according to this boolean. Such predicates are quite useful. |
1317 Say you want to sort the \code{lst}-list in ascending and descending order. |
1333 Say you want to sort the \code{lst}-list in ascending and descending order. |
1318 For this you can write |
1334 For this you can write |
1319 |
1335 |
1320 \begin{lstlisting}[numbers=none] |
1336 \begin{lstlisting}[numbers=none] |
1321 lst.sortWith(_ < _) |
1337 lst.sortWith(_ < _) |
1322 lst.sortWith(_ > _) |
1338 lst.sortWith(_ > _) |
1323 \end{lstlisting} |
1339 \end{lstlisting} |
1324 |
1340 |
1325 \noindent where \code{sortWith} expects a predicate as argument. The |
1341 \noindent where \code{sortWith} expects a predicate as argument. The |
1326 construction \code{_ < _} stands for a function that takes two arguments |
1342 construction \code{_ < _} stands for a function that takes two arguments |
1327 and returns true when the first one is smaller than the second. You can |
1343 and returns true when the first one is smaller than the second. You can |
1328 think of this as elegant shorthand notation for |
1344 think of this as elegant shorthand notation for |
1329 |
1345 |
1330 \begin{lstlisting}[numbers=none] |
1346 \begin{lstlisting}[numbers=none] |
1331 def smaller(x: Int, y: Int) : Boolean = x < y |
1347 def smaller(x: Int, y: Int) : Boolean = x < y |
1332 lst.sortWith(smaller) |
1348 lst.sortWith(smaller) |
1333 \end{lstlisting} |
1349 \end{lstlisting} |
1334 |
1350 |
1335 \noindent |
1351 \noindent |
1336 Say you want to find in \code{lst} the first odd number greater than 2. |
1352 Say you want to find in \code{lst} the first odd number greater than 2. |
1337 For this you need to write a function that specifies exactly this |
1353 For this you need to write a function that specifies exactly this |
1338 condition. To do this you can use a slight variant of the shorthand |
1354 condition. To do this you can use a slight variant of the shorthand |
1339 notation above |
1355 notation above |
1340 |
1356 |
1341 \begin{lstlisting}[numbers=none] |
1357 \begin{lstlisting}[numbers=none] |
1342 scala> lst.find(n => odd(n) && n > 2) |
1358 scala> lst.find(n => odd(n) && n > 2) |
1343 Some(3) |
1359 Some(3) |
1344 \end{lstlisting} |
1360 \end{lstlisting} |
1345 |
1361 |
1346 \noindent |
1362 \noindent |
1347 Here \code{n => ...} specifies a function that takes \code{n} as |
1363 Here \code{n => ...} specifies a function that takes \code{n} as |
1348 argument and uses this argument in whatever comes after the double |
1364 argument and uses this argument in whatever comes after the double |
1349 arrow. If you want to use this mechanism for looking for an element that |
1365 arrow. If you want to use this mechanism for looking for an element that |
1350 is both even and odd, then of course you out of luck. |
1366 is both even and odd, then of course you out of luck. |
1351 |
1367 |
1352 \begin{lstlisting}[numbers=none] |
1368 \begin{lstlisting}[numbers=none] |
1353 scala> lst.find(n => odd(n) && even(n)) |
1369 scala> lst.find(n => odd(n) && even(n)) |
1354 None |
1370 None |
1355 \end{lstlisting} |
1371 \end{lstlisting} |
1356 |
1372 |
1357 While functions taking functions as arguments seems a rather useful |
1373 While functions taking functions as arguments seems a rather useful |
1358 feature, the utility of returning a function might not be so clear. |
1374 feature, the utility of returning a function might not be so clear. |
1359 I admit the following example is a bit contrived, but believe me |
1375 I admit the following example is a bit contrived, but believe me |
1360 sometims functions produce other functions in a very meaningful way. |
1376 sometims functions produce other functions in a very meaningful way. |
1361 Say we want to generate functions according to strings, as in |
1377 Say we want to generate functions according to strings, as in |
1362 |
1378 |
1363 \begin{lstlisting}[numbers=none] |
1379 \begin{lstlisting}[numbers=none] |
1409 datatype and also whenever you define functions (their |
1425 datatype and also whenever you define functions (their |
1410 arguments and their results need a type). Base types are types |
1426 arguments and their results need a type). Base types are types |
1411 that do not take any (type)arguments, for example \code{Int} |
1427 that do not take any (type)arguments, for example \code{Int} |
1412 and \code{String}. Compound types take one or more arguments, |
1428 and \code{String}. Compound types take one or more arguments, |
1413 which as seen earlier need to be given in angle-brackets, for |
1429 which as seen earlier need to be given in angle-brackets, for |
1414 example \code{List[Int]} or \code{Set[List[String]]} or |
1430 example \code{List[Int]} or \code{Set[List[String]]} or |
1415 \code{Map[Int, Int]}. |
1431 \code{Map[Int, Int]}. |
1416 |
1432 |
1417 Scala provides a basic mechanism to check the type of a (closed) |
1433 Scala provides a basic mechanism to check the type of a (closed) |
1418 expression---closed means that all parts are already known to Scala. |
1434 expression---closed means that all parts are already known to Scala. |
1419 Then you can use the command \code{:type} and check in the REPL: |
1435 Then you can use the command \code{:type} and check in the REPL: |
1534 Given this rule, what kind of function has type |
1550 Given this rule, what kind of function has type |
1535 \mbox{\code{(Int => String) => Boolean}}? Well, it returns a |
1551 \mbox{\code{(Int => String) => Boolean}}? Well, it returns a |
1536 boolean. More interestingly, though, it only takes a single |
1552 boolean. More interestingly, though, it only takes a single |
1537 argument (because of the parentheses). The single argument |
1553 argument (because of the parentheses). The single argument |
1538 happens to be another function (taking an integer as input and |
1554 happens to be another function (taking an integer as input and |
1539 returning a string). Remember that \code{mk_string} is just |
1555 returning a string). Remember that \code{mk_string} is just |
1540 such a function. So how can we use it? For this define |
1556 such a function. So how can we use it? For this define |
1541 the somewhat silly function \code{apply_3}: |
1557 the somewhat silly function \code{apply_3}: |
1542 |
1558 |
1543 \begin{lstlisting}[numbers=none] |
1559 \begin{lstlisting}[numbers=none] |
1544 def apply_3(f: Int => String): Bool = f(3) == "many" |
1560 def apply_3(f: Int => String): Bool = f(3) == "many" |
1585 any kind of function (not just functions that, for example, |
1601 any kind of function (not just functions that, for example, |
1586 take as input an integer and produce a string like above). |
1602 take as input an integer and produce a string like above). |
1587 This means we cannot fix the type of the generic traversal |
1603 This means we cannot fix the type of the generic traversal |
1588 functions, but have to keep them |
1604 functions, but have to keep them |
1589 \emph{polymorphic}.\footnote{Another interesting topic about |
1605 \emph{polymorphic}.\footnote{Another interesting topic about |
1590 types, but we omit it here for the sake of brevity.} |
1606 types, but we omit it here for the sake of brevity.} |
1591 |
1607 |
1592 There is one more type constructor that is rather special. It is |
1608 There is one more type constructor that is rather special. It is |
1593 called \code{Unit}. Recall that \code{Boolean} has two values, namely |
1609 called \code{Unit}. Recall that \code{Boolean} has two values, namely |
1594 \code{true} and \code{false}. This can be used, for example, to test |
1610 \code{true} and \code{false}. This can be used, for example, to test |
1595 something and decide whether the test succeeds or not. In contrast the |
1611 something and decide whether the test succeeds or not. In contrast the |
1718 % def ~ (r: String) = SEQ(s, r) |
1734 % def ~ (r: String) = SEQ(s, r) |
1719 % def % = STAR(s) |
1735 % def % = STAR(s) |
1720 % } |
1736 % } |
1721 % \end{lstlisting} |
1737 % \end{lstlisting} |
1722 |
1738 |
1723 |
1739 |
1724 % \noindent This might seem a bit overly complicated, but its effect is |
1740 % \noindent This might seem a bit overly complicated, but its effect is |
1725 % that I can now write regular expressions such as $ab + ac$ |
1741 % that I can now write regular expressions such as $ab + ac$ |
1726 % simply as |
1742 % simply as |
1727 |
1743 |
1728 |
1744 |
1729 % \begin{lstlisting}[numbers=none] |
1745 % \begin{lstlisting}[numbers=none] |
1730 % scala> "ab" | "ac" |
1746 % scala> "ab" | "ac" |
1731 % res10 = ALT(SEQ(CHAR(a),CHAR(b)),SEQ(CHAR(a),CHAR(c))) |
1747 % res10 = ALT(SEQ(CHAR(a),CHAR(b)),SEQ(CHAR(a),CHAR(c))) |
1732 % \end{lstlisting} |
1748 % \end{lstlisting} |
1733 |
1749 |
1734 |
1750 |
1735 % \noindent I leave you to figure out what the other |
1751 % \noindent I leave you to figure out what the other |
1736 % syntactic sugar in the code above stands for. |
1752 % syntactic sugar in the code above stands for. |
1737 |
1753 |
1738 % One more useful feature of Scala is the ability to define |
1754 % One more useful feature of Scala is the ability to define |
1739 % functions with varying argument lists. This is a feature that |
1755 % functions with varying argument lists. This is a feature that |
1740 % is already present in old languages, like C, but seems to have |
1756 % is already present in old languages, like C, but seems to have |
1741 % been forgotten in the meantime---Java does not have it. In the |
1757 % been forgotten in the meantime---Java does not have it. In the |
1742 % context of regular expressions this feature comes in handy: |
1758 % context of regular expressions this feature comes in handy: |