-
Notifications
You must be signed in to change notification settings - Fork 1
/
CHEAT-SHEET.tex
402 lines (330 loc) · 13.4 KB
/
CHEAT-SHEET.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
\documentclass[10pt,landscape,a4paper]{article}
\usepackage[utf8]{inputenc}
%\usepackage[nosf]{kpfonts}
%\usepackage[t1]{sourcesanspro}
\usepackage{multicol}
%\usepackage{wrapfig}
\usepackage[top=5mm,bottom=5mm,left=5mm,right=5mm]{geometry}
%\usepackage{microtype}
\usepackage{fancyvrb}
\usepackage{listings}% http://ctan.org/pkg/listings
\lstset{basicstyle=\ttfamily, mathescape}
\let\bar\overline
\renewcommand{\baselinestretch}{.8}
\pagestyle{empty}
\makeatletter
\setlength{\parindent}{0pt}
\renewcommand{\section}{\@startsection{section}{1}{0mm}%
{.2ex}%
{.2ex}%x
{\sffamily\small\bfseries}}
\renewcommand{\subsection}{\@startsection{subsection}{1}{0mm}%
{.2ex}%
{.2ex}%x
{\sffamily\bfseries}}
\renewcommand{\subsubsection}{\@startsection{subsubsection}{1}{0mm}%
{.2ex}%
{.2ex}%x
{\sffamily\footnotesize\bfseries}}
\begin{document}
\small
\begin{multicols*}{3}
{\sffamily\Large\bfseries Lamtez Cheat-sheet}
\section{Contract}
\begin{Verbatim}[frame=single]
<contract> ::=
<type_declaration*>
<storage_declaration*>
<expression>
\end{Verbatim}
The expression must denote a function, taking a parameter and
returning a result. If types can't be innferred from the code, they must be annotated.
\section{Type declarations}
\subsection{Labelled sum types}
\begin{Verbatim}[frame=single]
type <name>=<Label_0>:<type_0>+...+<Label_n>:<type_n>
\end{Verbatim}
Union of named type cases, in arbitrary number, compiling into nested
\verb|Left/Right| cases. Two products or sum types cannot share a
common label. The value associated with a label can be omitted when it is
of type \verb|unit|.
The following sym types are built-in:
\begin{Verbatim}
type option t = None + Some t
type bool = False + True
type list a = Nil + Cons (a * list a)
\end{Verbatim}
\subsection{Labelled product types}
\begin{Verbatim}[frame=single]
type <name>=<Label_0>:<type_0>*...*<Label_n>:<type_n>
\end{Verbatim}
Record structures with named fields, in arbitrary number, compiling into
nested pairs. Two product or sum types cannot share a common label.
\subsection{Type aliases}
\begin{Verbatim}[frame=single]
type <name> <params>* = <type(params)>
\end{Verbatim}
\verb|type account = contract unit unit| is built-in.
\subsection{Unlabelled tuple types}
\begin{Verbatim}[frame=single]
(type_0 * ... * type_n)
\end{Verbatim}
Unlabelled tuples can be used as annotations without type
declarations, as a parameter for sum cases and product fields, or
named with a type alias.
\verb|type pair a b = (a*b)| is built-in.
\section{Storage declaration}
\begin{Verbatim}[frame=single]
@<name> :: <type> (= <expr>)?
\end{Verbatim}
Storage fields are persisted as the contract's storage. If every
storage field has an initialization value, the compiler can optionally
produce an initial store value litteral (option
\verb|--store-output|). Names can be capitalized or not.
\section{Expressions}
\subsection{Litterals}
{\bf Natural numbers:} \fbox{\tt~[0-9]+~}\\
e.g. \verb|1|, \verb|123456|
{\bf Signed integers:} \fbox{\tt~(+|-)[0-9]+~}\\
e.g. \verb|+1|, \verb|-2|, \verb|+0|.\\
Plus sign is mandatory for ints $\geq0$.\\
Beware that \verb|f+1| (without space) is parsed as \verb|f(+1)|, not \verb|f + 1|.
{\bf Tez:} \fbox{\tt~tz<d>*.<dd> | tz<d>+~}\\
where \verb|<d>| is a decimal digit, \verb|<dd>| a pair thereof.\\
e.g. \verb|tz1|, \verb|tz2.00|, \verb|tz.02|.
{\bf Key hashes:} \fbox{\tt~tz1<b58\_char>+~}\\
e.g. \verb|tz1MGxkasF5ABVVrxzxGbWo8wPg7EaLKn4RS|
{\bf Signatures:} \fbox{\tt~sig:[0-9a-f]+~}\\
e.g. \verb|sig:91b334be19d66d30205563b426c2f9b3|...
{\bf Date:} \fbox{
\begin{minipage}{5.5cm}
\tt dddd-dd-ddTdd:dd:ddZ |\\
dddd-dd-ddTdd:dd:dd(+|-)dd(:dd?)
\end{minipage}}\\
where \verb|d| are decimal digits.\\
e.g. \verb|1970-01-01T00:00:00Z|,\\
\verb| 2014-09-02T12:34:56+02:00|
{\bf String:} \fbox{\tt~"[\^{ }"]*"~}:\\
e.g. \verb|"foo"|, \verb|"hello \"world\""|.\\
Must fit on a single line, double quotes escaped with backslashes;
same escaped characters as Michelson.
\subsection{Composite types and collections}
\begin{Verbatim}[frame=single]
{ <Label_0>:<expr_0>,...,<Label_n>:<expr_n>} # Product
(<expr_0>, ..., <expr_n) # Tuple
(list <expr_0> ... <expr_n>) # List
(set <expr_0> ... <expr_n>) # Set
(map <expr_k0> <expr_v0>...<expr_kn> <expr_vn>) # Map
\end{Verbatim}
\subsection{Identifiers}
Identifiers start with a lowercase letter, can contain alphanumeric
characters, underscores and dashes.
\subsection{Functions}
\begin{Verbatim}[frame=single]
fun (<pattern>(::<type_param>)?)+ (::<type_result>)?:
<expr>
\end{Verbatim}
As in ML, arguments are syntactically separated by spaces without
mandatory parentheses around them. Unlike ML, multi-parameter
functions are encoded with tuples rather than in Curry style,
i.e. \verb|f x y z| is syntax sugar for \verb|f (x, y, z)| not
\verb|(((f x) y) z)|. Function application binds tighter than binary
and unary operators (e.g. \verb|a b + c d| parses as
\verb|a(b) + c(d)|), but looser than product field accessors.
\begin{Verbatim}
f arg_0 arg_1 ... arg_n
f (g arg_g0 arg_g1) arg_f1
\end{Verbatim}
Functions are created with ``\verb|fun|'' standing for the $\lambda$
operator (backslash also accepted for Haskellers); parameters are
comma-separated between them, separated from the function body by a
colon; when parameter types can't be inferred, they must be annotated
with a double-colon \verb|::| sign. Optionally, the function result
can be annotated with a double colon after annotated parameters.
\begin{Verbatim}
fun p: p - 1
fun p0, p1: p0 * p1
fun p0 :: tez, p1 :: nat :: tez: p0 * p1
fun p :: unit: ()
fun p :: unit :: time: self-now
\end{Verbatim}
\subsection{Local variables}
\begin{Verbatim}[frame=single]
let <pattern> = <expr_0>; <expr_1>; ...; <expr_n>
\end{Verbatim}
Local variables are created with the \verb|let| keyword, either as
identifiers, or as binding patterns (nested product types).
\subsection{Binding patterns}
\begin{Verbatim}[frame=single]
<id>
| _
| (<pattern_0>,...,<pattern_n>)
| {<Label_0>:<pattern_0>,...,<Label_n>:<pattern_n>}
\end{Verbatim}
When binding an identifier and a value (in function parameters, let
declarations and sum cases), patterns for product types and tuples can
be used, thus binding several variables simultaneously. Patterns can
be nested. They may not use sum types, as it would introduce the
possibility of runtime failures.
\begin{verbatim}
let (a, b) = (1, 2);
case p | Some {Lon: x, Lat: y}: ... end;
let norm = fun (x, y) :: int*int: x*x + y*y
\end{verbatim}
\subsection{Flow control}
\subsubsection{Sum case deconstruction}
\begin{Verbatim}[frame=single]
case <expr>
| <Label_0> <pattern_0>: <expr_0>
| ...
| <Label_n> <pattern_n>: <expr_n>
end
\end{Verbatim}
Labels can appear in any order, but all cases of one sum type must be
present. Patterns \verb|p_n| which are not used in \verb|e_n| can be
omitted. Booleans, options and lists are sum cases and can be
deconstructed with a sum type.
\subsubsection{If then else / switch}
\begin{Verbatim}[frame=single]
if
| <expr_cond_0>: <expr_if_true_0>
| ...
| <expr_cond_n>: <expr_if_true_n>
| else: <expr_if_everything_false>
end
\end{Verbatim}
The code \verb|<expr_if_true_i>| corresponding to the first true
\verb|<expr_cond_i>| is evaluated. \verb|else| clause may be
ommitted if the result type is \verb|unit|. The first bar after the
\verb|if| is optional.
\vfill\null\columnbreak
\subsection{Field access}
\begin{Verbatim}[frame=single]
<expr>.<d> # Tuple field access
<expr>.<Label> # Product type field access
<expr> <- <Label>: <expr> # Product type field update
@<name> # Persistent field access
@<name> <- <expr>; # Persistent field update
<Label> <expr> # Sum type constructor
\end{Verbatim}
Tuple fields are accessed with a dot followed by the field number, 0-indexed.
Labelled product fiels are accessed with a dot followed by the field label.
Persistent storage fields are accessed with ``\verb|@|'' followed by
the field name. They can be updated
with \verb|@<name> <- <expr>;|,
but such operations cannot occur in a function, a litteral product or
a function argument.
Sum types are constructed with the case label followed by the
associated value; the value can be omitted when its type is
\verb|unit|.
\begin{Verbatim}
let t = ("a","b","c"); t.1; # Tuple access
let p = {X:45,Y: 1}; p.X; # Product access
let s :: option nat = Some 42; # Sum constr.
let x = not @field; # store access
@field <- x # store update
\end{Verbatim}
\subsection{Type annotations}
\begin{Verbatim}[frame=single]
<expr> :: <type>
\end{Verbatim}
Michelson doesn't support polymorphic types. To prevent Lamtez from guessing
such types, as well as to improve contract readbility, you might have to add
type annotations.
\subsection{Operations}
\subsubsection{Binary infix operators}
in decreasing order of precedence:
\begin{itemize}
\itemsep0em
\item \verb|a * b| and \verb|a / b| (euclidian division);
\item \verb|a + b| and \verb|a - b|;
\item bit shifting \verb|a << b| and \verb|a >> b|;
\item comparisons \verb|a < b|, \verb|a <= b|, \verb|a = b|, \verb|a != b|,
\verb|a > b|, \verb|a >= b|;
\item logical and bitwise conjunction \verb|a && b|;
\item logical disjunctions \verb%a || b% and \verb|a ^^ b|.
\end{itemize}
Beware of spaces around addition and substraction: ``\verb|-|'' is a
valid identifier character, and both characters can be interpreted as
prefix sign for a signed literal integer.
\subsubsection{Unary operators}
\verb|-<expr>|, \verb|not <expr>|.\\
Precedence higher than binary ops, lower than field accessors and
function applications.
\subsubsection{Operands and result types}
Operator types and semantics are lifted from Michelson:
\begin{itemize}
\itemsep0em
\item \verb|nat| and \verb|int| can be added/substracted/multiplied
together, and result in a signed \verb|int|, except for \verb|nat+nat| and
\verb|nat*nat| which result in \verb|nat|.
\item As in Michelson, divisions are euclidian, return an (integer
division $*$ natural reminder) option pair (\verb|None| in case of
division by 0).
\item \verb|nat| can be added/substracted with \verb|time|, \verb|tez|
can be added/substracted together.
\item \verb|tez| can be multiplied by \verb|nat|, divided together or
by a \verb|nat|.
\item Logical operators work on \verb|bool| as well as bitwise on \verb|nat|.
\item comparison operators work on every type (both operands must have
the same type, though).
\end{itemize}
\vfill\null\columnbreak
\section{Primitives}
\subsection{Current contract context}
\begin{Verbatim}
val fail :: fail # FAIL
val self-amount :: tez # AMOUNT
val self-balance :: tez # BALANCE
val self-now :: time # NOW
val self-contract :: $\forall$p,r: contract p r # SELF
val self-source :: $\forall$p,r: contract p r # SOURCE
val self-steps-to-quota :: nat # STEPS_TO_QUOTA
\end{Verbatim}
\subsection{Contract management}
\begin{lstlisting}
val contract-call :: $\forall$p,r:
contract p r $\rightarrow$ p $\rightarrow$ tez $\rightarrow$
r # TRANSFER_TOKENS
val contract-create :: $\forall$p,s,r:
key $\rightarrow$ option key $\rightarrow$ bool $\rightarrow$ bool $\rightarrow$
tez $\rightarrow$ (p*s$\rightarrow$r*s) $\rightarrow$ storage $\rightarrow$
contract p r # CREATE_CONTRACT
val contract-create-account ::
key $\rightarrow$ option key $\rightarrow$ bool $\rightarrow$ tez $\rightarrow$
account # CREATE_ACCOUNT
val contract-get ::
key $\rightarrow$ account # DEFAULT_ACCOUNT
val contract-manager :: $\forall$p, s:
contract p s $\rightarrow$ key # MANAGER
\end{lstlisting}
\verb|contract-call| cannot be used in a function / tuple / product / collection.\\
\subsection{Cryptography}
\begin{lstlisting}
val crypto-check :: key $\rightarrow$ sig $\rightarrow$ string $\rightarrow$ bool
val crypto-hash :: $\forall$a: a $\rightarrow$ string
\end{lstlisting}
\subsection{Collections}
\begin{lstlisting}
val list-map :: $\forall$a,b: list a $\rightarrow$ (a$\rightarrow$b) $\rightarrow$ list b
val list-reduce:: $\forall$a,acc:
list a $\rightarrow$ acc $\rightarrow$ (a$\rightarrow$acc$\rightarrow$acc) $\rightarrow$ acc
val list-size :: $\forall$a: list a $\rightarrow$ nat
val set-map :: $\forall$a,b: set a $\rightarrow$ (a$\rightarrow$b) $\rightarrow$ set b
val set-mem :: $\forall$elt: set elt $\rightarrow$ elt $\rightarrow$ bool
val set-reduce :: $\forall$elt acc:
set elt $\rightarrow$ acc $\rightarrow$ (elt$\rightarrow$acc$\rightarrow$acc) $\rightarrow$ acc
val set-update :: $\forall$elt: elt $\rightarrow$ bool $\rightarrow$ set elt
val set-size :: $\forall$elt: set elt $\rightarrow$ nat
val map-get :: $\forall$k,v: k $\rightarrow$ map k v $\rightarrow$ option v
val map-map :: $\forall$k,v0,v1:
map k v0 $\rightarrow$ (k$\rightarrow$v0$\rightarrow$v1) $\rightarrow$ map k v1
val map-mem :: $\forall$k,v: k $\rightarrow$ map k v $\rightarrow$ bool
val map-reduce :: $\forall$k,v,acc:
map k v $\rightarrow$ acc (k$\rightarrow$v$\rightarrow$acc$\rightarrow$acc) $\rightarrow$ $\rightarrow$ acc
val map-update :: $\forall$k,v:
k $\rightarrow$ option v $\rightarrow$ map k v $\rightarrow$ map k v
val map-size :: $\forall$k,v: map k v $\rightarrow$ nat
\end{lstlisting}
\end{multicols*}
\end{document}