From 59680216ec401b802741a799b872936909104ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro=20Sousa?= Date: Tue, 24 Oct 2023 11:17:04 +0100 Subject: [PATCH 1/3] docs: method specialization --- docs/docs/language_concepts/01_functions.md | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/docs/language_concepts/01_functions.md b/docs/docs/language_concepts/01_functions.md index 2168c9203b6..cff9c58cc74 100644 --- a/docs/docs/language_concepts/01_functions.md +++ b/docs/docs/language_concepts/01_functions.md @@ -132,6 +132,26 @@ follows: assert(MyStruct::sum(s) == 42); ``` +When operating on [generics](./06_generics.md), method specialization is possible. In this example, the `foo` function returns different values depending on its type: + +```rust +struct Foo {} + +impl Foo { + fn foo(self) -> Field { 1 } +} + +impl Foo { + fn foo(self) -> Field { 2 } +} + +fn main() { + let f1: Foo = Foo{}; + let f2: Foo = Foo{}; + assert(f1.foo() + f2.foo() == 3); +} +``` + ## Lambdas Lambdas are anonymous functions. They follow the syntax of Rust - `|arg1, arg2, ..., argN| return_expression`. @@ -148,6 +168,7 @@ See [Lambdas](./08_lambdas.md) for more details. Attributes are metadata that can be applied to a function, using the following syntax: `#[attribute(value)]`. Supported attributes include: + - **builtin**: the function is implemented by the compiler, for efficiency purposes. - **deprecated**: mark the function as *deprecated*. Calling the function will generate a warning: `warning: use of deprecated function` - **field**: Used to enable conditional compilation of code depending on the field size. See below for more details @@ -155,12 +176,13 @@ Supported attributes include: - **test**: mark the function as unit tests. See [Tests](../nargo/02_testing.md) for more details ### Field Attribute + The field attribute defines which field the function is compatible for. The function is conditionally compiled, under the condition that the field attribute matches the Noir native field. The field can be defined implicitly, by using the name of the elliptic curve usually associated to it - for instance bn254, bls12_381 - or explicitly by using the field (prime) order, in decimal or hexadecimal form. As a result, it is possible to define multiple versions of a function with each version specialized for a different field attribute. This can be useful when a function requires different parameters depending on the underlying elliptic curve. - Example: we define the function `foo()` three times below. Once for the default Noir bn254 curve, once for the field $\mathbb F_{23}$, which will normally never be used by Noir, and once again for the bls12_381 curve. + ```rust #[field(bn254)] fn foo() -> u32 { @@ -184,4 +206,4 @@ fn foo() -> u32 { } ``` -If the field name is not known to Noir, it will discard the function. Field names are case insensitive. \ No newline at end of file +If the field name is not known to Noir, it will discard the function. Field names are case insensitive. From 06ccf559b987aaf5d4d1efbaae11b9cb50cd8b08 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 24 Oct 2023 10:21:30 -0500 Subject: [PATCH 2/3] Update docs/docs/language_concepts/01_functions.md --- docs/docs/language_concepts/01_functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/language_concepts/01_functions.md b/docs/docs/language_concepts/01_functions.md index cff9c58cc74..b47cdc4a1ee 100644 --- a/docs/docs/language_concepts/01_functions.md +++ b/docs/docs/language_concepts/01_functions.md @@ -132,7 +132,7 @@ follows: assert(MyStruct::sum(s) == 42); ``` -When operating on [generics](./06_generics.md), method specialization is possible. In this example, the `foo` function returns different values depending on its type: +It is also possible to specialize which method is chosen depending on the [generic](./06_generics.md) type that is used. In this example, the `foo` function returns different values depending on its type: ```rust struct Foo {} From 451f4c675c417b5d4e267ff343312d66b70e6514 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 24 Oct 2023 10:21:36 -0500 Subject: [PATCH 3/3] Update docs/docs/language_concepts/01_functions.md --- docs/docs/language_concepts/01_functions.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/docs/language_concepts/01_functions.md b/docs/docs/language_concepts/01_functions.md index b47cdc4a1ee..a369d4a3cab 100644 --- a/docs/docs/language_concepts/01_functions.md +++ b/docs/docs/language_concepts/01_functions.md @@ -152,6 +152,14 @@ fn main() { } ``` +Also note that impls with the same method name defined in them cannot overlap. For example, if we already have `foo` defined for `Foo` and `Foo` like we do above, we cannot also define `foo` in an `impl Foo` since it would be ambiguous which version of `foo` to choose. + +```rs +// Including this impl in the same project as the above snippet would +// cause an overlapping impls error +impl Foo { + fn foo(self) -> Field { 3 } +} ## Lambdas Lambdas are anonymous functions. They follow the syntax of Rust - `|arg1, arg2, ..., argN| return_expression`.