From 8f153c52c2357b479bb54a62e82274a37a3c5361 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Mon, 8 Jan 2024 10:35:30 -0500 Subject: [PATCH 1/4] Update generics docs --- docs/docs/noir/concepts/generics.md | 50 ++++++++++++----------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/docs/docs/noir/concepts/generics.md b/docs/docs/noir/concepts/generics.md index 443ca2b45a..3d35ab9d61 100644 --- a/docs/docs/noir/concepts/generics.md +++ b/docs/docs/noir/concepts/generics.md @@ -30,15 +30,6 @@ struct RepeatedValue { } impl RepeatedValue { - fn new(value: T) -> Self { - Self { value, count: 1 } - } - - fn increment(mut repeated: Self) -> Self { - repeated.count += 1; - repeated - } - fn print(self) { for _i in 0 .. self.count { dep::std::println(self.value); @@ -47,8 +38,7 @@ impl RepeatedValue { } fn main() { - let mut repeated = RepeatedValue::new("Hello!"); - repeated = repeated.increment(); + let repeated = RepeatedValue { value: "Hello!", count: 2 }; repeated.print(); } ``` @@ -80,35 +70,37 @@ impl BigInt { ## Calling functions on generic parameters -Unlike Rust, Noir does not have traits, so how can one translate the equivalent of a trait bound in -Rust into Noir? That is, how can we write a function that is generic over some type `T`, while also -requiring there is a function like `eq: fn(T, T) -> bool` that works on the type? +Since a generic type `T` can represent any type, how can we call functions on the underlying type? +In other words, how can we go from "any type `T`" to "any type `T` that has certain methods available?" -The answer is that we can translate this by passing in the function manually. Here's an example of -implementing array equality in Noir: +This is what [traits](docs/traits) are for in Noir. Here's an example of a function generic over +any type `T` that implements the `Eq` trait for equality: ```rust -fn array_eq(array1: [T; N], array2: [T; N], elem_eq: fn(T, T) -> bool) -> bool { - if array1.len() != array2.len() { - false +fn first_element_is_equal(array1: [T; N], array2: [T; N]) -> bool + where T: Eq +{ + if (array1.len() == 0) | (array2.len() == 0) { + true } else { - let mut result = true; - for i in 0 .. array1.len() { - result &= elem_eq(array1[i], array2[i]); - } - result + array1[0] == array2[0] } } fn main() { - assert(array_eq([1, 2, 3], [1, 2, 3], |a, b| a == b)); + assert(first_element_is_equal([1, 2, 3], [1, 5, 6])); - // We can use array_eq even for arrays of structs, as long as we have - // an equality function for these structs we can pass in + // We can use first_element_is_equal even for arrays of any type + // as long as we have an Eq impl for the types we pass in let array = [MyStruct::new(), MyStruct::new()]; assert(array_eq(array, array, MyStruct::eq)); } + +impl Eq for MyStruct { + fn eq(self, other: MyStruct) -> bool { + self.foo == other.foo + } +} ``` -You can see an example of generics in the tests -[here](https://github.com/noir-lang/noir/blob/master/tooling/nargo_cli/tests/execution_success/generics/src/main.nr). +You can find more details on traits and trait implementations on the [traits page](docs/traits). From 703262a87f911d0163b6ea769acb8c6a4038ec9a Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Mon, 8 Jan 2024 10:47:47 -0500 Subject: [PATCH 2/4] Try relative addresses --- docs/docs/noir/concepts/generics.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/noir/concepts/generics.md b/docs/docs/noir/concepts/generics.md index 3d35ab9d61..b6192215b5 100644 --- a/docs/docs/noir/concepts/generics.md +++ b/docs/docs/noir/concepts/generics.md @@ -73,7 +73,7 @@ impl BigInt { Since a generic type `T` can represent any type, how can we call functions on the underlying type? In other words, how can we go from "any type `T`" to "any type `T` that has certain methods available?" -This is what [traits](docs/traits) are for in Noir. Here's an example of a function generic over +This is what [traits](../traits) are for in Noir. Here's an example of a function generic over any type `T` that implements the `Eq` trait for equality: ```rust @@ -103,4 +103,4 @@ impl Eq for MyStruct { } ``` -You can find more details on traits and trait implementations on the [traits page](docs/traits). +You can find more details on traits and trait implementations on the [traits page](../traits). From 4e6d6016bbf44c0a80e3a34102aad879e6dc0e47 Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Mon, 8 Jan 2024 11:13:38 -0500 Subject: [PATCH 3/4] Try to fix link --- docs/docs/noir/concepts/generics.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/docs/noir/concepts/generics.md b/docs/docs/noir/concepts/generics.md index b6192215b5..b04cd1c4d7 100644 --- a/docs/docs/noir/concepts/generics.md +++ b/docs/docs/noir/concepts/generics.md @@ -73,7 +73,7 @@ impl BigInt { Since a generic type `T` can represent any type, how can we call functions on the underlying type? In other words, how can we go from "any type `T`" to "any type `T` that has certain methods available?" -This is what [traits](../traits) are for in Noir. Here's an example of a function generic over +This is what [traits](../concepts/traits) are for in Noir. Here's an example of a function generic over any type `T` that implements the `Eq` trait for equality: ```rust @@ -103,4 +103,4 @@ impl Eq for MyStruct { } ``` -You can find more details on traits and trait implementations on the [traits page](../traits). +You can find more details on traits and trait implementations on the [traits page](../concepts/traits). From 0325316834f9e21612f5f938d53affe5a931d392 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:01:58 +0000 Subject: [PATCH 4/4] Update docs/docs/noir/concepts/generics.md --- docs/docs/noir/concepts/generics.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/noir/concepts/generics.md b/docs/docs/noir/concepts/generics.md index b04cd1c4d7..50c7e9995a 100644 --- a/docs/docs/noir/concepts/generics.md +++ b/docs/docs/noir/concepts/generics.md @@ -90,7 +90,7 @@ fn first_element_is_equal(array1: [T; N], array2: [T; N]) -> bool fn main() { assert(first_element_is_equal([1, 2, 3], [1, 5, 6])); - // We can use first_element_is_equal even for arrays of any type + // We can use first_element_is_equal for arrays of any type // as long as we have an Eq impl for the types we pass in let array = [MyStruct::new(), MyStruct::new()]; assert(array_eq(array, array, MyStruct::eq));