\documentclass{article}
\usepackage{../style}
\usepackage{../langs}
\usepackage{marvosym}
\usepackage{tcolorbox}
%% \usepackage[]{hvextern}

%cheat sheet
%http://worldline.github.io/scala-cheatsheet/

\begin{document}
\fnote{\copyright{} Christian Urban, King's College London, 2020, 2021, 2023}

\section*{Scala 3 in 6CCS3CFL}

For the coursework in this module you are free to use any programming
language you like, but I will show you all my code using Scala---I
hope you have fond memories of Scala from PEP. The only difference
with PEP is that I will the Ammonite REPL for Scala 3.

\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
If you intend to submit your code for the CW in Scala, you \underline{MUST} submit code that
is compatible with Scala 3!! This is to make it easier for me to test
your code and the changes between Scala 2 from last year PEP to Scala
3 in CFL are not that great. In fact, most changes are just some new
syntax.
\end{tcolorbox}\medskip

\noindent
If you need a reminder of the Scala handouts from PEP updated to Scala 3
have a look here
\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
  been used previously in CFL. I do not recommend to use Java or C or C++ for
  writing a compiler, but if you insist, feel free. It has been done
  before.}  
\bigskip

\noindent
The other difference between the Scala I showed you in PEP is that in CFL
I will use the Ammonite REPL (with underlying Scala Version 3):

\begin{quote}
\url{https://ammonite.io/#Ammonite-REPL}
\end{quote}

\noindent
This is a drop-in replacement for the original Scala REPL and
works very similarly, for example

\begin{lstlisting}[language={},numbers=none,basicstyle=\ttfamily\small]
$ amm
Loading...
Welcome to the Ammonite Repl 3.0.0-M2 (Scala 3.3.3 Java 21.0.4)
@ 1 + 2
res0: Int = 3
\end{lstlisting} %% $

%%\runExtCmd[redirect]{ls -la}{voss}


\noindent
Ammonite uses the same Scala compiler, just adds some useful features
on top of it. It is quite main-stream in the Scala community and it should
therefore be very easy for you to install \texttt{amm}. If you work under
a Unix-like system, a sure way to install the right version of Ammonite
is by using \texttt{curl}:

\begin{lstlisting}[numbers=none,language={},basicstyle=\ttfamily\small]
$ curl -L https://github.com/com-lihaoyi/Ammonite/releases/\
  download/3.0.0-M2/3.3-3.0.0-M2 --output amm
\end{lstlisting} %% $  

\noindent
This creates a file \code{amm} which before it can be run might
need some adjustments of the permissions. Under recent versions of
Windows also have \texttt{curl}, but need a slightly different call:

\begin{lstlisting}[numbers=none,language={},basicstyle=\ttfamily\small]
$ curl -L https://github.com/com-lihaoyi/Ammonite/releases/\
  download/3.0.0-M2/3.3-3.0.0-M2 --output amm.bat
\end{lstlisting} %% $  

\noindent
Then you need to run Ammonite with \texttt{.$\backslash$amm} and there
is no need to change any permissions under Windows.  

The big advantage of Ammonite is that it comes with some additional
libraries already built-in and also allows one to easily break up code
into smaller modules. For example reading and writing files in
Ammonite can be achieved with

\begin{lstlisting}[numbers=none,language=Scala]
scala> import os._
scala> write.over(pwd / "file.name", "foo bar")  
scala> read(pwd / "file.name")   
res1: String = "foo bar"
\end{lstlisting}

\noindent
The second line writes the string \code{"foo bar"} into the file
\code{"file.name"}, which is located in the current working
directory (\code{pwd}). For loading and accessing code from
another Scala file, you can import the code into Ammonite
as follows:

\begin{lstlisting}[numbers=none,language=Scala]
import $file.name-of-the-file
import name-of-the-file._
\end{lstlisting}  %% $

\noindent
This assumes the other Scala file is called
\texttt{name-of-the-file.sc} and requires the file to be in the same
directory where \texttt{amm} is working in. This will be very convenient 
for the compiler we implement in CFL, because it allows us to easily
break up the code into the lexer, parser and code generator.

Another handy feature of Ammonite is that you can mark functions as
\texttt{@main}. For example

\begin{lstlisting}[numbers=none,language=Scala]
@main
def foo() = ...
\end{lstlisting}

\noindent
This means you can now call that function from the command line like

\begin{lstlisting}[numbers=none,language=Scala]
$ amm file.sc foo
\end{lstlisting} %% $

\noindent
If you want to specify an argument on the commandline, say an int and
a string, then you can write

\begin{lstlisting}[numbers=none,language=Scala]
@main
def bar(i: Int, s: String) = ...
\end{lstlisting}

\noindent
and then call

\begin{lstlisting}[numbers=none,language=Scala]
$ amm file.sc 42 foobar
\end{lstlisting} %% $

\noindent
What is also good in Ammonite is that you can specify more than one
function to be ``main'' and then specify on the command line which
function you want to run as entry-point.

Another feature you might like to use is that Ammonite can ``watch'' files.
This means it can automatically re-run a file when it is saved. For this
you have to call \texttt{amm} with the option \texttt{-w}, as in

\begin{lstlisting}[numbers=none,language=Scala]
$ amm -w file.sc
\end{lstlisting} %% $

\noindent Of course this requires that you use \texttt{println} for
inspecting any data as otherwise nothing will be displayed at the
commandline.
\smallskip

\noindent
To sum up, Ammonite is a really useful addition to the Scala ecosystem.
You can find more information about how to use it in the first five chapters
of the ``Hands-on Scala'' book by Li Haoyi. These chapters are
free and can be used as a reference, see

\begin{center}
\url{https://www.handsonscala.com/part-i-introduction-to-scala.html}
\end{center}

\end{document}

%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: 
