handouts/amm-ho.tex
changeset 994 35db8ee453c0
parent 965 94f5cce73a4f
equal deleted inserted replaced
993:9a85924835c0 994:35db8ee453c0
     7 
     7 
     8 %cheat sheet
     8 %cheat sheet
     9 %http://worldline.github.io/scala-cheatsheet/
     9 %http://worldline.github.io/scala-cheatsheet/
    10 
    10 
    11 \begin{document}
    11 \begin{document}
    12 \fnote{\copyright{} Christian Urban, King's College London, 2020, 2021, 2023}
    12 \fnote{\copyright{} Christian Urban, King's College London, 2020, 2021, 2023, 2025}
    13 
    13 
    14 \section*{Scala 3 in 6CCS3CFL}
    14 \section*{Scala 3 in 6CCS3CFL}
    15 
    15 
    16 For the coursework in this module you are free to use any programming
    16 For the coursework in this module you are free to use any programming
    17 language you like, but I will show you all my code using Scala---I
    17 language you like, but I will show you all my code using Scala---I
    27 \end{tcolorbox}\medskip
    27 \end{tcolorbox}\medskip
    28 
    28 
    29 \noindent
    29 \noindent
    30 If you need a reminder of the Scala handouts from PEP updated to Scala 3
    30 If you need a reminder of the Scala handouts from PEP updated to Scala 3
    31 have a look here
    31 have a look here
    32 \hr{http://talisker.nms.kcl.ac.uk/cgi-bin/repos.cgi/pep-material/raw-file/tip/handouts/pep-ho.pdf}. But as said, you do not need to use Scala for the CWs.\footnote{Haskell, Rust, Ocaml were other languages that have
    32 \hr{https://cflmark.nms.kcl.ac.uk/hg/pep-material/raw-file/tip/handouts/pep-ho.pdf}. But as said, you do not need to use Scala for the CWs.\footnote{Haskell, Rust, Ocaml were other languages that have
    33   been used previously in CFL. I do not recommend to use Java or C or C++ for
    33   been used previously in CFL. I do not recommend to use Java or C or C++ for
    34   writing a compiler, but if you insist, feel free. It has been done
    34   writing a compiler, but if you insist, feel free. It has been done
    35   before.}  
    35   before.}  
    36 \bigskip
    36 \bigskip
    37 
    37 
    48 works very similarly, for example
    48 works very similarly, for example
    49 
    49 
    50 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
    50 \begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
    51 $ amm
    51 $ amm
    52 Loading...
    52 Loading...
    53 Welcome to the Ammonite Repl 3.0.0-M2 (Scala 3.3.3 Java 21.0.4)
    53 Welcome to the Ammonite Repl 3.0.2 (Scala 3.3.5 Java 21.0.8)
    54 @ 1 + 2
    54 @ 1 + 2
    55 res0: Int = 3
    55 res0: Int = 3
    56 \end{lstlisting} %% $
    56 \end{lstlisting} %% $
    57 
    57 
    58 %%\runExtCmd[redirect]{ls -la}{voss}
    58 %%\runExtCmd[redirect]{ls -la}{voss}
    65 a Unix-like system, a sure way to install the right version of Ammonite
    65 a Unix-like system, a sure way to install the right version of Ammonite
    66 is by using \texttt{curl}:
    66 is by using \texttt{curl}:
    67 
    67 
    68 \begin{lstlisting}[numbers=none,language={},basicstyle=\ttfamily\small]
    68 \begin{lstlisting}[numbers=none,language={},basicstyle=\ttfamily\small]
    69 $ curl -L https://github.com/com-lihaoyi/Ammonite/releases/\
    69 $ curl -L https://github.com/com-lihaoyi/Ammonite/releases/\
    70   download/3.0.0-M2/3.3-3.0.0-M2 --output amm
    70   download/3.0.2/3.5-3.0.2 --output amm
    71 \end{lstlisting} %% $  
    71 \end{lstlisting} %% $  
    72 
    72 
    73 \noindent
    73 \noindent
    74 This creates a file \code{amm} which before it can be run might
    74 This creates a file \code{amm} which before it can be run might
    75 need some adjustments of the permissions. Under recent versions of
    75 need some adjustments of the permissions. Under recent versions of
    76 Windows also have \texttt{curl}, but need a slightly different call:
    76 Windows also have \texttt{curl}, but need a slightly different call:
    77 
    77 
    78 \begin{lstlisting}[numbers=none,language={},basicstyle=\ttfamily\small]
    78 \begin{lstlisting}[numbers=none,language={},basicstyle=\ttfamily\small]
    79 $ curl -L https://github.com/com-lihaoyi/Ammonite/releases/\
    79 $ curl -L https://github.com/com-lihaoyi/Ammonite/releases/\
    80   download/3.0.0-M2/3.3-3.0.0-M2 --output amm.bat
    80    download/3.0.2/3.5-3.0.2 --output amm.bat
    81 \end{lstlisting} %% $  
    81 \end{lstlisting} %% $  
    82 
    82 
    83 \noindent
    83 \noindent
    84 Then you need to run Ammonite with \texttt{.$\backslash$amm} and there
    84 Then you need to run Ammonite with \texttt{.$\backslash$amm} and there
    85 is no need to change any permissions under Windows.  
    85 is no need to change any permissions under Windows.  
    97 \end{lstlisting}
    97 \end{lstlisting}
    98 
    98 
    99 \noindent
    99 \noindent
   100 The second line writes the string \code{"foo bar"} into the file
   100 The second line writes the string \code{"foo bar"} into the file
   101 \code{"file.name"}, which is located in the current working
   101 \code{"file.name"}, which is located in the current working
   102 directory (\code{pwd}). For loading and accessing code from
   102 directory (\code{pwd}). We want to implement a compiler---therefore 
       
   103 reading and writing files will come in handy.
       
   104 
       
   105 
       
   106 For loading and accessing code from
   103 another Scala file, you can import the code into Ammonite
   107 another Scala file, you can import the code into Ammonite
   104 as follows:
   108 as follows:
   105 
   109 
   106 \begin{lstlisting}[numbers=none,language=Scala]
   110 \begin{lstlisting}[numbers=none,language=Scala]
   107 import $file.name-of-the-file
   111 import $file.name-of-the-file
   109 \end{lstlisting}  %% $
   113 \end{lstlisting}  %% $
   110 
   114 
   111 \noindent
   115 \noindent
   112 This assumes the other Scala file is called
   116 This assumes the other Scala file is called
   113 \texttt{name-of-the-file.sc} and requires the file to be in the same
   117 \texttt{name-of-the-file.sc} and requires the file to be in the same
   114 directory where \texttt{amm} is working in. This will be very convenient 
   118 directory where \texttt{amm} is working in. Again this will be very convenient 
   115 for the compiler we implement in CFL, because it allows us to easily
   119 for our compiler we implement in CFL, because it allows us to easily
   116 break up the code into the lexer, parser and code generator.
   120 break up the code into the lexer, parser and code generator.
   117 
   121 
   118 Another handy feature of Ammonite is that you can mark functions as
   122 Another handy feature of Ammonite is that you can mark functions as
   119 \texttt{@main}. For example
   123 \texttt{@main}. For example
   120 
   124 
   159 $ amm -w file.sc
   163 $ amm -w file.sc
   160 \end{lstlisting} %% $
   164 \end{lstlisting} %% $
   161 
   165 
   162 \noindent Of course this requires that you use \texttt{println} for
   166 \noindent Of course this requires that you use \texttt{println} for
   163 inspecting any data as otherwise nothing will be displayed at the
   167 inspecting any data as otherwise nothing will be displayed at the
   164 commandline.
   168 commandline.\medskip
   165 \smallskip
       
   166 
   169 
   167 \noindent
   170 \noindent
   168 To sum up, Ammonite is a really useful addition to the Scala ecosystem.
   171 To sum up, Ammonite is a really useful addition to the Scala ecosystem.
   169 You can find more information about how to use it in the first five chapters
   172 You can find more information about how to use it in the first five chapters
   170 of the ``Hands-on Scala'' book by Li Haoyi. These chapters are
   173 of the ``Hands-on Scala'' book by Li Haoyi. These chapters are
   172 
   175 
   173 \begin{center}
   176 \begin{center}
   174 \url{https://www.handsonscala.com/part-i-introduction-to-scala.html}
   177 \url{https://www.handsonscala.com/part-i-introduction-to-scala.html}
   175 \end{center}
   178 \end{center}
   176 
   179 
       
   180 
       
   181 \subsection*{Some Updates in Scala 3 and the Videos}
       
   182 
       
   183 While Scala 2 and Scala 3 code is on the whole quite compatible, there are some
       
   184 corners where my Scala 3 code differs from the code shown in the videos. I am still
       
   185 fond of using \texttt{\{...\}} rather than Pythonesque indentation syntax. But
       
   186 I switched to the \texttt{enum}-syntax for abstract datatypes. Defining regular
       
   187 expressions in the ``old'' way can be done using abstract classes, like:
       
   188 
       
   189 \begin{lstlisting}[language=Scala,basicstyle=\ttfamily\small]
       
   190 abstract class Rexp
       
   191 case object ZERO extends Rexp
       
   192 case object ONE extends Rexp
       
   193 case class CHAR(c: Char) extends Rexp
       
   194 case class ALT(r1: Rexp, r2: Rexp) extends Rexp
       
   195 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp
       
   196 case class STAR(r: Rexp) extends Rexp
       
   197 \end{lstlisting} 
       
   198 
       
   199 \noindent
       
   200 While this code still works in Scala 3 as expected, the definition can now 
       
   201 be simplified to:
       
   202 
       
   203 \begin{lstlisting}[language=Scala,basicstyle=\ttfamily\small]
       
   204 enum Rexp {
       
   205   case ZERO                     
       
   206   case ONE                      
       
   207   case CHAR(c: Char)            
       
   208   case ALT(r1: Rexp, r2: Rexp)  
       
   209   case SEQ(r1: Rexp, r2: Rexp)  
       
   210   case STAR(r: Rexp)            
       
   211 }
       
   212 import Rexp._
       
   213 \end{lstlisting} 
       
   214 
       
   215 \noindent
       
   216 Note that the syntax with \texttt{enum} needs an import, otherwise you need
       
   217 to refer to the constructors slightly clumsily as in \texttt{Rexp.CHAR('a')} and 
       
   218 so on.
       
   219 
       
   220 Also implicits are now defined differently in Scala 3 and need to be
       
   221 split up into \texttt{given}s and extension methods. If you want to
       
   222 construct regular expressions using strings, for example \texttt{STAR("a")},
       
   223 then you need to declare a \texttt{given}-clause:
       
   224 
       
   225 \begin{lstlisting}[language=Scala,basicstyle=\ttfamily\small]
       
   226 def charlist2rexp(s : List[Char]): Rexp = s match {
       
   227   case Nil => ONE
       
   228   case c::Nil => CHAR(c)
       
   229   case c::s => SEQ(CHAR(c), charlist2rexp(s))
       
   230 }
       
   231 
       
   232 given Conversion[String, Rexp] = (s => charlist2rexp(s.toList))
       
   233 \end{lstlisting} 
       
   234 
       
   235 \noindent
       
   236 This uses the auxiliary function \texttt{charlist2rexp} which translates
       
   237 a string (list of chars) into a regular expression. The ``magic'' is then 
       
   238 installed in the \texttt{given}-clause which calls \texttt{charlist2rexp} 
       
   239 whenever a \texttt{Rexp} is expected, but a string is given.
       
   240 
       
   241 More convenient operator syntax for regular instructions needs to be
       
   242 defined in Scala 3 as \emph{extension method}. For example, the shorthand-syntax
       
   243 for alternatives, sequences and stars needs to be defined as:
       
   244 
       
   245 \begin{lstlisting}[language=Scala,basicstyle=\ttfamily\small]
       
   246 extension (r: Rexp) {
       
   247   def | (s: Rexp) = ALT(r, s)
       
   248   def ~ (s: Rexp) = SEQ(r, s)
       
   249   def % = STAR(r)
       
   250 }
       
   251 \end{lstlisting} 
       
   252 
       
   253 \noindent
       
   254 After that you can define regular expressions more conveniently
       
   255 as \pcode{"ab" | "bc"}, \pcode{"ab" ~ "bc"} or \pcode{"ab".\%}\;.\medskip
       
   256 
       
   257 \noindent
       
   258 To sum up, it should be easy for you to translate the old syntax that
       
   259 is in some places used in the videos and the newer syntax used in the
       
   260 uploaded files. There are a few additional rough edges in the code
       
   261 for parsers, but I will mention them nearer the time. 
       
   262 
   177 \end{document}
   263 \end{document}
   178 
   264 
   179 %%% Local Variables: 
   265 %%% Local Variables: 
   180 %%% mode: latex
   266 %%% mode: latex
   181 %%% TeX-master: t
   267 %%% TeX-master: t