diff --git a/gitlab-pages/docs/language-basics/functions.md b/gitlab-pages/docs/language-basics/functions.md index eadc1c31e..54f0d82fd 100644 --- a/gitlab-pages/docs/language-basics/functions.md +++ b/gitlab-pages/docs/language-basics/functions.md @@ -299,3 +299,43 @@ gitlab-pages/docs/language-basics/src/functions/incr_map.religo incr_map +## Recursive function + +LIGO function are not recursive by default, the user need to indicate that the function is recursive. + +At the moment, recursive function are limited to one (possibly tupled) parameter and recursion is +limited to tail recursion (i.e the recursive call should be the last expression of the function) + + +In PascaLigo recursive funciton are defined using the "recursive" keyword + +```pascaligo group=d +recursive function sum (const n : int; const acc: int) : int is + if n<1 then acc else sum(n-1,acc+n) + +recursive function fibo (const n: int; const n_1: int; const n_0 :int) : int is + if n<2 then n_1 else fibo(n-1,n_1+n_0,n_1) +``` + + +In CameLigo recursive funciton are defined using the "rec" keyword + +```cameligo group=d +let rec sum ((n,acc):int * int) : int = + if (n < 1) then acc else sum (n-1, acc+n) + +let rec fibo ((n,n_1,n_0):int*int*int) : int = + if (n < 2) then n_1 else fibo (n-1, n_1 + n_0, n_1) +``` + + +In ReasonLigo recursive funciton are defined using the "rec" keyword + +```reasonligo group=d +let rec sum = ((n, acc) : (int,int)): int => + if (n < 1) {acc;} else {sum ((n-1,acc+n));}; + +let rec fibo = ((n, n_1, n_0) : (int,int,int)): int => + if (n < 2) {n_1;} else {fibo ((n-1,n_1+n_0,n_1));}; +``` + diff --git a/src/test/contracts/recursion.ligo b/src/test/contracts/recursion.ligo index 894993eac..3c8bcd7cb 100644 --- a/src/test/contracts/recursion.ligo +++ b/src/test/contracts/recursion.ligo @@ -1,4 +1,7 @@ // Test while loops in PascaLIGO -recursive function fibo (const n : int; const acc: int) : int is - if n<1 then acc else fibo(n-1,acc+n) +recursive function sum (const n : int; const acc: int) : int is + if n<1 then acc else sum(n-1,acc+n) + +recursive function fibo (const n: int; const n_1: int; const n_0 :int) : int is + if n<2 then n_1 else fibo(n-1,n_1+n_0,n_1) diff --git a/src/test/contracts/recursion.mligo b/src/test/contracts/recursion.mligo index 13e86518b..79549b5ee 100644 --- a/src/test/contracts/recursion.mligo +++ b/src/test/contracts/recursion.mligo @@ -1,5 +1,7 @@ // Test while loops in PascaLIGO -let rec fibo ((n,acc):int * int) : int = - if (n < 1) then acc - else fibo (n-1, acc+n) +let rec sum ((n,acc):int * int) : int = + if (n < 1) then acc else sum (n-1, acc+n) + +let rec fibo ((n,n_1,n_0):int*int*int) : int = + if (n < 2) then n_1 else fibo (n-1, n_1 + n_0, n_1) diff --git a/src/test/contracts/recursion.religo b/src/test/contracts/recursion.religo index 71f016962..7a9d5063a 100644 --- a/src/test/contracts/recursion.religo +++ b/src/test/contracts/recursion.religo @@ -1,5 +1,7 @@ // Test while loops in PascaLIGO -let rec fibo = ((n, acc) : (int,int)): int => - if (n < 1) {acc;} - else {fibo ((n-1,acc+n));}; +let rec sum = ((n, acc) : (int,int)): int => + if (n < 1) {acc;} else {sum ((n-1,acc+n));}; + +let rec fibo = ((n, n_1, n_0) : (int,int,int)): int => + if (n < 2) {n_1;} else {fibo ((n-1,n_1+n_0,n_1));}; diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 60b8f57bb..9c17f2479 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -1495,24 +1495,43 @@ let assert_religo () : unit result = let recursion_ligo () : unit result = let%bind program = type_file "./contracts/recursion.ligo" in - let make_input = e_pair (e_int 10) (e_int 0) in - let make_expected = e_int 55 in - let%bind _ = expect_eq program "fibo" make_input make_expected in - ok () + let%bind _ = + let make_input = e_pair (e_int 10) (e_int 0) in + let make_expected = e_int 55 in + expect_eq program "sum" make_input make_expected + in + let%bind _ = + let make_input = e_tuple [(e_int 10); (e_int 1); (e_int 1)] in + let make_expected = e_int 89 in + expect_eq program "fibo" make_input make_expected + in ok () + let recursion_mligo () : unit result = let%bind program = mtype_file "./contracts/recursion.mligo" in - let make_input = e_pair (e_int 10) (e_int 0) in - let make_expected = e_int 55 in - let%bind _ = expect_eq program "fibo" make_input make_expected in - ok () + let%bind _ = + let make_input = e_pair (e_int 10) (e_int 0) in + let make_expected = e_int 55 in + expect_eq program "sum" make_input make_expected + in + let%bind _ = + let make_input = e_tuple [(e_int 10); (e_int 1); (e_int 1)] in + let make_expected = e_int 89 in + expect_eq program "fibo" make_input make_expected + in ok () let recursion_religo () : unit result = let%bind program = retype_file "./contracts/recursion.religo" in - let make_input = e_pair (e_int 10) (e_int 0) in - let make_expected = e_int 55 in - let%bind _ = expect_eq program "fibo" make_input make_expected in - ok () + let%bind _ = + let make_input = e_pair (e_int 10) (e_int 0) in + let make_expected = e_int 55 in + expect_eq program "sum" make_input make_expected + in + let%bind _ = + let make_input = e_tuple [(e_int 10); (e_int 1); (e_int 1)] in + let make_expected = e_int 89 in + expect_eq program "fibo" make_input make_expected + in ok () let guess_string_mligo () : unit result = let%bind program = type_file "./contracts/guess_string.mligo" in