Skip to content

Commit 2c83378

Browse files
committed
Mention records.
1 parent af8667d commit 2c83378

File tree

1 file changed

+92
-8
lines changed

1 file changed

+92
-8
lines changed

main.tex

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,9 @@ \subsection{Top-Level Definitions}
561561
presented later.
562562
563563
\begin{lstlisting}
564-
let mandelbrot_step(Zn: (f64, f64), C: (f64, f64)): (f64, f64) =
565-
let (Zn_r, Zn_i) = Zn
566-
let (C_r, C_i) = C
564+
let mandelbrot_step ((Zn_r, Zn_i): (f64, f64))
565+
((C_r, C_i): (f64, f64))
566+
: (f64, f64) =
567567
let real_part = Zn_r*Zn_r - Zn_i*Zn_i + C_r
568568
let imag_part = 2.0*Zn_r*Zn_i + C_i
569569
in (real_part, imag_part)
@@ -608,9 +608,9 @@ \subsubsection{Type abbreviations}
608608
We can now define \lstinline{mandelbrot_step} as follows:
609609
610610
\begin{lstlisting}
611-
let mandelbrot_step(Zn: complex, C: complex): complex =
612-
let (Zn_r, Zn_i) = Zn
613-
let (C_r, C_i) = C
611+
let mandelbrot_step ((Zn_r, Zn_i): complex)
612+
((C_r, C_i): complex)
613+
: complex =
614614
let real_part = Zn_r*Zn_r - Zn_i*Zn_i + C_r
615615
let imag_part = 2.0*Zn_r*Zn_i + C_i
616616
in (real_part, imag_part)
@@ -1297,8 +1297,9 @@ \section{Size Annotations}
12971297
\section{Records}
12981298
\label{sec:records}
12991299
1300-
Records are a finite map from labels to values. These are supported
1301-
by Futhark as a convenient syntactic extension on top of tuples. As
1300+
Semantically, a record is a finite map from labels to values. These
1301+
are supported by Futhark as a convenient syntactic extension on top of
1302+
tuples. A label-value pairing is often called a \textit{field}. As
13021303
an example, let us return to our previous definition of complex
13031304
numbers:
13041305
@@ -1313,6 +1314,89 @@ \section{Records}
13131314
type complex = {re: f64, im: f64}
13141315
\end{lstlisting}
13151316
1317+
We can construct values of record type with a \textit{record
1318+
expression}, which consists of field assignments enclosed in curly
1319+
braces:
1320+
1321+
\begin{lstlisting}
1322+
let sqrt_minus_one = {re = 0.0, im = -1.0}
1323+
\end{lstlisting}
1324+
1325+
The order of the fields in a record type or value does not matter, so
1326+
the following definition is equivalent to the one above:
1327+
1328+
\begin{lstlisting}
1329+
let sqrt_minus_one = {im = -1.0, re = 0.0}
1330+
\end{lstlisting}
1331+
1332+
In contrast to most other programming languages, record types in
1333+
Futhark are \textit{structural}, not \textit{nominal}. This means
1334+
that the name (if any) of a record type does not matter. For example,
1335+
we can define a type abbreviation that is equivalent to the previous
1336+
definition of \lstinline{complex}:
1337+
1338+
\begin{lstlisting}
1339+
type another_complex = {re: f64, im: f64}
1340+
\end{lstlisting}
1341+
1342+
The types \lstinline{complex} and \lstinline{another_complex} are
1343+
entirely interchangeable. In fact, we do not need to name record
1344+
types at all; they can be used anonymously:
1345+
1346+
\begin{lstlisting}
1347+
let sqrt_minus_one: {re: f64, im: f64} = {re = 0.0, im = -1.0}
1348+
\end{lstlisting}
1349+
1350+
However, for readability purposes it is usually a good idea to use
1351+
type abbreviations when working with records.
1352+
1353+
There are two ways to access the fields of records. The first is by
1354+
\textit{field projection}, which is done by dot notation known from
1355+
most other programming languages. To access the \lstinline{re} field
1356+
of the \lstinline{sqrt_minus_one} value defined above, we write
1357+
\lstinline{sqrt_minus_one.re}.
1358+
1359+
The second way of accessing field values is by pattern matching, just
1360+
like we do with tuples. A record pattern is similar to a record
1361+
expression, and consists of field patterns enclosed in curly braces.
1362+
For example, a function for adding complex numbers could be defined as:
1363+
1364+
\begin{lstlisting}
1365+
let complex_add ({re = x_re, im = x_im}: complex)
1366+
({re = y_re, im = y_im}: complex)
1367+
: complex =
1368+
{re = x_re + y_re, im = x_im + y_im}
1369+
\end{lstlisting}
1370+
1371+
As with tuple patterns, we can use record patterns in both function
1372+
parameters, \lstinline{let}-bindings, and \lstinline{loop} parameters.
1373+
1374+
As a special syntactic convenience, we can elide the \lstinline{= pat}
1375+
part of a record pattern, which will bind the value of the field to a
1376+
variable of the same name as the field. For example:
1377+
1378+
\begin{lstlisting}
1379+
let conj ({re, im}: complex): complex =
1380+
{re = re, im = -im}
1381+
\end{lstlisting}
1382+
1383+
\subsection{Tuples as a Special Case of Records}
1384+
1385+
In Futhark, tuples are merely records with numeric labels starting
1386+
from 1. For example, the types \lstinline{(i32,f64)} and
1387+
\lstinline!{1:i32,2:f64}! are indistinguishable. The main utility of
1388+
this equivalence is that we can use field projection to access the
1389+
components of tuples, rather than using a pattern in a
1390+
\lstinline{let}-binding. For example, we can say \lstinline{foo.1} to
1391+
extract the first component of a tuple.
1392+
1393+
Note that the fields of a record must constitute a prefix of the
1394+
positive numbers for it to be considered a tuple. The record type
1395+
\lstinline!{1:i32,3:f64}! does not correspond to a tuple, and neither
1396+
does \lstinline!{2:i32,3:f64}! (but \lstinline!{2:f64,1:i32}! is
1397+
equivalent to the tuple \lstinline{(i32,f64)}, because field order
1398+
does not matter).
1399+
13161400
\section{Parametric Polymorphism}
13171401
\label{sec:polymorphism}
13181402

0 commit comments

Comments
 (0)