From 29d8f9845ecefe87377d3174379fbb406a7ad3e4 Mon Sep 17 00:00:00 2001 From: josh11b Date: Mon, 26 Sep 2022 16:57:03 -0700 Subject: [PATCH] Clarifications to "checked and template parameters" (#2216) This attempts to address concerns that @brevzin first tried to fix in #1443 . Co-authored-by: Barry Revzin --- docs/design/README.md | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index a7014b6a732f..b7196346d5ee 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -2558,16 +2558,20 @@ being passed as a separate explicit argument. ### Checked and template parameters -The `:!` indicates that `T` is a _checked_ parameter passed at compile time. +The `:!` indicates that the `T` parameter is generic, and therefore bound at +compile time. Generic parameters may either be _checked_ or _template_, and +default to checked. + "Checked" here means that the body of `Min` is type checked when the function is defined, independent of the specific type values `T` is instantiated with, and name lookup is delegated to the constraint on `T` (`Ordered` in this case). This type checking is equivalent to saying the function would pass type checking -given any type `T` that implements the `Ordered` interface. Then calls to `Min` -only need to check that the deduced type value of `T` implements `Ordered`. +given any type `T` that implements the `Ordered` interface. Subsequent calls to +`Min` only need to check that the deduced type value of `T` implements +`Ordered`. -The parameter could alternatively be declared to be a _template_ parameter by -prefixing with the `template` keyword, as in `template T:! Type`. +The parameter could alternatively be declared to be a _template_ generic +parameter by prefixing with the `template` keyword, as in `template T:! Type`. ```carbon fn Convert[template T:! Type](source: T, template U:! Type) -> U { @@ -2582,6 +2586,15 @@ fn Foo(i: i32) -> f32 { } ``` +A template parameter can still use a constraint. The `Min` example could have +been declared as: + +```carbon +fn Min[template T:! Ordered](x: T, y: T) -> T { + return if x <= y then x else y; +} +``` + Carbon templates follow the same fundamental paradigm as [C++ templates](): they are instantiated when called, resulting in late type checking, duck typing, and lazy