Improvements from Sander and JDP.

This commit is contained in:
Christian Rinderknecht 2020-02-06 11:47:41 +01:00
parent 61ec0f41c3
commit 3583f72cb4
9 changed files with 71 additions and 54 deletions

View File

@ -386,13 +386,14 @@ type return = (list (operation), storage);
let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address); let dest : address = ("KT19wgxcuXG9VH4Af5Tpm1vqEKdaMFpznXT3" : address);
let proxy = ((param, store): (parameter, storage)) : return => let proxy = ((param, store): (parameter, storage)) : return => {
let counter : contract (parameter) = Operation.get_contract (dest); let counter : contract (parameter) = Operation.get_contract (dest);
(* Reuse the parameter in the subsequent (* Reuse the parameter in the subsequent
transaction or use another one, `mock_param`. *) transaction or use another one, `mock_param`. *)
let mock_param : parameter = Increment (5n); let mock_param : parameter = Increment (5n);
let op : operation = Operation.transaction (param, 0mutez, counter); let op : operation = Operation.transaction (param, 0mutez, counter);
([op], store); ([op], store)
};
``` ```
<!--END_DOCUSAURUS_CODE_TABS--> <!--END_DOCUSAURUS_CODE_TABS-->

View File

@ -101,8 +101,8 @@ let in_24_hrs : timestamp = today - one_day;
### Comparing Timestamps ### Comparing Timestamps
You can also compare timestamps using the same comparison operators as You can compare timestamps using the same comparison operators
for numbers. applying to numbers.
<!--DOCUSAURUS_CODE_TABS--> <!--DOCUSAURUS_CODE_TABS-->
<!--Pascaligo--> <!--Pascaligo-->
@ -124,10 +124,10 @@ let not_tomorrow : bool = (Current.time == in_24_hrs);
## Addresses ## Addresses
The type `address` in LIGO is used to denote Tezos addresses (tz1, The type `address` in LIGO denotes Tezos addresses (tz1, tz2, tz3,
tz2, tz3, KT1, ...). Currently, addresses are created by casting a KT1, ...). Currently, addresses are created by casting a string to the
string to the type `address`. Beware of failures if the address is type `address`. Beware of failures if the address is invalid. Consider
invalid. Consider the following examples. the following examples.
<!--DOCUSAURUS_CODE_TABS--> <!--DOCUSAURUS_CODE_TABS-->
<!--Pascaligo--> <!--Pascaligo-->
@ -152,7 +152,7 @@ let my_account : address =
## Signatures ## Signatures
The type `signature` in LIGO datatype is used for Tezos signature The `signature` type in LIGO datatype is used for Tezos signatures
(edsig, spsig). Signatures are created by casting a string. Beware of (edsig, spsig). Signatures are created by casting a string. Beware of
failure if the signature is invalid. failure if the signature is invalid.
@ -181,7 +181,7 @@ signature);
## Keys ## Keys
The type `key` in LIGO is used for Tezos public keys. Do not confuse The `key` type in LIGO is used for Tezos public keys. Do not confuse
them with map keys. Keys are made by casting strings. Beware of them with map keys. Keys are made by casting strings. Beware of
failure if the key is invalid. failure if the key is invalid.

View File

@ -34,7 +34,10 @@ In LIGO, only values of the same type can be compared. Moreover, not
all values of the same type can be compared, only those with all values of the same type can be compared, only those with
*comparable types*, which is a concept lifted from *comparable types*, which is a concept lifted from
Michelson. Comparable types include, for instance, `int`, `nat`, Michelson. Comparable types include, for instance, `int`, `nat`,
`string`, `tez`, `timestamp`, `address`, etc. `string`, `tez`, `timestamp`, `address`, etc. As an example of
non-comparable types: maps, sets or lists are not comparable: if you
wish to compare them, you will have to write your own comparison
function.
### Comparing Strings ### Comparing Strings
@ -110,7 +113,7 @@ let h : bool = (a != b);
```pascaligo group=d ```pascaligo group=d
const a : tez = 5mutez const a : tez = 5mutez
const b : tez = 10mutez const b : tez = 10mutez
const c : bool = (a = b) // false const c : bool = (a = b) // False
``` ```
<!--CameLIGO--> <!--CameLIGO-->
```cameligo group=d ```cameligo group=d
@ -129,7 +132,7 @@ let c : bool = (a == b); // false
## Conditionals ## Conditionals
Conditional logic enables to fork the control flow depending on the Conditional logic enables forking the control flow depending on the
state. state.
<!--DOCUSAURUS_CODE_TABS--> <!--DOCUSAURUS_CODE_TABS-->

View File

@ -10,11 +10,11 @@ logic into functions.
## Blocks ## Blocks
In PascaLIGO, *blocks* enable the sequential composition of In PascaLIGO, *blocks* enable the sequential composition of
*instructions* into an isolated scope. Each `block` needs to include instructions into an isolated scope. Each block needs to include at
at least one instruction. If we need a placeholder *placeholder*, we least one instruction. If we need a placeholder, we use the
use the instruction called `skip`, that leaves the state instruction `skip` which leaves the state unchanged. The rationale
invariant. The rationale for `skip` instead of a truly empty block is for `skip` instead of a truly empty block is that it prevents you from
that it prevents you from writing an empty block by mistake. writing an empty block by mistake.
<!--DOCUSAURUS_CODE_TABS--> <!--DOCUSAURUS_CODE_TABS-->
<!--Pascaligo--> <!--Pascaligo-->
@ -31,10 +31,10 @@ Blocks are more versatile than simply containing instructions:
they can also include *declarations* of values, like so: they can also include *declarations* of values, like so:
```pascaligo skip ```pascaligo skip
// terse style // terse style
block { const a : int = 1; } block { const a : int = 1 }
// verbose style // verbose style
begin begin
const a : int = 1; const a : int = 1
end end
``` ```

View File

@ -64,7 +64,7 @@ to have a special type: if the type of the accumulator is `t`, then it
must have the type `bool * t` (not simply `t`). It is the boolean must have the type `bool * t` (not simply `t`). It is the boolean
value that denotes whether the stopping condition has been reached. value that denotes whether the stopping condition has been reached.
```cameligo group=b ```cameligo group=a
let iter (x,y : nat * nat) : bool * (nat * nat) = let iter (x,y : nat * nat) : bool * (nat * nat) =
if y = 0n then false, (x,y) else true, (y, x mod y) if y = 0n then false, (x,y) else true, (y, x mod y)
@ -77,7 +77,7 @@ let gcd (x,y : nat * nat) : nat =
To ease the writing and reading of the iterated functions (here, To ease the writing and reading of the iterated functions (here,
`iter`), two predefined functions are provided: `continue` and `stop`: `iter`), two predefined functions are provided: `continue` and `stop`:
```cameligo group=c ```cameligo group=a
let iter (x,y : nat * nat) : bool * (nat * nat) = let iter (x,y : nat * nat) : bool * (nat * nat) =
if y = 0n then stop (x,y) else continue (y, x mod y) if y = 0n then stop (x,y) else continue (y, x mod y)
@ -113,27 +113,29 @@ accumulator is `t`, then it must have the type `bool * t` (not simply
`t`). It is the boolean value that denotes whether the stopping `t`). It is the boolean value that denotes whether the stopping
condition has been reached. condition has been reached.
```reasonligo group=d ```reasonligo group=a
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) => let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
if (y == 0n) { (false, (x,y)); } else { (true, (y, x mod y)); }; if (y == 0n) { (false, (x,y)); } else { (true, (y, x mod y)); };
let gcd = ((x,y) : (nat, nat)) : nat => let gcd = ((x,y) : (nat, nat)) : nat => {
let (x,y) = if (x < y) { (y,x); } else { (x,y); }; let (x,y) = if (x < y) { (y,x); } else { (x,y); };
let (x,y) = Loop.fold_while (iter, (x,y)); let (x,y) = Loop.fold_while (iter, (x,y));
x; x
};
``` ```
To ease the writing and reading of the iterated functions (here, To ease the writing and reading of the iterated functions (here,
`iter`), two predefined functions are provided: `continue` and `stop`: `iter`), two predefined functions are provided: `continue` and `stop`:
```reasonligo group=e ```reasonligo group=b
let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) => let iter = ((x,y) : (nat, nat)) : (bool, (nat, nat)) =>
if (y == 0n) { stop ((x,y)); } else { continue ((y, x mod y)); }; if (y == 0n) { stop ((x,y)); } else { continue ((y, x mod y)); };
let gcd = ((x,y) : (nat, nat)) : nat => let gcd = ((x,y) : (nat, nat)) : nat => {
let (x,y) = if (x < y) { (y,x); } else { (x,y); }; let (x,y) = if (x < y) { (y,x); } else { (x,y); };
let (x,y) = Loop.fold_while (iter, (x,y)); let (x,y) = Loop.fold_while (iter, (x,y));
x; x
};
``` ```
<!--END_DOCUSAURUS_CODE_TABS--> <!--END_DOCUSAURUS_CODE_TABS-->
@ -147,7 +149,7 @@ To iterate over a range of integers you use a loop of the form `for
familiar for programmers of imperative languages. Note that, for the familiar for programmers of imperative languages. Note that, for the
sake of generality, the bounds are of type `int`, not `nat`. sake of generality, the bounds are of type `int`, not `nat`.
```pascaligo group=f ```pascaligo group=c
function sum (var n : nat) : int is block { function sum (var n : nat) : int is block {
var acc : int := 0; var acc : int := 0;
for i := 1 to int (n) block { for i := 1 to int (n) block {
@ -177,7 +179,7 @@ of the form `for <element var> in <collection type> <collection var>
Here is an example where the integers in a list are summed up. Here is an example where the integers in a list are summed up.
```pascaligo group=g ```pascaligo group=d
function sum_list (var l : list (int)) : int is block { function sum_list (var l : list (int)) : int is block {
var total : int := 0; var total : int := 0;
for i in list l block { for i in list l block {
@ -197,7 +199,7 @@ gitlab-pages/docs/language-basics/src/loops/collection.ligo sum_list
Here is an example where the integers in a set are summed up. Here is an example where the integers in a set are summed up.
```pascaligo=g ```pascaligo=e
function sum_set (var s : set (int)) : int is block { function sum_set (var s : set (int)) : int is block {
var total : int := 0; var total : int := 0;
for i in set s block { for i in set s block {

View File

@ -358,7 +358,7 @@ let moves : register =
let moves : register = let moves : register =
Map.literal ([ Map.literal ([
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)), ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3)),]); ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
``` ```
> The `Map.literal` predefined function builds a map from a list of > The `Map.literal` predefined function builds a map from a list of
@ -377,8 +377,8 @@ example:
<!--DOCUSAURUS_CODE_TABS--> <!--DOCUSAURUS_CODE_TABS-->
<!--Pascaligo--> <!--Pascaligo-->
```pascaligo group=f ```pascaligo group=f
(*const my_balance : option (move) = const my_balance : option (move) =
moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)] *) moves [("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address)]
``` ```
<!--Cameligo--> <!--Cameligo-->
@ -418,11 +418,12 @@ let force_access (key, moves : address * register) : move =
``` ```
<!--Reasonligo--> <!--Reasonligo-->
```reasonlig group=f ```reasonligo group=f
let force_access : ((key, moves) : address * register) : move => { let force_access = ((key, moves) : (address, register)) : move => {
switch (Map.find_opt key moves) with switch (Map.find_opt (key, moves)) {
Some move -> move | Some (move) => move
| None -> (failwith "No move." : move) | None => failwith ("No move.") : move
}
}; };
``` ```
<!--END_DOCUSAURUS_CODE_TABS--> <!--END_DOCUSAURUS_CODE_TABS-->
@ -475,9 +476,8 @@ let assign (m : register) : register =
``` ```
> Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had > Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
> use `None` instead, that would have meant that the binding is only > use `None` instead, that would have meant that the binding is
> defined on its key, but not its value. This encoding enables > removed.
> partially defined bindings.
<!--Reasonligo--> <!--Reasonligo-->
@ -492,9 +492,8 @@ let assign = (m : register) : register => {
``` ```
> Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had > Notice the optional value `Some (4,9)` instead of `(4,9)`. If we had
> use `None` instead, that would have meant that the binding is only > use `None` instead, that would have meant that the binding is
> defined on its key, but not its value. This encoding enables > removed.
> partially defined bindings.
<!--END_DOCUSAURUS_CODE_TABS--> <!--END_DOCUSAURUS_CODE_TABS-->
@ -601,7 +600,7 @@ let map_op = (m : register) : register => {
A *fold operation* is the most general of iterations. The iterated A *fold operation* is the most general of iterations. The iterated
function takes two arguments: an *accumulator* and the structure function takes two arguments: an *accumulator* and the structure
*element* at hand, with which it then produces a new accumulator. This *element* at hand, with which it then produces a new accumulator. This
enables to have a partial result that becomes complete when the enables having a partial result that becomes complete when the
traversal of the data structure is over. traversal of the data structure is over.
<!--DOCUSAURUS_CODE_TABS--> <!--DOCUSAURUS_CODE_TABS-->
@ -622,7 +621,7 @@ let fold_op (m : register) : register =
<!--Reasonligo--> <!--Reasonligo-->
```reasonligo group=f ```reasonligo group=f
let fold_op = (m: register): register => { let fold_op = (m : register) : register => {
let aggregate = ((i,j): (int, (address, move))) => i + j[1][1]; let aggregate = ((i,j): (int, (address, move))) => i + j[1][1];
Map.fold (aggregate, m, 5); Map.fold (aggregate, m, 5);
}; };
@ -703,7 +702,7 @@ let moves : register =
let moves : register = let moves : register =
Big_map.literal ([ Big_map.literal ([
("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)), ("tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx" : address, (1,2)),
("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3)),]); ("tz1gjaF81ZRRvdzjobyfVNsAeSC6PScjfQwN" : address, (0,3))]);
``` ```
> The predefind function `Big_map.literal` constructs a big map from a > The predefind function `Big_map.literal` constructs a big map from a

View File

@ -8,15 +8,14 @@ LIGO offers three built-in numerical types: `int`, `nat` and `tez`.
## Addition ## Addition
Addition in LIGO is accomplished by means of the `+` infix Addition in LIGO is accomplished by means of the `+` infix
operator. Some type constraints apply, for example you ca not add a operator. Some type constraints apply, for example you cannot add a
value of type `tez` to a value of type `nat`. value of type `tez` to a value of type `nat`.
In the following example you can find a series of arithmetic In the following example you can find a series of arithmetic
operations, including various numerical types. However, some bits operations, including various numerical types. However, some bits
remain in comments because they would otherwise not compile because, remain in comments as they would otherwise not compile, for example,
for example, adding a value of type `int` to a value of type `tez` is adding a value of type `int` to a value of type `tez` is invalid. Note
invalid. Note that adding an integer to a natural number produces an that adding an integer to a natural number produces an integer.
integer.
<!--DOCUSAURUS_CODE_TABS--> <!--DOCUSAURUS_CODE_TABS-->
<!--Pascaligo--> <!--Pascaligo-->
@ -115,7 +114,7 @@ let g : int = 1_000_000;
## Subtraction ## Subtraction
Subtraction looks like as follows. Subtraction looks as follows.
> ⚠️ Even when subtracting two `nats`, the result is an `int` > ⚠️ Even when subtracting two `nats`, the result is an `int`

View File

@ -0,0 +1,6 @@
type coin = Head | Tail
let flip (c : coin) : coin =
match c with
Head -> Tail
| Tail -> Head

View File

@ -0,0 +1,7 @@
type coin = | Head | Tail;
let flip = (c : coin) : coin =>
switch (c) {
| Head => Tail
| Tail => Head
};