# HG changeset patch # User Christian Urban # Date 1541725723 0 # Node ID 01ee4b576eb2c2f5d43d77d9560dabcc2bf1d1be # Parent 54befaf236485b029dce7afa0dee3d927f119d09 updated diff -r 54befaf23648 -r 01ee4b576eb2 progs/lecture1.scala --- a/progs/lecture1.scala Thu Nov 08 23:42:03 2018 +0000 +++ b/progs/lecture1.scala Fri Nov 09 01:08:43 2018 +0000 @@ -63,7 +63,7 @@ List(1,2,3) == List(3,1,2) -// this applies for "concrete" values; +// this applies to "concrete" values; // you cannot compare functions @@ -86,6 +86,7 @@ println(lst.mkString("[", ",", "]")) + // Conversion methods //==================== @@ -109,8 +110,11 @@ "1,2,3,4,5".split(",").mkString("\n") "1,2,3,4,5".split(",3,").mkString("\n") +"abcdefg".startsWith("abc") + + // Types (slide) -//======= +//=============== /* Scala is a strongly typed language @@ -126,6 +130,7 @@ Set[Double] Pairs: (Int, String) List[(BigInt, String)] + Option[Int] */ @@ -141,6 +146,8 @@ t._4 +List(("one", 1), ("two", 2), ("three", 3)) + // Function Definitions //====================== @@ -159,12 +166,22 @@ // } +// +// BTW: no returns!! +// "last" line (expression) in a function determines the result +// + +def silly(n: Int) : Int = { + n * n + n + n +} + // If-Conditionals //================= -// Scala does not have a then-keyword -// both if-else branches need to be present +// - Scala does not have a then-keyword +// - both if-else branches need to be present def fact(n: Int) : Int = if (n == 0) 1 else n * fact(n - 1) @@ -211,7 +228,7 @@ //in Java if something unusually happens, you return null // -//in Scala you use Option +//in Scala you use Options instead // - if the value is present, you use Some(value) // - if no value is present, you use None @@ -240,6 +257,26 @@ // the same for files Source.fromFile("test.txt").mkString +// function reading something from files... + +def get_contents(name: String) : List[String] = + Source.fromFile(name).getLines.toList + +get_contents("test.txt") + +// slightly better - return Nil +def get_contents(name: String) : List[String] = + Try(Source.fromFile(name).getLines.toList).getOrElse(Nil) + +get_contents("text.txt") + +// much better - you record in the type that things can go wrong +def get_contents(name: String) : Option[List[String]] = + Try(Some(Source.fromFile(name).getLines.toList)).getOrElse(None) + +get_contents("text.txt") + + // String Interpolations //======================= @@ -250,6 +287,12 @@ println(s"The square of ${n} is ${square(n)}.") +// helpful for debugging purposes +// +// "The most effective debugging tool is still careful thought, +// coupled with judiciously placed print statements." +// — Brian W. Kernighan, in Unix for Beginners (1979) + def gcd_db(a: Int, b: Int) : Int = { println(s"Function called with ${a} and ${b}.") @@ -260,7 +303,7 @@ // Asserts/Testing -//================ +//================= assert(gcd(48, 18) == 6) @@ -282,11 +325,12 @@ mult_table.sliding(10,10).mkString("\n") -// the list can also be constructed in any other way +// the list/set/... can also be constructed in any +// other way for (n <- List(10,12,4,5,7,8,10)) yield n * n -// with if-predicates +// with if-predicates / filters for (n <- (1 to 3).toList; m <- (1 to 3).toList; @@ -305,14 +349,36 @@ for (p <- lst) yield p._1 + p._2 -// general pattern +// general pattern of for-yield -for (x <- ...) yield { +for (p <- ...) yield { // potentially complicated // calculation of a result } +// Functions producing multiple outputs +//====================================== +def get_ascii(c: Char) : (Char, Int) = (c, c.toInt) + +get_ascii('a') + + +// .maxBy, sortBy with pairs +def get_length(s: String) : (String, Int) = (s, s.length) + +val lst = List("zero", "one", "two", "three", "four", "ten") +val strs = for (s <- lst) yield get_length(s) + +strs.sortBy(_._2) +strs.sortBy(_._1) + +strs.maxBy(_._2) +strs.maxBy(_._1) + + +// For without yield +//=================== // with only a side-effect (no list is produced), // has no "yield" @@ -325,7 +391,7 @@ for (i <- (0 until lst.length)) println(lst(i)) -// why not? +// Why not just? Why making your life so complicated? for (c <- lst) println(c) // Aside: concurrency @@ -350,87 +416,75 @@ time_needed(10, for (n <- list.par) yield n + 42) -// Function producing multiple outputs -//===================================== -def get_ascii(c: Char) : (Char, Int) = (c, c.toInt) - -get_ascii('a') - +// Just for "Fun": Mutable vs Immutable +//======================================= +// +// - no vars, no ++i, no += +// - no mutable data-structures (no Arrays, no ListBuffers) -// .maxBy, sortBy with pairs -def get_length(s: String) : (String, Int) = (s, s.length) +// Q: Count how many elements are in the intersections of two sets? + +def count_intersection(A: Set[Int], B: Set[Int]) : Int = { + var count = 0 + for (x <- A; if (B contains x)) count += 1 + count +} -val lst = List("zero", "one", "two", "three", "four", "ten") -val strs = for (s <- lst) yield get_length(s) +val A = (1 to 1000).toSet +val B = (1 to 1000 by 4).toSet + +count_intersection(A, B) + +// but do not try to add .par to the for-loop above + -strs.sortBy(_._2) -strs.sortBy(_._1) +//propper parallel version +def count_intersection2(A: Set[Int], B: Set[Int]) : Int = + A.par.count(x => B contains x) + +count_intersection2(A, B) + -strs.maxBy(_._2) -strs.maxBy(_._1) +//for measuring time +def time_needed[T](n: Int, code: => T) = { + val start = System.nanoTime() + for (i <- (0 to n)) code + val end = System.nanoTime() + (end - start) / 1.0e9 +} + +val A = (1 to 1000000).toSet +val B = (1 to 1000000 by 4).toSet + +time_needed(10, count_intersection(A, B)) +time_needed(10, count_intersection2(A, B)) + // Further Information //===================== -// The Scala home page and general information is at +// The Scala homepage and general information is at // // http://www.scala-lang.org // http://docs.scala-lang.org // // // It should be fairly easy to install the Scala binary and -// run Scala on the commandline. There are also at least -// four IDEs you can use with Scala: -// -// (0) Some general information about setting up IDEs -// with Scala support can be found at -// -// http://docs.scala-lang.org/getting-started.html -// -// -// (1) Eclipse for Scala (one big bundle) +// run Scala on the commandline. People also use Scala with +// Vim and Jedit. I currently settled on VS Code // -// http://scala-ide.org/download/sdk.html -// -// (2) IntelliJ (needs additional Plugins) -// -// https://www.jetbrains.com/idea/ -// http://docs.scala-lang.org/getting-started-intellij-track/getting-started-with-scala-in-intellij.html -// -// (3) Sublime (not free, but unlimited trial period; -// needs Scala and SublimeREPL plugin) -// -// https://www.sublimetext.com -// -// (4) Emacs (old-fashioned, but reliable) +// https://code.visualstudio.com // -// https://www.gnu.org/software/emacs/ -// -// I use the old scala-tool support for Emacs distributed at -// -// https://github.com/scala/scala-tool-support/tree/master/tool-support/emacs -// -// but there is also support for the newer Ensime Scala Mode +// There are also plugins for Eclipse and IntelliJ - YMMV. +// Finally there are online editors specifically designed for +// running Scala applications (but do not blame me if you lose +// all what you typed in): // -// http://ensime.org/editors/emacs/scala-mode/ -// -// There is also Scala support in the Atom editor, but my -// experience is mixed. People also use Scala with Vim and Jedit. -// Finally there is an online editor specifically designed for -// running Scala applications (but do not blame mne if you lose all -// what you typed in): +// https://scalafiddle.io +// https://scastie.scala-lang.org // -// https://scalafiddle.io -// -// -// -// All of the IDEs above support a REPL for Scala. Some of them have -// the very nifty feature of a Scala Worksheet -- you just save your -// file and it will be automatically evaluated and the result pasted -// into your file. However, this way of writing Scala code never worked -// for me. I just use the REPL. // // // Scala Library Docs @@ -443,8 +497,8 @@ // http://docs.scala-lang.org/tutorials/ // // There are also a massive number of Scala tutorials on youtube -// and there are tons of books and free material. -// +// and there are tons of books and free material. Google is your +// friend. diff -r 54befaf23648 -r 01ee4b576eb2 slides/slides01.pdf Binary file slides/slides01.pdf has changed diff -r 54befaf23648 -r 01ee4b576eb2 slides/slides01.tex --- a/slides/slides01.tex Thu Nov 08 23:42:03 2018 +0000 +++ b/slides/slides01.tex Fri Nov 09 01:08:43 2018 +0000 @@ -84,7 +84,8 @@ \begin{bubble}[9cm] \small developed since 2004 by Martin Odersky\\ - (he was behind Generic Scala which was included in Java 5) + (he was behind Generic Java which was included in Java 5 + \ldots I am using it maybe since 2008?) \end{bubble} \end{textblock} @@ -143,7 +144,7 @@ \textbf{\large Java} \end{textblock} -\begin{textblock}{6}(13,13.4) +\begin{textblock}{6}(13,13.6) \textbf{\large Scala} \end{textblock} @@ -167,7 +168,7 @@ \frametitle{First Steps: Scala Tools} \begin{itemize} -\item I use VS Code and a Scala extension +\item I use VS Code and a Scala extension (M'place) \begin{center} \includegraphics[scale=0.10]{../pics/vscode.png}\\[-10mm]\mbox{} \end{center}\bigskip @@ -183,10 +184,9 @@ \begin{frame}[c] \frametitle{\bf \only<1>{\begin{tabular}{l}\\[2mm]Why Scala?\\ \mbox{}\end{tabular}} - \only<2->{\begin{tabular}{l}\\[2mm]Why Functional\\ Programming?\end{tabular}} + \only<2->{\begin{tabular}{c}\\[2mm]Why Functional\\[-2mm] Programming?\end{tabular}} } - % \mbox{}\\[3.5cm] \small @@ -203,9 +203,37 @@ \end{bubble} \end{textblock}} +\only<4>{ +\begin{textblock}{6}(5,5.8) +\hspace{2mm}\includegraphics[scale=0.06]{../pics/assign.jpg}\\[-1mm] +\Large\alert{\textbf{Immutability}} +\end{textblock}} + + \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{frame}[c, fragile] + +{\Large Why bother? or\smallskip\\\hfill What is wrong with this?}\bigskip\bigskip + + +\begin{lstlisting}[language=C,numbers=none] +for (int i = 10; i < 20; i++) { + + //...Do something interesting + // with i... + +} +\end{lstlisting} + + +\end{frame} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{frame}[c] \mbox{}\\[-21mm]\mbox{} @@ -296,7 +324,7 @@ \begin{bubble}[9cm] \begin{tabular}{@{\hspace{8mm}}llll@{\hspace{8mm}}} \\ - \multicolumn{4}{c}{\bf Speedup by Moore's Law}\medskip\\ + \multicolumn{4}{c}{\alert{\bf Speedup by Moore's Law}}\medskip\\ \textbf{1986:} & 3 days & \textbf{1996:} & 135 mins\\ \textbf{1988:} & 1.5 days & \textbf{1998:} & 67 mins\\ \textbf{1990:} & 18 hs & \textbf{2000:} & 33 mins\\ @@ -313,12 +341,14 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \begin{frame}[c] -\frametitle{Seq vs Par} +\frametitle{Seq \;vs\; Par} \begin{center} \begin{tabular}[t]{@{}l@{}l@{}} - \includegraphics[scale=0.14]{../pics/mand4.png} & - \raisebox{1.2mm}{\includegraphics[scale=0.14]{../pics/mand3.png}} + \includegraphics[scale=0.14]{../pics/mand4.png} & \hspace{4mm} + \raisebox{0mm}{\includegraphics[scale=0.14]{../pics/mand3.png}}\\ + \hspace{6mm}\includegraphics[scale=0.5]{../pics/cpu2.png} & + \hspace{11mm}\includegraphics[scale=0.5]{../pics/cpu1.png} \end{tabular} \end{center} @@ -331,10 +361,10 @@ \end{textblock}} \only<3>{ - \begin{textblock}{14.2}(1,12.3) + \begin{textblock}{14.2}(1,13.5) In FP: Once a variable is created, it is assigned a value and then never changed again $\Rightarrow$ no synchronisation\smallskip\\ - \small\textcolor{gray}{(Andrew's second favourite feature of C++)} + %%\small\textcolor{gray}{(Andrew's second favourite feature of C++)} \end{textblock}} \end{frame} @@ -370,7 +400,7 @@ \textcolor{codegreen}{\texttt{List[(BigInt, String)]}} & lists of BigInt-String\\ & pairs\\ - \textcolor{codegreen}{\texttt{List[List[Int]]}} & list of lists of Int's\\ + \textcolor{codegreen}{\texttt{List[List[Int]]}} & list of lists of Int's\\ \textcolor{codegreen}{\texttt{Option[Int]}} & options of Int's \\ \end{tabular} \end{itemize} @@ -379,50 +409,50 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\begin{frame}[c] -\frametitle{An Http Request} +%\begin{frame}[c] +%\frametitle{An Http Request} -\begin{textblock}{1}(2,5) -\begin{tabular}{c} -\includegraphics[scale=0.15]{../pics/servers.png}\\[-2mm] -\small Server -\end{tabular} -\end{textblock} +%\begin{textblock}{1}(2,5) +%\begin{tabular}{c} +%\includegraphics[scale=0.15]{../pics/servers.png}\\[-2mm] +%\small Server +%\end{tabular} +%\end{textblock} -\begin{textblock}{1}(5.6,4) - \begin{tikzpicture}[scale=1.1] - \draw[white] (0,1) node (X) {}; - \draw[white] (2,1) node (Y) {}; - \draw[white] (0,0) node (X1) {}; - \draw[white] (2,0) node (Y1) {}; - \draw[white] (0,-1) node (X2) {}; - \draw[white] (2,-1) node (Y2) {}; - \draw[red, <-, line width = 2mm] (X) -- (Y); - \node [inner sep=5pt,label=above:\textcolor{black}{GET request}] at ($ (X)!.5!(Y) $) {}; - \draw[red, ->, line width = 2mm] (X1) -- (Y1); - \node [inner sep=5pt,label=above:\textcolor{black}{webpage}] at ($ (X1)!.5!(Y1) $) {}; - \draw[red, <-, line width = 2mm] (X2) -- (Y2); - \node [inner sep=7pt,label=above:\textcolor{black}{POST data}] at ($ (X2)!.5!(Y2) $) {}; - \end{tikzpicture} -\end{textblock} +%\begin{textblock}{1}(5.6,4) +% \begin{tikzpicture}[scale=1.1] +% \draw[white] (0,1) node (X) {}; +% \draw[white] (2,1) node (Y) {}; +% \draw[white] (0,0) node (X1) {}; +% \draw[white] (2,0) node (Y1) {}; +% \draw[white] (0,-1) node (X2) {}; +% \draw[white] (2,-1) node (Y2) {}; +% \draw[red, <-, line width = 2mm] (X) -- (Y); +% \node [inner sep=5pt,label=above:\textcolor{black}{GET request}] at ($ (X)!.5!(Y) $) {}; +% \draw[red, ->, line width = 2mm] (X1) -- (Y1); +% \node [inner sep=5pt,label=above:\textcolor{black}{webpage}] at ($ (X1)!.5!(Y1) $) {}; +% \draw[red, <-, line width = 2mm] (X2) -- (Y2); +% \node [inner sep=7pt,label=above:\textcolor{black}{POST data}] at ($ (X2)!.5!(Y2) $) {}; +% \end{tikzpicture} +%\end{textblock} -\begin{textblock}{1}(9,5.5) -\begin{tabular}{c} -\includegraphics[scale=0.15]{../pics/laptop.png}\\[-2mm] -\small Browser -\end{tabular} -\end{textblock} -\end{frame} +%\begin{textblock}{1}(9,5.5) +%\begin{tabular}{c} +%\includegraphics[scale=0.15]{../pics/laptop.png}\\[-2mm] +%\small Browser +%\end{tabular} +%\end{textblock} +%\end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\begin{frame}[c] - -{\lstset{language=Java}\fontsize{7}{8}\selectfont -\texttt{\lstinputlisting{URLReader.java}}} - -\end{frame} +%\begin{frame}[c] +% +%{\lstset{language=Java}\fontsize{7}{8}\selectfont +%\texttt{\lstinputlisting{URLReader.java}}} +% +%\end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -430,14 +460,16 @@ \frametitle{Coursework} \begin{itemize} -\item sorry, I might have been a bit wordy:\\ +\item Sorry, I might have been a bit wordy:\\ CW description is 7 pages, but - I only needed \mbox{< 150} loc for all the CW\bigskip + I only needed \mbox{< 100} loc for \emph{all} the CW6.\bigskip -\item there is email feedback when pushing code to github\bigskip +\item there is email feedback when pushing code to github\medskip -\item we want you to learn FP: \alert{no vars}, no mutable - datastructures, e.g.~\texttt{ListBuffer} +\item there are \texttt{jar}-files you can use to test my implementation\bigskip + +\item we want you to learn FP: \alert{\bf no vars}, no mutable + data-structures, e.g.~no \texttt{Arrays}, no \texttt{ListBuffer} \end{itemize} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -458,8 +490,9 @@ val new_list = 0 :: old_list \end{lstlisting}} -\item You do not have to be defensive about who can access the data - (concurrency, lazyness). +\item You do not have to be defensive about who can access the data. + +\item You can look at your code in isolation. \end{itemize} \end{frame} @@ -632,10 +665,10 @@ you a lot of rope to shoot yourself\bigskip \item learning functional programming is not easy\ldots{}when you have - spent all of your career thinking in a procedural way it is hard to + spent all of your career thinking in an imperative way, it is hard to change\bigskip\medskip -\item hope you have fun with the coursework +\item hope you have fun with Scala and the assignments \end{itemize} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -646,13 +679,14 @@ \begin{center} \begin{tabular}[t]{@{}l@{}l@{}} - \includegraphics[scale=0.1]{../pics/mand4.png} & - \raisebox{1.2mm}{\includegraphics[scale=0.1]{../pics/mand3.png}} + \includegraphics[scale=0.1]{../pics/mand4.png} & \hspace{4mm} + \raisebox{0mm}{\includegraphics[scale=0.1]{../pics/mand3.png}} \end{tabular} \end{center} \begin{center} -My Scala Office Hours: Thursdays 11 -- 13 + My Office Hours: Mondays 12 -- 14\\ + except next week: Tuesday 12 -- 14 \end{center} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%