handouts/pep-ho.tex
changeset 278 0c2481cd8b1c
parent 277 acaf2099406a
child 301 c3b33c709696
equal deleted inserted replaced
277:acaf2099406a 278:0c2481cd8b1c
   223 This kind of running code uses a single core of your CPU and goes as
   223 This kind of running code uses a single core of your CPU and goes as
   224 fast as your CPU frequency, also called clock-speed, allows. The problem
   224 fast as your CPU frequency, also called clock-speed, allows. The problem
   225 is that this clock-speed has not much increased over the past decade and
   225 is that this clock-speed has not much increased over the past decade and
   226 no dramatic increases are predicted for any time soon. So you are a bit
   226 no dramatic increases are predicted for any time soon. So you are a bit
   227 stuck. This is unlike previous generations of developers who could rely
   227 stuck. This is unlike previous generations of developers who could rely
   228 upon the fact that every 2 years or so their code would run twice as
   228 upon the fact that approximately every 2 years their code would run
   229 fast  because the clock-speed of their CPUs got twice as fast.
   229 twice as fast  because the clock-speed of their CPUs got twice as fast.
   230 Unfortunately this does not happen any more nowadays. To get you out of
   230 Unfortunately this does not happen any more nowadays. To get you out of
   231 this dreadful situation, CPU producers pile more and more cores into
   231 this dreadful situation, CPU producers pile more and more cores into
   232 CPUs in order to make them more powerful and potentially make software
   232 CPUs in order to make them more powerful and potentially make software
   233 faster. The task for you as developer is to take somehow advantage of
   233 faster. The task for you as developer is to take somehow advantage of
   234 these cores by running as much of your code as possible in parallel on
   234 these cores by running as much of your code as possible in parallel on
   235 as many cores you have available (typically 4 in modern laptops and
   235 as many cores you have available (typically 4 in modern laptops and
   236 sometimes much more on high-end machines). In this situation,
   236 sometimes much more on high-end machines). In this situation
   237 \textit{mutable} variables like \texttt{i} above are evil, or at least a
   237 \textit{mutable} variables like \texttt{i} above are evil, or at least a
   238 major nuisance: Because if you want to distribute some of the
   238 major nuisance: Because if you want to distribute some of the
   239 loop-iterations over the cores that are currently idle in your system,
   239 loop-iterations over the cores that are currently idle in your system,
   240 you need to be extremely careful about who can read and overwrite the
   240 you need to be extremely careful about who can read and overwrite the
   241 variable \texttt{i}.\footnote{If you are of the mistaken belief that
   241 variable \texttt{i}.\footnote{If you are of the mistaken belief that
   874 
   874 
   875 \noindent The \code{if}-condition in this for-comprehension filters out
   875 \noindent The \code{if}-condition in this for-comprehension filters out
   876 all pairs where the sum is not even (therefore \code{(1, 2)}, \code{(2,
   876 all pairs where the sum is not even (therefore \code{(1, 2)}, \code{(2,
   877 1)} and \code{(3, 2)} are not in the result because their sum is odd). 
   877 1)} and \code{(3, 2)} are not in the result because their sum is odd). 
   878 
   878 
   879 To sum up, maps (or for-comprehensions) transform one collection into
   879 To summarise, maps (or for-comprehensions) transform one collection into
   880 another. For example a list of \code{Int}s into a list of squares, and
   880 another. For example a list of \code{Int}s into a list of squares, and
   881 so on. There is no need for for-loops in Scala. But please do not be
   881 so on. There is no need for for-loops in Scala. But please do not be
   882 tempted to write anything like
   882 tempted to write anything like
   883 
   883 
   884 \begin{lstlisting}[numbers=none]
   884 \begin{lstlisting}[numbers=none]
   966 
   966 
   967 \subsection*{Aggregates}
   967 \subsection*{Aggregates}
   968 
   968 
   969 There is one more usage of for-loops in Java, C/C++ and the like:
   969 There is one more usage of for-loops in Java, C/C++ and the like:
   970 sometimes you want to \emph{aggregate} something about a list, for
   970 sometimes you want to \emph{aggregate} something about a list, for
   971 example summing up all its elements. In this case you cannot use map,
   971 example summing up all its elements. In this case you cannot use maps,
   972 because maps \emph{transform} one data collection into another data
   972 because maps \emph{transform} one data collection into another data
   973 collection. They cannot be used to generate a single integer
   973 collection. They cannot be used to generate a single integer
   974 representing an aggregate. So how is this done in Scala? Let us
   974 representing an aggregate. So how is this kind of aggregation done in
   975 suppose you want to sum up all elements from a list. You might
   975 Scala? Let us suppose you want to sum up all elements from a list. You
   976 be tempted to write something like
   976 might be tempted to write something like
   977 
   977 
   978 \begin{lstlisting}[numbers=none]
   978 \begin{lstlisting}[numbers=none]
   979 var cnt = 0
   979 var cnt = 0
   980 for (n <- (1 to 8).toList) {
   980 for (n <- (1 to 8).toList) {
   981   cnt += n
   981   cnt += n
   985 
   985 
   986 \noindent
   986 \noindent
   987 and indeed this is accepted Scala code and produces the expected result,
   987 and indeed this is accepted Scala code and produces the expected result,
   988 namely \code{36}, \textbf{BUT} this is imperative style and not
   988 namely \code{36}, \textbf{BUT} this is imperative style and not
   989 permitted in PEP. It uses a \code{var} and therefore violates the
   989 permitted in PEP. It uses a \code{var} and therefore violates the
   990 immutability property I ask for in your code. Sorry.
   990 immutability property I ask for in your code. Sorry!
   991 
   991 
   992 So how to do that same thing without using a \code{var}? Well there are
   992 So how to do that same thing without using a \code{var}? Well there are
   993 several ways. One way is to define the following recursive
   993 several ways. One way is to define the following recursive
   994 \code{sum}-function:
   994 \code{sum}-function:
   995 
   995 
   998   if (xs.isEmpty) 0 else xs.head + sum(xs.tail)
   998   if (xs.isEmpty) 0 else xs.head + sum(xs.tail)
   999 \end{lstlisting}  
   999 \end{lstlisting}  
  1000 
  1000 
  1001 \noindent
  1001 \noindent
  1002 You can then call \code{sum((1 to 8).toList)} and obtain the same result
  1002 You can then call \code{sum((1 to 8).toList)} and obtain the same result
  1003 without a mutable variable or for-loop. Obviously for simple things like
  1003 without a mutable variable and without a for-loop. Obviously for simple things like
  1004 sum, you could have written \code{xs.sum} in the first place. But not
  1004 sum, you could have written \code{xs.sum} in the first place. But not
  1005 all aggregate functions are pre-defined and often you have to write your
  1005 all aggregate functions are pre-defined and often you have to write your
  1006 own recursive function for this.
  1006 own recursive function for this.
  1007 
  1007 
  1008 
  1008