From 1f0ea4869ba28b372064a76fc7a059fc358adb53 Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Fri, 30 May 2025 15:16:41 -0400 Subject: [PATCH] Rework conditionals topic in language-basics --- gitlab-pages/docs/data-types/booleans.md | 73 +-- gitlab-pages/docs/data-types/variants.md | 4 +- gitlab-pages/docs/imperative/conditionals.md | 114 ++++ .../imperative/src/conditionals/if.jsligo | 7 + .../docs/language-basics/boolean-if-else.md | 539 ------------------ .../src/boolean-if-else/a.jsligo | 2 - .../src/boolean-if-else/a.mligo | 2 - .../src/boolean-if-else/b.jsligo | 3 - .../src/boolean-if-else/b.mligo | 3 - .../src/boolean-if-else/c.jsligo | 8 - .../src/boolean-if-else/c.mligo | 8 - .../src/boolean-if-else/cond.jsligo | 6 - .../src/boolean-if-else/cond.mligo | 4 - .../src/boolean-if-else/d.jsligo | 8 - .../src/boolean-if-else/d.mligo | 8 - .../src/boolean-if-else/e.jsligo | 3 - .../src/boolean-if-else/e.mligo | 3 - .../src/boolean-if-else/switch.jsligo | 28 - .../src/boolean-if-else/ungrouped.jsligo | 15 - .../src/boolean-if-else/ungrouped.mligo | 9 - gitlab-pages/docs/syntax/comparisons.md | 307 ++++++++++ gitlab-pages/website/sidebars.js | 2 + 22 files changed, 459 insertions(+), 697 deletions(-) create mode 100644 gitlab-pages/docs/imperative/conditionals.md create mode 100644 gitlab-pages/docs/imperative/src/conditionals/if.jsligo delete mode 100644 gitlab-pages/docs/language-basics/boolean-if-else.md delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/a.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/a.mligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/b.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/b.mligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/c.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/c.mligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/cond.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/cond.mligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/d.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/d.mligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/e.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/e.mligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/switch.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.jsligo delete mode 100644 gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.mligo create mode 100644 gitlab-pages/docs/syntax/comparisons.md diff --git a/gitlab-pages/docs/data-types/booleans.md b/gitlab-pages/docs/data-types/booleans.md index 318d15210b..7f3079b576 100644 --- a/gitlab-pages/docs/data-types/booleans.md +++ b/gitlab-pages/docs/data-types/booleans.md @@ -5,7 +5,7 @@ title: Booleans import Syntax from '@theme/Syntax'; -The predefined type `bool` has exactly two values: `true` and `false`. +The predefined Boolean type `bool` has exactly two values: `true` and `false`. @@ -29,9 +29,7 @@ const b: bool = false; -The logical disjunction ("or") is implemented by the binary operator -`||`: - +The logical disjunction ("or") is implemented by the binary operator `||`: ```cameligo group=or let or_1 : bool = false || true // true @@ -40,8 +38,7 @@ let or_3 : bool = true || true // true let or_4 : bool = true || false // true ``` -Note that you can also use the keyword `or` instead of the symbol `||` -(as in OCaml): +You can also use the keyword `or` instead of the symbol `||` (as in OCaml): ```cameligo group=or let or_1 : bool = false or true // true @@ -54,8 +51,7 @@ let or_4 : bool = true or false // true -The logical disjunction ("or") is implemented by the binary operator -`||`. +The logical disjunction ("or") is implemented by the binary operator `||`. ```jsligo group=or const or_1: bool = false || true; // true @@ -68,8 +64,7 @@ const or_4: bool = true || false; // true ## And -The logical conjunction ("and") is implemented by the binary operator -`&&`. +The logical conjunction ("and") is implemented by the binary operator `&&`. @@ -97,8 +92,7 @@ const and_4: bool = true && false; // false -The logical negation ("not") is implemented by the unary operator -`not`. +The logical negation ("not") is implemented by the unary operator `not`. ```cameligo group=not let not_1 : bool = not true // false @@ -109,8 +103,7 @@ let not_2 : bool = not false // true -The logical negation ("not") is implemented by the unary operator -`!`. +The logical negation ("not") is implemented by the unary operator `!`. ```jsligo group=not const not_1: bool = !true // false @@ -121,12 +114,10 @@ const not_2: bool = !false // true ## Comparing -Boolean values are the result of comparisons of values. Numbers and -strings are completely ordered. Booleans can be compared for -equality. Two values need to be of the same type to be compared, but -not all values of the same type can be compared: only those with comparable types (a concept directly lifted from Michelson) -such as `int`, `nat`, `string`, and `bool` itself. The comparison -operators are overloaded so they are defined on all comparable types. +Boolean values are the result of comparisons of other values. +As described in [Comparisons](../syntax/comparisons), values must be the same type to be compared, and not all types are comparable. +You can compare comparable types such as `int`, `nat`, `string`, and `bool` to each other. +The comparison operators are overloaded so they are defined on all comparable types, as in these examples: @@ -154,41 +145,31 @@ const f: bool = 0 <= 0; // lower than or equal (true) -## Conditional expressions - -Conditional logic enables forking the control flow depending on the -state, that is, the values available at a given point in the code. Put -in a less technical manner, conditionals enable decision making. - -A conditional expression is made of three parts: -
    -
  1. a condition, that is, a boolean expression;
  2. -
  3. an expression evaluated if, and only if, the condition is true;
  4. -
  5. an expression evaluated if, and only if, the condition is false.
  6. -
+You can also use a single value to create a Boolean value. +For example, empty strings and the number 0 are false, while strings with any content in them and nonzero numbers are true: -The syntax uses the keywords `if`, `then` and `else` to separate the -three parts, like so: - -```cameligo group=conditionals -let a = 0 -let b = 1 -let min = if a < b then a else b // min = 0 +```cameligo group=unary_boolean +let natToBoolTrue : bool = 1n (* True *) +let natToBoolFalse : bool = 0n (* False *) +let stringToBoolTrue : bool = "A" (* True *) +let stringToBoolFalse : bool = "" (* False *) ``` -The syntax uses a ternary operator with the symbols `?` and `:` to -separate the three parts: - -```jsligo group=conditionals -const a = 0; -const b = 1; -const min = (a < b) ? a : b; // min == 0 +```jsligo group=unary_boolean +const natToBoolTrue: bool = (1 as nat); // True +const natToBoolFalse: bool = (0 as nat); // False +const stringToBoolTrue: bool = "A"; // True +const stringToBoolFalse: bool = ""; // False ``` + +For more information about comparing values, see [Comparisons](../syntax/comparisons). + +You can use Boolean values and comparisons in logical `if` and `else` statements like many other languages; see [Conditionals](../imperative/conditionals). diff --git a/gitlab-pages/docs/data-types/variants.md b/gitlab-pages/docs/data-types/variants.md index 72d7b9f8e6..718fc58980 100644 --- a/gitlab-pages/docs/data-types/variants.md +++ b/gitlab-pages/docs/data-types/variants.md @@ -67,8 +67,8 @@ type user = | ["Manager", id] | ["Guest"]; -const bob : user = ["Admin" as "Admin", 1000 as nat]; -const carl : user = ["Guest" as "Guest"]; +const bob: user = ["Admin" as "Admin", 1000 as nat]; +const carl: user = ["Guest" as "Guest"]; ``` A constant constructor is equivalent to the same constructor taking a value of type `unit`, so, for example, `["Guest" as "Guest"]` is the same value as `["Guest" as "Guest", []]` and `["Guest" as "Guest", unit]`. diff --git a/gitlab-pages/docs/imperative/conditionals.md b/gitlab-pages/docs/imperative/conditionals.md new file mode 100644 index 0000000000..27443e0260 --- /dev/null +++ b/gitlab-pages/docs/imperative/conditionals.md @@ -0,0 +1,114 @@ +--- +id: conditionals +title: Conditionals +--- + +LIGO includes logical `if` and `else` statements like many other languages. + + + +```cameligo group=if +let greater_than_5 (input : int) : bool = + if input > 5 then true else false +``` + +:::note + +As in OCaml, in CameLIGO, if a conditional has a branch `else ()`, that branch can be omitted. +The resulting so-called *dangling else* problem is parsed by associating any `else` to the closest previous `then`. + +::: + + + + + +```jsligo group=if +function greater_than_5(input: int) { + if (input > 5) { + return true; + } else { + return false; + } +} +``` + + + + + +## Switch statement + +JsLIGO also supports branching of control flow via the `switch` statement. + +```jsligo group=switch +let quarter = n => { + let output = ""; + switch (n) { + case 1: + case 2: + case 3: + output = "Q1"; + break; + case 4: + case 5: + case 6: + output = "Q2"; + break; + case 7: + case 8: + case 9: + output = "Q3"; + break; + case 10: + case 11: + case 12: + output = "Q4"; + break; + default: + output = "Invalid month." + }; + return output; +} +``` + +The `switch` statement takes an expression and tries to find a case that matches the expression. +If a matching case is found, the statements of the matching case are executed until a `break;` statement. +If no `break` statement is found, LIGO continues to the next case or `default` case. +If no matching case is found, LIGO runs the statements in the `default` case. + +In LIGO, the `switch` statement has these limitations: + +- The `switch` statement must have at least one case or `default` case. +- If a `default` case is provided, it should be the last case. +- Conditional `break` statements are not supported; for example, you can't include a `break` statement inside a `if-then-else` block. +- In the case of nested `switch` statements, the inner `switch` statement should not contain a `return` statement. + +You can run the `quarter` function defined above using the LIGO compiler like this: + +```shell +ligo run evaluate-call gitlab-pages/docs/imperative/src/conditionals/switch.jsligo quarter '5' +# Outputs: "Q2" +``` + +## Ternary conditional expression + +JsLIGO also supports JavaScript's ternary expression: + +```jsligo group=ternary +const ternary = a => (a == 1) ? true : false; +``` + +Ternary expressions can be nested, as in this example: + +```jsligo group=ternary +const ternary_nested = a => + a == 1 ? "one" : + a == 2 ? "two" : + a == 3 ? "three" : + "other" +``` + + + + \ No newline at end of file diff --git a/gitlab-pages/docs/imperative/src/conditionals/if.jsligo b/gitlab-pages/docs/imperative/src/conditionals/if.jsligo new file mode 100644 index 0000000000..399a22baa2 --- /dev/null +++ b/gitlab-pages/docs/imperative/src/conditionals/if.jsligo @@ -0,0 +1,7 @@ +function greater_than_5(input: int) { + if (input > 5) { + return true; + } else { + return false; + } +} \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/boolean-if-else.md b/gitlab-pages/docs/language-basics/boolean-if-else.md deleted file mode 100644 index d8f2d4b015..0000000000 --- a/gitlab-pages/docs/language-basics/boolean-if-else.md +++ /dev/null @@ -1,539 +0,0 @@ ---- -id: boolean-if-else -title: Booleans and Conditionals ---- - -import Syntax from '@theme/Syntax'; - -## Booleans - -The type of a boolean value is `bool`. Here is how to define a boolean -value: - - - -```cameligo group=a -let a : bool = true -let b : bool = false -``` - - - - - -```jsligo group=a -const a = true; -const b = false; -``` - - - -Common operations: - - -
-
- && -
-
- Logical and -
-
- -```cameligo -let logical_and: bool = true && true -``` - -
-
- || -
-
- Logical or -
-
- -```cameligo -let logical_or: bool = false || true -``` - -
-
- not -
-
- Logical not -
-
- -```cameligo -let logical_not: bool = not false -``` - -
-
- = -
-
- Equals -
-
- -```cameligo -let eq: bool = 2 = 3 -``` - -
-
- <> -
-
- Not equals -
-
- -```cameligo -let not_eq: bool = 2 <> 3 -``` - -
-
- > -
-
- Greater than -
-
- -```cameligo -let gt: bool = 4 > 3 -``` - -
-
- < -
-
- Less than -
-
- -```cameligo -let lt: bool = 4 < 3 -``` - -
-
- >= -
-
- Greater than or equal to -
-
- -```cameligo -let gte: bool = 4 >= 3 -``` - -
-
- <= -
-
- Less than or equal to -
-
- -```cameligo -let lte: bool = 4 <= 3 -``` - -
-
-
- - - -
-
- && -
-
- Logical and -
-
- -```jsligo -const logical_and = true && true; -``` - -
-
- || -
-
- Logical or -
-
- -```jsligo -const logical_or = false || true; -``` - -
-
- ! -
-
- Logical not -
-
- -```jsligo -const logical_not = !false; -``` - -
-
- == -
-
- Equals -
-
- -```jsligo -const eq = 2 == 3; -``` - -
-
- != -
-
- Not equals -
-
- -```jsligo -const not_eq = 2 != 3; -``` - -
-
- > -
-
- Greater than -
-
- -```jsligo -const gt = 4 > 3; -``` - -
-
- < -
-
- Less than -
-
- -```jsligo -const lt = 4 < 3; -``` - -
-
- >= -
-
- Greater than or equal to -
-
- -```jsligo -const gte = 4 >= 3; -``` - -
-
- <= -
-
- Less than or equal to -
-
- -```jsligo -const lte = 4 <= 3; -``` - -
-
-
- - -## Comparing Values - -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 -*comparable types*, which is a concept lifted from -Michelson. Comparable types include, for instance, `int`, `nat`, `bytes` -`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. - -> Note: when running in test mode (this is, in the testing framework), -> for developer convinence, more types are made comparable. Maps, sets -> and lists will be made comparable in case its elements are -> comparable. - -### Comparing Strings - - - -```cameligo group=b -let a : string = "Alice" -let b : string = "Alice" -let c : bool = (a = b) (* true *) -``` - - - - - -```jsligo group=b -const a = "Alice"; -const b = "Alice"; -const c = (a == b); // true -``` - - - - -### Comparing numbers - - - -```cameligo group=c -let a : int = 5 -let b : int = 4 -let c : bool = (a = b) -let d : bool = (a > b) -let e : bool = (a < b) -let f : bool = (a <= b) -let g : bool = (a >= b) -let h : bool = (a <> b) -``` - - - - -```jsligo group=c -const a : int = 5; -const b : int = 4; -const c : bool = (a == b); -const d : bool = (a > b); -const e : bool = (a < b); -const f : bool = (a <= b); -const g : bool = (a >= b); -const h : bool = (a != b); -``` - - - -### Comparing bytes - - - -To check if the following operators have the expected result use -`ligo compile expression cameligo "a OP b"` - -Usage: - -```cameligo group=d -let a : bytes = 0x1001 -let b : bytes = 0x1000 -let c : bool = (a = b) -let d : bool = (a > b) -let e : bool = (a < b) -let f : bool = (a <= b) -let g : bool = (a >= b) -let h : bool = (a <> b) -``` - - - - - -To check if the following operators have the expected result use -`ligo compile expression jsligo "a OP b"` - -Usage: - -```jsligo group=d -const a : bytes = 0x1001; -const b : bytes = 0x1000; -const c : bool = (a == b); -const d : bool = (a > b); -const e : bool = (a < b); -const f : bool = (a <= b); -const g : bool = (a >= b); -const h : bool = (a != b); -``` - - - -### Comparing tez - -> 💡 Comparing `tez` values is especially useful when dealing with an -> amount sent in a transaction. - - - -```cameligo group=e -let a : tez = 5mutez -let b : tez = 10mutez -let c : bool = (a = b) // false -``` - - - - - -```jsligo group=e -const a: tez = 5 as mutez; -const b: tez = 10 as mutez; -const c : bool = (a == b); // false -``` - - - -## Conditionals - -Conditional logic enables forking the control flow depending on the -state. - - - -```cameligo group=cond -type magnitude = Small | Large (* See variant types. *) - -let compare (n : nat) : magnitude = - if n < 10n then Small else Large -``` - -You can run the `compare` function defined above using the LIGO compiler -like this: -```shell -ligo run evaluate-call gitlab-pages/docs/language-basics/src/boolean-if-else/cond.mligo compare '21n' -# Outputs: Large -``` - -> Notice that, as in OCaml, in CameLIGO, if a conditional has a branch -> `else ()`, that branch can be omitted. The resulting so-called -> *dangling else* problem is parsed by associating any `else` to the -> closest previous `then`. - - - - -```jsligo group=cond -type magnitude = ["Small"] | ["Large"]; // See variant types. - -const compare = (n: nat): magnitude => { - if (n < (10 as nat)) return ["Small" as "Small"]; - return ["Large" as "Large"] -}; -``` - -You can run the `compare` function defined above using the LIGO compiler -like this: -```shell -ligo run evaluate-call gitlab-pages/docs/language-basics/src/boolean-if-else/cond.jsligo compare '21n' -# Outputs: Large -``` - - - - - - - -## Switch Statement - -JsLIGO also supports branching of control flow via the switch statement. - -```jsligo group=switch -let quarter = n => { - let output = ""; - switch (n) { - case 1: - case 2: - case 3: - output = "Q1"; - break; - case 4: - case 5: - case 6: - output = "Q2"; - break; - case 7: - case 8: - case 9: - output = "Q3"; - break; - case 10: - case 11: - case 12: - output = "Q4"; - break; - default: - output = "Invalid month." - }; - return output; -} -``` - -The switch statement takes an expression and tries to find a `case` which matches the switch expression, -If a matching `case` is found, the statements of the matching case are executed untill a `break;` statement. -If no `break` is found the control falls through to the next `case` or `default`. If no matching case is found -the statements of the `default` case are executed. - -> A few gotcha's about the switch statement -> 1. A switch should have at-least one `case` or `default`. -> 2. If a `default` case is provided, It should be the last case. -> 3. Conditional `break`'s are not supported i.e. `break` inside a `if-then-else`. -> 4. In case of nested `switch` statements, the inner `switch` should not contain a `return`. - -You can run the `quarter` function defined above using the LIGO compiler -like this: -```shell -ligo run evaluate-call gitlab-pages/docs/language-basics/src/boolean-if-else/switch.jsligo quarter '5' -# Outputs: "Q2" -``` - -### Ternary conditional expression -JsLIGO also supports JavaScript's ternary expression: - -```jsligo -const ternary = a => (a == 1) ? true : false; -``` - -which can also be nested: - -```jsligo -const ternary_nested = a => - a == 1 ? "one" : - a == 2 ? "two" : - a == 3 ? "three" : - "other" -``` - - - - diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/a.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/a.jsligo deleted file mode 100644 index 26406bb67e..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/a.jsligo +++ /dev/null @@ -1,2 +0,0 @@ -const a = true; -const b = false; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/a.mligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/a.mligo deleted file mode 100644 index 40b61003f3..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/a.mligo +++ /dev/null @@ -1,2 +0,0 @@ -let a : bool = true -let b : bool = false \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/b.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/b.jsligo deleted file mode 100644 index d8922a667e..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/b.jsligo +++ /dev/null @@ -1,3 +0,0 @@ -const a = "Alice"; -const b = "Alice"; -const c = (a == b); // true \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/b.mligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/b.mligo deleted file mode 100644 index c44ac30fd7..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/b.mligo +++ /dev/null @@ -1,3 +0,0 @@ -let a : string = "Alice" -let b : string = "Alice" -let c : bool = (a = b) (* true *) \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/c.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/c.jsligo deleted file mode 100644 index eb51588c3a..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/c.jsligo +++ /dev/null @@ -1,8 +0,0 @@ -const a : int = 5; -const b : int = 4; -const c : bool = (a == b); -const d : bool = (a > b); -const e : bool = (a < b); -const f : bool = (a <= b); -const g : bool = (a >= b); -const h : bool = (a != b); \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/c.mligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/c.mligo deleted file mode 100644 index 4bdc60788a..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/c.mligo +++ /dev/null @@ -1,8 +0,0 @@ -let a : int = 5 -let b : int = 4 -let c : bool = (a = b) -let d : bool = (a > b) -let e : bool = (a < b) -let f : bool = (a <= b) -let g : bool = (a >= b) -let h : bool = (a <> b) \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/cond.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/cond.jsligo deleted file mode 100644 index 010a9fc13e..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/cond.jsligo +++ /dev/null @@ -1,6 +0,0 @@ -type magnitude = ["Small"] | ["Large"]; // See variant types. - -const compare = (n: nat): magnitude => { - if (n < (10 as nat)) return ["Small" as "Small"]; - return ["Large" as "Large"] -}; \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/cond.mligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/cond.mligo deleted file mode 100644 index 1920e50798..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/cond.mligo +++ /dev/null @@ -1,4 +0,0 @@ -type magnitude = Small | Large (* See variant types. *) - -let compare (n : nat) : magnitude = - if n < 10n then Small else Large \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/d.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/d.jsligo deleted file mode 100644 index 7f42a35a36..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/d.jsligo +++ /dev/null @@ -1,8 +0,0 @@ -const a : bytes = 0x1001; -const b : bytes = 0x1000; -const c : bool = (a == b); -const d : bool = (a > b); -const e : bool = (a < b); -const f : bool = (a <= b); -const g : bool = (a >= b); -const h : bool = (a != b); \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/d.mligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/d.mligo deleted file mode 100644 index d2dc45a8c2..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/d.mligo +++ /dev/null @@ -1,8 +0,0 @@ -let a : bytes = 0x1001 -let b : bytes = 0x1000 -let c : bool = (a = b) -let d : bool = (a > b) -let e : bool = (a < b) -let f : bool = (a <= b) -let g : bool = (a >= b) -let h : bool = (a <> b) \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/e.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/e.jsligo deleted file mode 100644 index d08bec27e5..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/e.jsligo +++ /dev/null @@ -1,3 +0,0 @@ -const a: tez = 5 as mutez; -const b: tez = 10 as mutez; -const c : bool = (a == b); // false \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/e.mligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/e.mligo deleted file mode 100644 index 3736af71a3..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/e.mligo +++ /dev/null @@ -1,3 +0,0 @@ -let a : tez = 5mutez -let b : tez = 10mutez -let c : bool = (a = b) // false \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/switch.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/switch.jsligo deleted file mode 100644 index 6a8d504d9a..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/switch.jsligo +++ /dev/null @@ -1,28 +0,0 @@ -let quarter = n => { - let output = ""; - switch (n) { - case 1: - case 2: - case 3: - output = "Q1"; - break; - case 4: - case 5: - case 6: - output = "Q2"; - break; - case 7: - case 8: - case 9: - output = "Q3"; - break; - case 10: - case 11: - case 12: - output = "Q4"; - break; - default: - output = "Invalid month." - }; - return output; -} \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.jsligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.jsligo deleted file mode 100644 index bb59e4976b..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.jsligo +++ /dev/null @@ -1,15 +0,0 @@ -const logical_and = true && true; -const logical_or = false || true; -const logical_not = !false; -const eq = 2 == 3; -const not_eq = 2 != 3; -const gt = 4 > 3; -const lt = 4 < 3; -const gte = 4 >= 3; -const lte = 4 <= 3; -const ternary = a => (a == 1) ? true : false; -const ternary_nested = a => - a == 1 ? "one" : - a == 2 ? "two" : - a == 3 ? "three" : - "other" \ No newline at end of file diff --git a/gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.mligo b/gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.mligo deleted file mode 100644 index cfa7fc8b66..0000000000 --- a/gitlab-pages/docs/language-basics/src/boolean-if-else/ungrouped.mligo +++ /dev/null @@ -1,9 +0,0 @@ -let logical_and: bool = true && true -let logical_or: bool = false || true -let logical_not: bool = not false -let eq: bool = 2 = 3 -let not_eq: bool = 2 <> 3 -let gt: bool = 4 > 3 -let lt: bool = 4 < 3 -let gte: bool = 4 >= 3 -let lte: bool = 4 <= 3 \ No newline at end of file diff --git a/gitlab-pages/docs/syntax/comparisons.md b/gitlab-pages/docs/syntax/comparisons.md new file mode 100644 index 0000000000..55cba51dad --- /dev/null +++ b/gitlab-pages/docs/syntax/comparisons.md @@ -0,0 +1,307 @@ +--- +id: comparisons +title: Comparisons +--- + +import Syntax from '@theme/Syntax'; + +In LIGO, you can compare only variables of the same type. + +Moreover, you can compare only *comparable types*. +Comparable types (a concept lifted from Michelson) include: + +- `int` +- `nat` +- `bytes` +- `string` +- `tez` +- `timestamp` +- `address` +- `ticket` +- `tuple` +- `variant` + +Types that are not comparable include: + +- `list` +- `set` +- `big-set` +- `map` +- `big-map` + +Trying to compare two non-comparable types in a smart contract causes the compiler to throw an error that the types are not comparable. +If you need to compare these types, you can implement comparison logic in your own comparison functions. + + + +:::note + +You can use functions such as `Test.Compare.eq` to compare some non-comparable types in tests, but these functions are not available in smart contracts. +For more information, see the predefined [module Test.Compare](../reference/test.compare-reference/?lang=cameligo). + +::: + + + + + +:::note + +You can use functions such as `Test.Compare.eq` to compare some non-comparable types in tests, but these functions are not available in smart contracts. +For more information, see the predefined [namespace Test.Compare](../reference/test.compare-reference/?lang=jsligo). + +::: + + + +### Comparing strings + + + +```cameligo group=strings +let a : string = "Alice" +let b : string = "Alice" +let c : bool = (a = b) (* true *) +``` + + + + + +```jsligo group=strings +const a = "Alice"; +const b = "Alice"; +const c = (a == b); // true +``` + + + + +### Comparing numbers + + + +```cameligo group=numbers +let a : int = 5 +let b : int = 4 +let c : bool = (a = b) +let d : bool = (a > b) +let e : bool = (a < b) +let f : bool = (a <= b) +let g : bool = (a >= b) +let h : bool = (a <> b) +``` + + + + +```jsligo group=numbers +const a : int = 5; +const b : int = 4; +const c : bool = (a == b); +const d : bool = (a > b); +const e : bool = (a < b); +const f : bool = (a <= b); +const g : bool = (a >= b); +const h : bool = (a != b); +``` + + + +### Comparing bytes + + + +Usage: + +```cameligo group=bytes +let a : bytes = 0x1001 +let b : bytes = 0x1000 +let c : bool = (a = b) +let d : bool = (a > b) +let e : bool = (a < b) +let f : bool = (a <= b) +let g : bool = (a >= b) +let h : bool = (a <> b) +``` + + + + + +Usage: + +```jsligo group=bytes +const a : bytes = 0x1001; +const b : bytes = 0x1000; +const c : bool = (a == b); +const d : bool = (a > b); +const e : bool = (a < b); +const f : bool = (a <= b); +const g : bool = (a >= b); +const h : bool = (a != b); +``` + + + +### Comparing tez + +Comparing `tez` values is especially useful when dealing with an amount sent in a transaction, which you can get with the `Tezos.get_amount` function. + + + +```cameligo grouptez +let a : tez = 5mutez +let b : tez = 10mutez +let c : bool = (a = b) // false +``` + + + + + +```jsligo grouptez +const a: tez = 5 as mutez; +const b: tez = 10 as mutez; +const c: bool = (a == b); // false +``` + + + +### Comparing tuples + +To compare tuples, LIGO compares the values in order from left to right. + +Therefore, the tuple `[1, 2, 3]` is equal to the tuple `[1, 2, 3]` but not equal to a tuple with the same values in a different order: + + + +```cameligo group=tuples_equal +let a = [1, 2, 3] +let b = [1, 2, 3] +let c = (a = b) // true +let d = [3, 2, 1] +let e = (a = d) // false +``` + + + + + +```jsligo group=tuples_equal +const a = [1, 2, 3]; +const b = [1, 2, 3]; +const c = (a == b); // true +const d = [3, 2, 1]; +const e = (a == d); // false +``` + + + +To determine whether a tuple is greater than or lesser than another tuple, LIGO compares values in the tuples from left to right until the values are different. +Then it compares the two different values and returns the result, as in this example: + + + +```cameligo group=tuples_greater +let a = [1, 3, 2] +let b = [1, 2, 10] +let c = (a > b) // true because 3 > 2 +``` + + + + + +```jsligo group=tuples_greater +const a = [1, 3, 2]; +const b = [1, 2, 10]; +const c = (a > b); // true because 3 > 2 +``` + + + +### Comparing variants and options + +You can compare variants and options of the same type. +To be equal, the values must have the same case and data, as in these examples: + + + +```cameligo group=variants +type user = + Admin of nat +| Manager of nat +| VP of string +| Guest + +let alice : user = Admin 1 +let bob : user = Manager 1 +let carl : user = Guest +let diana : user = VP "Accounts" +let alice_2 : user = Admin 1 + +let a = (alice = bob) // false +let b = (alice = carl) // false +let c = (alice = carl) // false +let d = (alice = diana) // false +let e = (alice = alice_2) // true +``` + + + + + +```jsligo group=variants +type user = + ["Admin", nat] +| ["Manager", nat] +| ["VP", string] +| ["Guest"]; + +const alice: user = ["Admin" as "Admin", 1 as nat]; +const bob: user = ["Manager" as "Manager", 1 as nat]; +const carl: user = ["Guest" as "Guest"]; +const diana: user = ["VP" as "VP", "Accounts"]; +const alice_2: user = ["Admin" as "Admin", 1 as nat]; + +const a = (alice == bob); // false +const b = (alice == carl); // false +const c = (alice == carl); // false +const d = (alice == diana); // false +const e = (alice == alice_2); // true +``` + + + +You can compare variants of the same case to see if their data is greater than or less than each other: + + + +```cameligo group=variants +let edwin : user = Admin 9 +let francis : user = Admin 12 +let grady : user = Admin 1 +let h = (edwin < francis) // true +let i = (edwin < grady) // false +``` + + + + + +```jsligo group=variants +const edwin: user = ["Admin" as "Admin", 9 as nat]; +const francis: user = ["Admin" as "Admin", 12 as nat]; +const grady: user = ["Admin" as "Admin", 1 as nat]; +const h = (edwin < francis); // true +const i = (edwin < grady); // false +``` + + + +:::note + +You can compare variants of different cases with the greater than and less than operators but the result is not meaningful, even if the data is of the same type. + +::: diff --git a/gitlab-pages/website/sidebars.js b/gitlab-pages/website/sidebars.js index 6b3244ec57..1ca45cd6bb 100644 --- a/gitlab-pages/website/sidebars.js +++ b/gitlab-pages/website/sidebars.js @@ -21,11 +21,13 @@ const sidebars = { "Syntax": [ "syntax/comments", "syntax/variables", + "syntax/comparisons", "syntax/functions", { "type": "category", "label": "Flow control", "items": [ + "imperative/conditionals", "imperative/looping", "imperative/asserting", "imperative/switches",