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 |
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 |