From f63ddfcfde7cd691f40151376051a50ba5c71072 Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 6 May 2022 22:06:10 +0000 Subject: [PATCH 01/46] Begin big reorganization and update of design overview --- docs/design/README.md | 1235 +++++++++++------ .../lexical_conventions/numeric_literals.md | 24 +- 2 files changed, 791 insertions(+), 468 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index cb3dfccc2f35b..d272501d6e20c 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -11,21 +11,32 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ## Table of contents - [Overview](#overview) -- [Context and disclaimer](#context-and-disclaimer) - - [Example code](#example-code) -- [Basic syntax](#basic-syntax) - - [Code and comments](#code-and-comments) - - [Packages, libraries, and namespaces](#packages-libraries-and-namespaces) - - [Names and scopes](#names-and-scopes) - - [Naming conventions](#naming-conventions) - - [Aliases](#aliases) - - [Name lookup](#name-lookup) - - [Name lookup for common types](#name-lookup-for-common-types) - - [Expressions](#expressions) - - [Functions](#functions) + - [A note on example code](#a-note-on-example-code) +- [Hello, Carbon](#hello-carbon) +- [Code and comments](#code-and-comments) +- [Types](#types) +- [Primitive types](#primitive-types) + - [`bool`](#bool) + - [Integer types](#integer-types) + - [Integer literals](#integer-literals) + - [Floating-point types](#floating-point-types) + - [Floating-point literals](#floating-point-literals) + - [String type](#string-type) + - [String literals](#string-literals) +- [Composite types](#composite-types) + - [Tuples](#tuples) + - [Struct types](#struct-types) + - [Struct literals](#struct-literals) + - [Pointer types](#pointer-types) + - [Arrays and slices](#arrays-and-slices) +- [Functions](#functions) - [Blocks and statements](#blocks-and-statements) + - [Expressions](#expressions) - [Variables](#variables) - - [Lifetime and move semantics](#lifetime-and-move-semantics) + - [`let`](#let) + - [`auto`](#auto) + - [Pattern matching](#pattern-matching) + - [Pattern matching in local variables](#pattern-matching-in-local-variables) - [Control flow](#control-flow) - [`if` and `else`](#if-and-else) - [Loops](#loops) @@ -34,248 +45,329 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [`break`](#break) - [`continue`](#continue) - [`return`](#return) -- [Types](#types) - - [Primitive types](#primitive-types) - - [Composite types](#composite-types) - - [Tuples](#tuples) - - [Variants](#variants) - - [Pointers and references](#pointers-and-references) - - [Arrays and slices](#arrays-and-slices) - - [User-defined types](#user-defined-types) - - [Classes](#classes) - - [Assignment, copying](#assignment-copying) - - [Member access](#member-access) - - [Methods](#methods) - - [Allocation, construction, and destruction](#allocation-construction-and-destruction) - - [Moving](#moving) - - [Comparison](#comparison) - - [Implicit and explicit conversion](#implicit-and-explicit-conversion) - - [Inline type composition](#inline-type-composition) - - [Unions](#unions) -- [Pattern matching](#pattern-matching) - - [`match` control flow](#match-control-flow) - - [Pattern matching in local variables](#pattern-matching-in-local-variables) - - [Pattern matching as function overload resolution](#pattern-matching-as-function-overload-resolution) -- [Type abstractions](#type-abstractions) - - [Interfaces](#interfaces) - - [Generics](#generics) - - [Templates](#templates) - - [Types with template parameters](#types-with-template-parameters) + - [`returned var`](#returned-var) + - [`match` control flow](#match-control-flow) +- [User-defined types](#user-defined-types) + - [Classes](#classes) + - [Assignment, copying](#assignment-copying) + - [Member access](#member-access) + - [Methods](#methods) + - [Inheritance](#inheritance) + - [Access control](#access-control) + - [Destructors](#destructors) + - [Variants](#variants) +- [Names](#names) + - [Packages, libraries, namespaces](#packages-libraries-namespaces) + - [Names and scopes](#names-and-scopes) + - [Naming conventions](#naming-conventions) + - [Aliases](#aliases) + - [Name lookup](#name-lookup) + - [Name lookup for common types](#name-lookup-for-common-types) +- [Generics](#generics) + - [Interfaces and implementations](#interfaces-and-implementations) + - [Checked and template parameters](#checked-and-template-parameters) + - [Templates](#templates) + - [Generic functions](#generic-functions) - [Functions with template parameters](#functions-with-template-parameters) - - [Overloading](#overloading) -- [Metaprogramming](#metaprogramming) -- [Execution abstractions](#execution-abstractions) - - [Abstract machine and execution model](#abstract-machine-and-execution-model) - - [Lambdas](#lambdas) - - [Co-routines](#co-routines) + - [Generic types](#generic-types) + - [Types with template parameters](#types-with-template-parameters) + - [Operator overloading](#operator-overloading) + - [Implicit and explicit conversion](#implicit-and-explicit-conversion) + - [Comparison operators](#comparison-operators) + - [Arithmetic operators](#arithmetic-operators) + - [Bitwise and shift operators](#bitwise-and-shift-operators) + - [Common type](#common-type) - [Bidirectional interoperability with C/C++](#bidirectional-interoperability-with-cc) +- [Unfinished tales](#unfinished-tales) + - [Pattern matching as function overload resolution](#pattern-matching-as-function-overload-resolution) + - [Lifetime and move semantics](#lifetime-and-move-semantics) + - [Metaprogramming](#metaprogramming) + - [Execution abstractions](#execution-abstractions) + - [Abstract machine and execution model](#abstract-machine-and-execution-model) + - [Lambdas](#lambdas) + - [Co-routines](#co-routines) ## Overview This documentation describes the design of the Carbon language, and the -rationale for that design. - -## Context and disclaimer - -Eventually, this document hopes to provide a high-level overview of the design -of the Carbon language. It should summarize the key points across the different -aspects of the language design and link to more detailed and comprehensive -design documents to expand on specific aspects of the design. That means it -isn't and doesn't intend to be complete or stand on its own. Notably, it doesn't -attempt to provide detailed and comprehensive justification for design -decisions. Those should instead be provided by the dedicated and focused designs -linked to from here. However, it should provide an overarching view of the -design and a good basis for diving into specific details. - -However, these are extremely early days for Carbon. Currently, this document -tries to capture two things: - -1. Initial musings about what _might_ make sense as a basis for Carbon. These - are largely informed by idle discussions between C++ and Clang developers - over the years, and should not be given any particular weight. -2. A summary and snapshot of in-progress efforts to flesh out and motivate - specific designs for parts of the language. - -The utility of capturing these at this early stage is primarily to give everyone -a reasonably consistent set of terminology and context as we begin fleshing out -concrete (and well justified) designs for each part of the language. In some -cases, it captures ideas that may be interesting to explore, but isn't meant to -overly anchor on them. Any ideas here need to be fully explored and justified -with a detailed analysis. The context of #1 (directly evolving C++, experience -building Clang, and experience working on C++ codebases including Clang and LLVM -themselves) is also important. It is both an important signal but also a bias. - -### Example code +rationale for that design. This documentation is an overview of the Carbon +project in its current state, written for the builders of Carbon and for those +interested in learning more about Carbon. + +This document is _not_ a complete programming manual, and, nor does it provide +detailed and comprehensive justification for design decisions. These +descriptions are found in linked dedicated designs. + +### A note on example code Some syntax used in example code is provisional or placeholder, and may change later. -## Basic syntax +## Hello, Carbon -### Code and comments +Here is a simple function showing some Carbon code: -> References: [Source files](code_and_name_organization/source_files.md) and -> [lexical conventions](lexical_conventions) -> -> **TODO:** References need to be evolved. +```carbon +import Console; + +// Prints the Fibonacci numbers less than `limit`. +fn Fibonacci(limit: i64) { + var (a, b): (i64, i64) = (0, 1); + while (a < limit) { + Console.Print(a, " "); + (a, b) = (b, a + b); + } + Console.Print("\n"); +} +``` -- All source code is UTF-8 encoded text. For simplicity, no other encoding is - supported. -- Line comments look like `// ...`. However, they are required to be the only - non-whitespace on the line for readability. -- Block comments look like `//\{ ... //\}`, with each marker on its own line. - Nested block comments are supported using named regions. For example: - - ```carbon - live code - //\{ - commented code - //\{ nested block - commented code in nested block - //\} nested block - //\} - live code - ``` - -- Decimal, hexadecimal, and binary integer literals and decimal and - hexadecimal floating-point literals are supported, with `_` as a digit - separator. For example, `42`, `0b1011_1101` and `0x1.EEFp+5`. Numeric - literals are case-sensitive: `0x`, `0b`, `e+`, and `p+` must be lowercase, - whereas hexadecimal digits must be uppercase. A digit is required on both - sides of a period. - -### Packages, libraries, and namespaces - -> References: [Code and name organization](code_and_name_organization) +Carbon is a language that should feel familiar to C++ and C developers. This +example has familiar constructs like imports, function definitions, typed +arguments, and curly braces. -- **Files** are grouped into libraries, which are in turn grouped into - packages. -- **Libraries** are the granularity of code reuse through imports. -- **Packages** are the unit of distribution. +A few other features that are unlike C or C++ may stand out. First, declarations +start with introducer keywords. `fn` introduces a function declaration, and +`var` introduces a variable declaration. You can also see a _tuple_, a composite +type written as a comma-separated list inside parentheses. Unlike, say, Python, +these types are strongly-typed as well. -Name paths in Carbon always start with the package name. Additional namespaces -may be specified as desired. +## Code and comments -For example, this code declares a class `Geometry.Shapes.Flat.Circle` in a -library `Geometry/OneSide`: +> References: +> +> - [Source files](code_and_name_organization/source_files.md) +> - [lexical conventions](lexical_conventions) +> - Proposal +> [#142: Unicode source files](https://github.com/carbon-language/carbon-lang/pull/142) +> - Proposal +> [#198: Comments](https://github.com/carbon-language/carbon-lang/pull/198) -```carbon -package Geometry library("OneSide") namespace Shapes; +All source code is UTF-8 encoded text. Comments, identifiers, and strings are +allowed to have non-ASCII characters. -namespace Flat; -class Flat.Circle { ... } +```carbon +var résultat: String = "Succès"; ``` -This type can be used from another package: +Comments start with two slashes `//` and go to the end of the line. They are +required to be the only non-whitespace on the line. ```carbon -package ExampleUser; +// Compute an approximation of π +``` -import Geometry library("OneSide"); +## Types -fn Foo(Geometry.Shapes.Flat.Circle circle) { ... } -``` +Carbon's core types are broken down into three categories: -### Names and scopes +- [Primitive types](#primitive-types) +- [Composite types](#composite-types) +- [User-defined types](#user-defined-types) -> References: [Lexical conventions](lexical_conventions) +The first two are intrinsic and directly built in the language. The last aspect +of types allows for defining new types. + +Expressions compute values in Carbon, and these values are always strongly typed +much like in C++. However, an important difference from C++ is that types are +themselves modeled as values; specifically, compile-time constant values. +However, in simple cases this doesn't make much difference. + +## Primitive types + +> References: [Primitive types](primitive_types.md) + +These types are fundamental to the language as they aren't either formed from or +modifying other types. They also have semantics that are defined from first +principles rather than in terms of other operations. These will be made +available through the [prelude package](#name-lookup-for-common-types). + +Primitive types fall into the following categories: + +- A boolean type `bool` +- Signed and unsigned integer types. +- IEEE-754 floating-point types. +- String types. + +### `bool` + +The type `bool` is a boolean type with two possible values: `true` and `false`. + +### Integer types + +> References: > -> **TODO:** References need to be evolved. +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) -Various constructs introduce a named entity in Carbon. These can be functions, -types, variables, or other kinds of entities that we'll cover. A name in Carbon -is formed from a word, which is a sequence of letters, numbers, and underscores, -and which starts with a letter. We intend to follow Unicode's Annex 31 in -selecting valid identifier characters, but a concrete set of valid characters -has not been selected yet. +> **TODO:** -#### Naming conventions +Signed integer types: `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, and +`Carbon.Int(N)`. Overflow in either direction is an error. -> References: [Naming conventions](naming_conventions.md) +Unsigned integer types: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, and +`Carbon.Unsigned(N)`. Overflow wraps. -Our naming conventions are: +#### Integer literals -- For idiomatic Carbon code: - - `UpperCamelCase` will be used when the named entity cannot have a - dynamically varying value. For example, functions, namespaces, or - compile-time constant values. - - `lower_snake_case` will be used when the named entity's value won't be - known until runtime, such as for variables. -- For Carbon-provided features: - - Keywords and type literals will use `lower_snake_case`. - - Other code will use the conventions for idiomatic Carbon code. +> References: +> +> - [Integer literals](lexical_conventions/numeric_literals.md#integer-literals) +> - Proposal +> [#143: Numeric literals](https://github.com/carbon-language/carbon-lang/pull/143) +> - Proposal +> [#144: Numeric literal semantics](https://github.com/carbon-language/carbon-lang/pull/144) +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) -#### Aliases +> **TODO:** -> References: [Aliases](aliases.md) +Decimal, hexadecimal, and binary integer literals and decimal and hexadecimal +floating-point literals are supported, with `_` as a digit separator. For +example, `42`, `0b1011_1101` and `0x1.EEFp+5`. Numeric literals are +case-sensitive: `0x`, `0b`, `e+`, and `p+` must be lowercase, whereas +hexadecimal digits must be uppercase. A digit is required on both sides of a +period. + +### Floating-point types + +> References: > -> **TODO:** References need to be evolved. +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) -Carbon provides a facility to declare a new name as an alias for a value. This -is a fully general facility because everything is a value in Carbon, including -types. +> **TODO:** -For example: +Floating point type with semantics based on IEEE-754: `f16`, `f32`, `f64`, and +`f128`. [`BFloat16`](primitive_types.md#bfloat16) is also provided. + +#### Floating-point literals + +> References: +> +> - [Real-number literals](lexical_conventions/numeric_literals.md#real-number-literals) +> - Proposal +> [#143: Numeric literals](https://github.com/carbon-language/carbon-lang/pull/143) +> - Proposal +> [#144: Numeric literal semantics](https://github.com/carbon-language/carbon-lang/pull/144) +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> - Proposal +> [#866: Allow ties in floating literals](https://github.com/carbon-language/carbon-lang/pull/866) + +> **TODO:** + +### String type + +> **TODO:** + +- `String` - a byte sequence treated as containing UTF-8 encoded text. +- `StringView` - a read-only reference to a byte sequence treated as + containing UTF-8 encoded text. + +#### String literals + +> References: +> +> - [String literals](lexical_conventions/string_literals.md) +> - Proposal +> [#199: String literals](https://github.com/carbon-language/carbon-lang/pull/199) + +> **TODO:** + +## Composite types + +### Tuples + +> References: [Tuples](tuples.md) + +> **TODO:** + +The primary composite type involves simple aggregation of other types as a +tuple. In formal type theory, tuples are product types. + +An example use of tuples is to return multiple values from a function: ```carbon -alias MyInt = Int; +fn DoubleBoth(x: i32, y: i32) -> (i32, i32) { + return (2 * x, 2 * y); +} ``` -This creates an alias called `MyInt` for whatever `Int` resolves to. Code -textually after this can refer to `MyInt`, and it will transparently refer to -`Int`. +Breaking this example apart: -#### Name lookup +- The return type is a tuple of two `i32` types. +- The expression uses tuple syntax to build a tuple of two `i32` values. -> References: [name lookup](name_lookup.md) -> -> **TODO:** References need to be evolved. +Both of these are expressions using the tuple syntax +`(, )`. The only difference is the type of the tuple +expression: one is a tuple of types, the other a tuple of values. -Unqualified name lookup will always find a file-local result, including aliases. +Element access uses subscript syntax: -##### Name lookup for common types +```carbon +fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { + return (2 * x[0], 2 * x[1]); +} +``` -> References: [Name lookup](name_lookup.md) -> -> **TODO:** References need to be evolved. +Tuples also support multiple indices and slicing to restructure tuple elements: -Common types that we expect to be used universally will be provided for every -file, including `Int` and `Bool`. These will likely be defined in a special -"prelude" package. +```carbon +// This reverses the tuple using multiple indices. +fn Reverse(x: (i32, i32, i32)) -> (i32, i32, i32) { + return x[2, 1, 0]; +} -### Expressions +// This slices the tuple by extracting elements [0, 2). +fn RemoveLast(x: (i32, i32, i32)) -> (i32, i32) { + return x[0 .. 2]; +} +``` + +### Struct types -> References: [Lexical conventions](lexical_conventions) and -> [expressions](expressions/) +> References: > -> **TODO:** References need to be evolved. +> - [Struct types](classes.md#struct-types) +> - Proposal +> [#561: Basic classes: use cases, struct literals, struct types, and future work](https://github.com/carbon-language/carbon-lang/pull/561) +> - Proposal +> [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) -Expressions describe some computed value. The simplest example would be a -literal number like `42`: an expression that computes the integer value 42. +> **TODO:** -Some common expressions in Carbon include: +_structural data class_, also known as a _struct type_ or _struct_ -- Literals: `42`, `3.1419`, `"Hello World!"` -- Operators: +#### Struct literals - - Increment and decrement: `++i`, `--j` - - These do not return any result. - - Unary negation: `-x` - - Arithmetic: `1 + 2`, `3 - 4`, `2 * 5`, `6 / 3` - - Bitwise: `2 & 3`, `2 | 4`, `3 ^ 1`, `~7` - - Bit shift: `1 << 3`, `8 >> 1` - - Comparison: `2 == 2`, `3 != 4`, `5 < 6`, `7 > 6`, `8 <= 8`, `8 >= 8` - - Logical: `a and b`, `c or d` +> References: [Struct literals](classes.md#literals) -- Parenthesized expressions: `(7 + 8) * (3 - 1)` +> **TODO:** + +_structural data class literal_, also known as a _struct literal_ + +### Pointer types + +> **TODO:** + +### Arrays and slices -### Functions +> **TODO:** -> References: [Functions](functions.md) +## Functions -Functions are the core unit of behavior. For example: +> References: +> +> - [Functions](functions.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438) + +Functions are the core unit of behavior. For example, this declares a function +that adds two 64-bit integers: ```carbon fn Add(a: i64, b: i64) -> i64; @@ -290,11 +382,16 @@ Breaking this apart: You would call this function like `Add(1, 2)`. +This just declares the function, a definition that includes the body that +defines what this function does would follow. + ### Blocks and statements -> References: [Blocks and statements](blocks_and_statements.md) +> References: > -> **TODO:** References need to be evolved. +> - [Blocks and statements](blocks_and_statements.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) The body or definition of a function is provided by a block of code containing statements. The body of a function is also a new, nested scope inside the @@ -315,9 +412,61 @@ fn Foo() { } ``` +### Expressions + +> References: +> +> - [Expressions](expressions/) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#555: Operator precedence](https://github.com/carbon-language/carbon-lang/pull/555) +> - Proposal +> [#601: Operator tokens](https://github.com/carbon-language/carbon-lang/pull/601) +> - Proposal +> [#680: And, or, not](https://github.com/carbon-language/carbon-lang/pull/680) +> - Proposal +> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) +> - Proposal +> [#845: as expressions](https://github.com/carbon-language/carbon-lang/pull/845) +> - Proposal +> [#911: Conditional expressions](https://github.com/carbon-language/carbon-lang/pull/911) +> - Proposal +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) + +Expressions describe some computed value. The simplest example would be a +literal number like `42`: an expression that computes the integer value 42. + +Some common expressions in Carbon include: + +- Literals: `42`, `3.1419`, `"Hello World!"` +- Operators: + + - Increment and decrement: `++i`, `--j` + - These do not return any result. + - Unary negation: `-x` + - Arithmetic: `1 + 2`, `3 - 4`, `2 * 5`, `6 / 3` + - Bitwise: `2 & 3`, `2 | 4`, `3 ^ 1`, `^7` + - Bit shift: `1 << 3`, `8 >> 1` + - Comparison: `2 == 2`, `3 != 4`, `5 < 6`, `7 > 6`, `8 <= 8`, `8 >= 8` + - Logical: `a and b`, `c or d`, `not e` + - Conditional: `if c then t else f` + +- Parenthesized expressions: `(7 + 8) * (3 - 1)` + ### Variables -> References: [Variables](variables.md) +> References: +> +> - [Variables](variables.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) +> - Proposal +> [#339: Add `var [ = ];` syntax for variables](https://github.com/carbon-language/carbon-lang/pull/339) +> - Proposal +> [#618: var ordering](https://github.com/carbon-language/carbon-lang/pull/618) Blocks introduce nested scopes and can contain local variable declarations that work similarly to function parameters. @@ -337,22 +486,82 @@ Breaking this apart: - Its type is `i64`. - It is initialized with the value `42`. -### Lifetime and move semantics +### `let` + +> **TODO:** + +### `auto` + +> References: +> +> - [Type inference](type_inference.md) +> - Proposal +> [#826: Function return type inference](https://github.com/carbon-language/carbon-lang/pull/826) +> - Proposal +> [#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851) + +> **TODO:** + +### Pattern matching + +> References: +> +> - [Pattern matching](pattern_matching.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> +> **TODO:** References need to be evolved. + +The most prominent mechanism to manipulate and work with types in Carbon is +pattern matching. This may seem like a deviation from C++, but in fact this is +largely about building a clear, coherent model for a fundamental part of C++: +overload resolution. -> References: TODO +#### Pattern matching in local variables + +> References: [Pattern matching](pattern_matching.md) > > **TODO:** References need to be evolved. +Value patterns may be used when declaring local variables to conveniently +destructure them and do other type manipulations. However, the patterns must +match at compile time, so a boolean predicate cannot be used directly. + +An example use is: + +```carbon +fn Bar() -> (i32, (f32, f32)); +fn Foo() -> i32 { + var (p: i32, _: auto) = Bar(); + return p; +} +``` + +To break this apart: + +- The `i32` returned by `Bar()` matches and is bound to `p`, then returned. +- The `(f32, f32)` returned by `Bar()` matches and is discarded by `_: auto`. + ### Control flow -> References: [Control flow](control_flow/README.md) +> References: +> +> - [Control flow](control_flow/README.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#623: Require braces](https://github.com/carbon-language/carbon-lang/pull/623) Blocks of statements are generally executed sequentially. However, statements are the primary place where this flow of execution can be controlled. #### `if` and `else` -> References: [Control flow](control_flow/conditionals.md) +> References: +> +> - [Control flow](control_flow/conditionals.md) +> - Proposal +> [#285: if/else](https://github.com/carbon-language/carbon-lang/pull/285) `if` and `else` provide conditional execution of statements. For example: @@ -375,15 +584,21 @@ This code will: #### Loops +> References: [Control flow](control_flow/loops.md) + ##### `while` -> References: [Control flow](control_flow/loops.md#while) +> References: +> +> - [Control flow](control_flow/loops.md#while) +> - Proposal +> [#340: Add C++-like `while` loops](https://github.com/carbon-language/carbon-lang/pull/340) `while` statements loop for as long as the passed expression returns `True`. For example, this prints `0`, `1`, `2`, then `Done!`: ```carbon -var x: Int = 0; +var x: i32 = 0; while (x < 3) { Print(x); ++x; @@ -393,7 +608,11 @@ Print("Done!"); ##### `for` -> References: [Control flow](control_flow/loops.md#for) +> References: +> +> - [Control flow](control_flow/loops.md#for) +> - Proposal +> [#353: Add C++-like `for` loops](https://github.com/carbon-language/carbon-lang/pull/353) `for` statements support range-based looping, typically over containers. For example, this prints all names in `names`: @@ -446,142 +665,113 @@ while (!f.EOF()) { #### `return` -> References: [Control flow](control_flow/return.md) +> References: +> +> - [Control flow](control_flow/return.md) +> - [`return` statements](functions.md#return-statements) +> - Proposal +> [#415: return](https://github.com/carbon-language/carbon-lang/pull/415) +> - Proposal +> [#538: return with no argument](https://github.com/carbon-language/carbon-lang/pull/538) The `return` statement ends the flow of execution within a function, returning execution to the caller. If the function returns a value to the caller, that value is provided by an expression in the return statement. For example: ```carbon -fn Sum(a: Int, b: Int) -> Int { +fn Sum(a: i32, b: i32) -> i32 { return a + b; } ``` -## Types +##### `returned var` -> References: [Primitive types](primitive_types.md), [tuples](tuples.md), and -> [classes](classes.md) +> References: > -> **TODO:** References need to be evolved. +> - [Control flow](control_flow/return.md#returned-var) +> - Proposal +> [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) -Carbon's core types are broken down into three categories: +> **TODO:** -- Primitive types -- Composite types -- User-defined types +#### `match` control flow -The first two are intrinsic and directly built in the language. The last aspect -of types allows for defining new types. +> References: [Pattern matching](pattern_matching.md) +> +> **TODO:** References need to be evolved. -Expressions compute values in Carbon, and these values are always strongly typed -much like in C++. However, an important difference from C++ is that types are -themselves modeled as values; specifically, compile-time constant values. -However, in simple cases this doesn't make much difference. - -### Primitive types - -> References: [Primitive types](primitive_types.md) -> -> **TODO:** References need to be evolved. - -These types are fundamental to the language as they aren't either formed from or -modifying other types. They also have semantics that are defined from first -principles rather than in terms of other operations. These will be made -available through the [prelude package](#name-lookup-for-common-types). - -Primitive types fall into the following categories: - -- `Bool` - a boolean type with two possible values: `True` and `False`. -- `Int` and `UInt` - signed and unsigned 64-bit integer types. - - Standard sizes are available, both signed and unsigned, including - `Int8`, `Int16`, `Int32`, `Int128`, and `Int256`. - - Overflow in either direction is an error. -- `Float64` - a floating point type with semantics based on IEEE-754. - - Standard sizes are available, including `Float16`, `Float32`, and - `Float128`. - - [`BFloat16`](primitive_types.md#bfloat16) is also provided. -- `String` - a byte sequence treated as containing UTF-8 encoded text. - - `StringView` - a read-only reference to a byte sequence treated as - containing UTF-8 encoded text. - -### Composite types - -#### Tuples - -> References: [Tuples](tuples.md) -> -> **TODO:** References need to be evolved. - -The primary composite type involves simple aggregation of other types as a -tuple. In formal type theory, tuples are product types. - -An example use of tuples is: - -```carbon -fn DoubleBoth(x: Int, y: Int) -> (Int, Int) { - return (2 * x, 2 * y); -} -``` - -Breaking this example apart: - -- The return type is a tuple of two `Int` types. -- The expression uses tuple syntax to build a tuple of two `Int` values. - -Both of these are expressions using the tuple syntax -`(, )`. The only difference is the type of the tuple -expression: one is a tuple of types, the other a tuple of values. - -Element access uses subscript syntax: - -```carbon -fn DoubleTuple(x: (Int, Int)) -> (Int, Int) { - return (2 * x[0], 2 * x[1]); -} -``` +`match` is a control flow similar to `switch` of C/C++ and mirrors similar +constructs in other languages, such as Swift. -Tuples also support multiple indices and slicing to restructure tuple elements: +An example `match` is: ```carbon -// This reverses the tuple using multiple indices. -fn Reverse(x: (Int, Int, Int)) -> (Int, Int, Int) { - return x[2, 1, 0]; -} +fn Bar() -> (i32, (f32, f32)); -// This slices the tuple by extracting elements [0, 2). -fn RemoveLast(x: (Int, Int, Int)) -> (Int, Int) { - return x[0 .. 2]; +fn Foo() -> f32 { + match (Bar()...) { + case (42, (x: f32, y: f32)) => { + return x - y; + } + case (p: i32, (x: f32, _: f32)) if (p < 13) => { + return p * x; + } + case (p: i32, _: auto) if (p > 3) => { + return p * Pi; + } + default => { + return Pi; + } + } } ``` -#### Variants - -> **TODO:** Needs a feature design and a high level summary provided inline. - -#### Pointers and references +Breaking apart this `match`: -> **TODO:** Needs a feature design and a high level summary provided inline. +- It accepts a value that will be inspected; in this case, the result of the + call to `Bar()`. + - It then will find the _first_ `case` that matches this value, and + execute that block. + - If none match, then it executes the default block. +- Each `case` pattern contains a value pattern, such as `(p: i32, _: auto)`, + followed by an optional boolean predicate introduced by the `if` keyword. + - The value pattern must first match, and then the predicate must also + evaluate to true for the overall `case` pattern to match. + - Using `auto` for a type will always match. -#### Arrays and slices +Value patterns may be composed of the following: -> **TODO:** Needs a feature design and a high level summary provided inline. +- An expression, such as `42`, whose value must be equal to match. +- An identifier to bind the value, followed by a `:` and followed by a type, + such as `i32`. + - The special identifier `_` may be used to discard the value once + matched. +- A destructuring pattern containing a sequence of value patterns, such as + `(x: f32, y: f32)`, which match against tuples and tuple-like values by + recursively matching on their elements. +- An unwrapping pattern containing a nested value pattern which matches + against a variant or variant-like value by unwrapping it. -### User-defined types +## User-defined types -#### Classes +### Classes -> References: [Classes](classes.md) +> References: +> +> - [Classes](classes.md#nominal-class-types) +> - Proposal +> [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722) -Classes are a way for users to define their own data strutures or record types. +_Nominal classes_, or just _classes_, are a way for users to define their own +data strutures or record types. For example: ```carbon class Widget { - var x: Int; - var y: Int; - var z: Int; + var x: i32; + var y: i32; + var z: i32; var payload: String; } @@ -589,14 +779,26 @@ class Widget { Breaking apart `Widget`: -- `Widget` has three `Int` members: `x`, `y`, and `z`. +- `Widget` has three `i32` members: `x`, `y`, and `z`. - `Widget` has one `String` member: `payload`. - Given an instance `dial`, a member can be referenced with `dial.paylod`. -##### Assignment, copying +The order of the member declarations determines the members' memory-layout +order. -You may use a _structural data class literal_, also known as a _struct literal_, -to assign or initialize a variable with a class type. +Both [structural data classes](#struct-types) and nominal classes are considered +class types, but they are commonly referred to as "structs" and "classes" +respectively when that is not confusing. + +#### Assignment, copying + +> References: [Classes](classes.md#construction) +> +> - Proposal +> [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) + +You may use a [struct literal](#struct-literals), to assign or initialize a +variable with a class type. ```carbon var sprocket: Widget = {.x = 3, .y = 4, .z = 5, .payload = "Sproing"}; @@ -610,7 +812,10 @@ var thingy: Widget = sprocket; sprocket = thingy; ``` -##### Member access +#### Member access + +> References: Proposal +> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) The data members of a variable with a class type may be accessed using dot `.` notation: @@ -619,7 +824,13 @@ notation: Assert(sprocket.x == thingy.x); ``` -##### Methods +#### Methods + +> References: +> +> - [Methods](classes.md#methods) +> - Proposal +> [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722) Class type definitions can include methods: @@ -663,143 +874,180 @@ two methods `Distance` and `Offset`: - Methods may be declared lexically inline like `Distance`, or lexically out of line like `Offset`. -##### Allocation, construction, and destruction +#### Inheritance -> **TODO:** Needs a feature design and a high level summary provided inline. +> References: +> +> - [Inheritance](classes.md#inheritance) +> - Proposal +> [#777: Inheritance](https://github.com/carbon-language/carbon-lang/pull/777) +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) -##### Moving +> **TODO:** -> **TODO:** Needs a feature design and a high level summary provided inline. +#### Access control -##### Comparison +> References: [Access control](classes.md#access-control) -> **TODO:** Needs a feature design and a high level summary provided inline. +> **TODO:** -##### Implicit and explicit conversion +#### Destructors -> **TODO:** Needs a feature design and a high level summary provided inline. +> References: +> +> - [Destructors](classes.md#destructors) +> - Proposal +> [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) -##### Inline type composition +> **TODO:** -> **TODO:** Needs a feature design and a high level summary provided inline. +### Variants -#### Unions +FIXME: Rename to "Choice types" -> **TODO:** Needs a detailed design and a high level summary provided inline. +> References: +> +> - Proposal +> [#157: Design direction for sum types](https://github.com/carbon-language/carbon-lang/pull/157) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -## Pattern matching +> **TODO:** -> References: [Pattern matching](pattern_matching.md) +## Names + +### Packages, libraries, namespaces + +> References: > -> **TODO:** References need to be evolved. +> - [Code and name organization](code_and_name_organization) +> - Proposal +> [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107) +> - Proposal +> [#752: api file default publicn](https://github.com/carbon-language/carbon-lang/pull/752) -The most prominent mechanism to manipulate and work with types in Carbon is -pattern matching. This may seem like a deviation from C++, but in fact this is -largely about building a clear, coherent model for a fundamental part of C++: -overload resolution. +- **Files** are grouped into libraries, which are in turn grouped into + packages. +- **Libraries** are the granularity of code reuse through imports. +- **Packages** are the unit of distribution. -### `match` control flow +Name paths in Carbon always start with the package name. Additional namespaces +may be specified as desired. -> References: [Pattern matching](pattern_matching.md) -> -> **TODO:** References need to be evolved. +For example, this code declares a class `Geometry.Shapes.Flat.Circle` in a +library `Geometry/OneSide`: -`match` is a control flow similar to `switch` of C/C++ and mirrors similar -constructs in other languages, such as Swift. +```carbon +package Geometry library("OneSide") namespace Shapes; -An example `match` is: +namespace Flat; +class Flat.Circle { ... } +``` + +This type can be used from another package: ```carbon -fn Bar() -> (Int, (Float, Float)); +package ExampleUser; -fn Foo() -> Float { - match (Bar()...) { - case (42, (x: Float, y: Float)) => { - return x - y; - } - case (p: Int, (x: Float, _: Float)) if (p < 13) => { - return p * x; - } - case (p: Int, _: auto) if (p > 3) => { - return p * Pi; - } - default => { - return Pi; - } - } -} +import Geometry library("OneSide"); + +fn Foo(Geometry.Shapes.Flat.Circle circle) { ... } ``` -Breaking apart this `match`: +### Names and scopes -- It accepts a value that will be inspected; in this case, the result of the - call to `Bar()`. - - It then will find the _first_ `case` that matches this value, and - execute that block. - - If none match, then it executes the default block. -- Each `case` pattern contains a value pattern, such as `(Int p, auto _)`, - followed by an optional boolean predicate introduced by the `if` keyword. - - The value pattern must first match, and then the predicate must also - evaluate to true for the overall `case` pattern to match. - - Using `auto` for a type will always match. +> References: [Lexical conventions](lexical_conventions) +> +> **TODO:** References need to be evolved. -Value patterns may be composed of the following: +Various constructs introduce a named entity in Carbon. These can be functions, +types, variables, or other kinds of entities that we'll cover. A name in Carbon +is formed from a word, which is a sequence of letters, numbers, and underscores, +and which starts with a letter. We intend to follow Unicode's Annex 31 in +selecting valid identifier characters, but a concrete set of valid characters +has not been selected yet. -- An expression, such as `42`, whose value must be equal to match. -- An identifier to bind the value, followed by a `:` and followed by a type, - such as `Int`. - - The special identifier `_` may be used to discard the value once - matched. -- A destructuring pattern containing a sequence of value patterns, such as - `(x: Float, y: Float)`, which match against tuples and tuple-like values by - recursively matching on their elements. -- An unwrapping pattern containing a nested value pattern which matches - against a variant or variant-like value by unwrapping it. +### Naming conventions -### Pattern matching in local variables +> References: +> +> - [Naming conventions](naming_conventions.md) +> - Proposal +> [#861: Naming conventions](https://github.com/carbon-language/carbon-lang/pull/861) -> References: [Pattern matching](pattern_matching.md) +Our naming conventions are: + +- For idiomatic Carbon code: + - `UpperCamelCase` will be used when the named entity cannot have a + dynamically varying value. For example, functions, namespaces, or + compile-time constant values. + - `lower_snake_case` will be used when the named entity's value won't be + known until runtime, such as for variables. +- For Carbon-provided features: + - Keywords and type literals will use `lower_snake_case`. + - Other code will use the conventions for idiomatic Carbon code. + +### Aliases + +> References: [Aliases](aliases.md) > > **TODO:** References need to be evolved. -Value patterns may be used when declaring local variables to conveniently -destructure them and do other type manipulations. However, the patterns must -match at compile time, so a boolean predicate cannot be used directly. +Carbon provides a facility to declare a new name as an alias for a value. This +is a fully general facility because everything is a value in Carbon, including +types. -An example use is: +For example: ```carbon -fn Bar() -> (Int, (Float, Float)); -fn Foo() -> Int { - var (p: Int, _: auto) = Bar(); - return p; -} +alias MyInt = i32; ``` -To break this apart: +This creates an alias called `MyInt` for whatever `i32` resolves to. Code +textually after this can refer to `MyInt`, and it will transparently refer to +`i32`. -- The `Int` returned by `Bar()` matches and is bound to `p`, then returned. -- The `(Float, Float)` returned by `Bar()` matches and is discarded by - `_: auto`. +### Name lookup -### Pattern matching as function overload resolution +> References: +> +> - [Name lookup](name_lookup.md) +> - Proposal +> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) +> +> **TODO:** References need to be evolved. -> References: [Pattern matching](pattern_matching.md) +Unqualified name lookup will always find a file-local result, including aliases. + +#### Name lookup for common types + +FIXME: should this be renamed to "The prelude"? + +> References: [Name lookup](name_lookup.md) > -> **TODO:** References need to be evolved. Needs a detailed design and a high -> level summary provided inline. +> **TODO:** References need to be evolved. + +Common types that we expect to be used universally will be provided for every +file, including `i32` and `Bool`. These will likely be defined in a special +"prelude" package. + +## Generics -## Type abstractions +> **TODO:** -### Interfaces +### Interfaces and implementations -> **TODO:** Needs a feature design and a high level summary provided inline. +> **TODO:** -### Generics +### Checked and template parameters -> **TODO:** Needs a feature design and a high level summary provided inline. +> References: Proposal +> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) -### Templates +> **TODO:** + +#### Templates > References: [Templates](templates.md) > @@ -811,32 +1059,9 @@ binding. Although generics are generally preferred, templates enable translation of code between C++ and Carbon, and address some cases where the type checking rigor of generics are problematic. -#### Types with template parameters +### Generic functions -> References: [Templates](templates.md) -> -> **TODO:** References need to be evolved. - -User-defined types may have template parameters. The resulting type-function may -be used to instantiate the parameterized definition with the provided arguments -in order to produce a complete type. For example: - -```carbon -class Stack(template T:! Type) { - var storage: Array(T); - - fn Push(value: T); - fn Pop() -> T; -} -``` - -Breaking apart the template use in `Stack`: - -- `Stack` is a paremeterized type accepting a type `T`. -- `T` may be used within the definition of `Stack` anywhere a normal type - would be used, and will only be type checked on instantiation. -- `var ... Array(T)` instantiates a parameterized type `Array` when `Stack` is - instantiated. +> **TODO:** #### Functions with template parameters @@ -857,10 +1082,10 @@ fn Convert[template T:! Type](source: T, template U:! Type) -> U { return converted; } -fn Foo(i: Int) -> Float { - // Instantiates with the `T` implicit argument set to `Int` and the `U` - // explicit argument set to `Float`, then calls with the runtime value `i`. - return Convert(i, Float); +fn Foo(i: i32) -> f32 { + // Instantiates with the `T` implicit argument set to `i32` and the `U` + // explicit argument set to `f32`, then calls with the runtime value `i`. + return Convert(i, f32); } ``` @@ -872,23 +1097,129 @@ that type unavailable to the declaration of _that_ runtime parameter, it still is a _template_ parameter and available to use as a type in the remaining parts of the function declaration. -#### Overloading +### Generic types + +> **TODO:** + +#### Types with template parameters > References: [Templates](templates.md) > > **TODO:** References need to be evolved. -An important feature of templates in C++ is the ability to customize how they -end up specialized for specific arguments. Because template parameters (whether -as type parameters or function parameters) are pattern matched, we expect to -leverage pattern matching techniques to provide "better match" definitions that -are selected analogously to specializations in C++ templates. When expressed -through pattern matching, this may enable things beyond just template parameter -specialization, but that is an area that we want to explore cautiously. +User-defined types may have template parameters. The resulting type-function may +be used to instantiate the parameterized definition with the provided arguments +in order to produce a complete type. For example: + +```carbon +class Stack(template T:! Type) { + var storage: Array(T); + + fn Push(value: T); + fn Pop() -> T; +} +``` + +Breaking apart the template use in `Stack`: + +- `Stack` is a paremeterized type accepting a type `T`. +- `T` may be used within the definition of `Stack` anywhere a normal type + would be used, and will only be type checked on instantiation. +- `var ... Array(T)` instantiates a parameterized type `Array` when `Stack` is + instantiated. + +### Operator overloading + +> References: +> +> - [Operator overloading](generics/details.md#operator-overloading) +> - Question-for-leads issue +> [#1058: How should interfaces for core functionality be named?](https://github.com/carbon-language/carbon-lang/issues/1058) +> - Proposal +> [#1178: Rework operator interfaces](https://github.com/carbon-language/carbon-lang/pull/1178) + +> **TODO:** + +#### Implicit and explicit conversion + +> References: +> +> - [Implicit conversions](expressions/implicit_conversions.md#extensibility) +> - [`as` expressions](expressions/as_expressions.md#extensibility) +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> - Proposal +> [#845: as expressions](https://github.com/carbon-language/carbon-lang/pull/845) + +> **TODO:** + +#### Comparison operators + +> References: +> +> - [Comparison operators](expressions/comparison_operators.md#extensibility) +> - Proposal +> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) +> - Proposal +> [#1178: Rework operator interfaces](https://github.com/carbon-language/carbon-lang/pull/1178) + +> **TODO:** + +#### Arithmetic operators + +> References: +> +> - [Arithmetic expressions](expressions/arithmetic.md#extensibility) +> - Proposal +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) -> **TODO:** lots more work to flesh this out needs to be done... +> **TODO:** -## Metaprogramming +#### Bitwise and shift operators + +> References: +> +> - +> - Proposal +> [#1191: Bitwise operators](https://github.com/carbon-language/carbon-lang/pull/1191) + +> **TODO:** + +#### Common type + +> References: +> +> - [`if` expressions](expressions/if.md#finding-a-common-type) +> - Proposal +> [#911: Conditional expressions](https://github.com/carbon-language/carbon-lang/pull/911) + +> **TODO:** + +## Bidirectional interoperability with C/C++ + +> References: +> +> - [Bidirectional interoperability with C/C++](interoperability/README.md) +> - Proposal +> [#175: C++ interoperability goals](https://github.com/carbon-language/carbon-lang/pull/175) +> +> **TODO:** References need to be evolved. Needs a detailed design and a high +> level summary provided inline. + +## Unfinished tales + +### Pattern matching as function overload resolution + +> References: [Pattern matching](pattern_matching.md) +> +> **TODO:** References need to be evolved. Needs a detailed design and a high +> level summary provided inline. + +### Lifetime and move semantics + +> **TODO:** + +### Metaprogramming > References: [Metaprogramming](metaprogramming.md) > @@ -899,27 +1230,19 @@ Carbon provides metaprogramming facilities that look similar to regular Carbon code. These are structured, and do not offer arbitrary inclusion or preprocessing of source text such as C/C++ does. -## Execution abstractions +### Execution abstractions Carbon provides some higher-order abstractions of program execution, as well as the critical underpinnings of such abstractions. -### Abstract machine and execution model - -> **TODO:** Needs a feature design and a high level summary provided inline. - -### Lambdas +#### Abstract machine and execution model -> **TODO:** Needs a feature design and a high level summary provided inline. +> **TODO:** -### Co-routines +#### Lambdas -> **TODO:** Needs a feature design and a high level summary provided inline. +> **TODO:** -## Bidirectional interoperability with C/C++ +#### Co-routines -> References: -> [Bidirectional interoperability with C/C++](interoperability/README.md) -> -> **TODO:** References need to be evolved. Needs a detailed design and a high -> level summary provided inline. +> **TODO:** diff --git a/docs/design/lexical_conventions/numeric_literals.md b/docs/design/lexical_conventions/numeric_literals.md index 2065a44f76833..b4f1a33a6d30b 100644 --- a/docs/design/lexical_conventions/numeric_literals.md +++ b/docs/design/lexical_conventions/numeric_literals.md @@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Overview](#overview) - [Details](#details) - [Integer literals](#integer-literals) - - [Real number literals](#real-number-literals) + - [Real-number literals](#real-number-literals) - [Digit separators](#digit-separators) - [Divergence from other languages](#divergence-from-other-languages) - [Alternatives considered](#alternatives-considered) @@ -29,13 +29,13 @@ The following syntaxes are supported: - `12345` (decimal) - `0x1FE` (hexadecimal) - `0b1010` (binary) -- Real number literals +- Real-number literals - `123.456` (digits on both sides of the `.`) - `123.456e789` (optional `+` or `-` after the `e`) - `0x1.2p123` (optional `+` or `-` after the `p`) - Digit separators (`_`) may be used, but only in conventional locations -Note that real number literals always contain a `.` with digits on both sides, +Note that real-number literals always contain a `.` with digits on both sides, and integer literals never contain a `.`. Literals are case-sensitive. Unlike in C++, literals do not have a suffix to @@ -65,7 +65,7 @@ the literal is `0`, the `0` begins a base specifier, or the next character is a decimal point (see below). No support is provided for octal literals, and any C or C++ octal literal (other than `0`) is invalid in Carbon. -### Real number literals +### Real-number literals Real numbers are written as a decimal or hexadecimal integer followed by a period (`.`) followed by a sequence of one or more decimal or hexadecimal @@ -81,23 +81,23 @@ is `p`, and the effect is to multiply the given value by 2±_N_. The exponent suffix is optional for both decimal and hexadecimal real numbers. -Note that a decimal integer followed by `e` is not a real number literal. For +Note that a decimal integer followed by `e` is not a real-number literal. For example, `3e10` is not a valid literal. -When a real number literal is interpreted as a value of a real number type, its +When a real-number literal is interpreted as a value of a real-number type, its value is the representable real number closest to the value of the literal. In the case of a tie, the nearest value whose mantissa is even is selected. The decimal real number syntax allows for any decimal fraction to be expressed -- that is, any number of the form _a_ x 10-_b_, where _a_ is an integer and _b_ is a non-negative integer. Because the decimal fractions are -dense in the reals and the set of values of the real number type is assumed to -be discrete, every value of the real number type can be expressed as a real +dense in the reals and the set of values of the real-number type is assumed to +be discrete, every value of the real-number type can be expressed as a real number literal. However, for certain applications, directly expressing the -intended real number representation may be more convenient than producing a +intended real-number representation may be more convenient than producing a decimal equivalent that is known to convert to the intended value. Hexadecimal -real number literals are provided in order to permit values of binary floating -or fixed point real number types to be expressed directly. +real-number literals are provided in order to permit values of binary floating +or fixed point real-number types to be expressed directly. ### Digit separators @@ -108,7 +108,7 @@ respective condition: starting from the right. For example, `2_147_483_648`. - For hexadecimal integers, the digit separators shall occur every four digits starting from the right. For example, `0x7FFF_FFFF`. -- For real number literals, digit separators can appear in the decimal and +- For real-number literals, digit separators can appear in the decimal and hexadecimal integer portions (prior to the period and after the optional `e` or mandatory `p`) as described in the previous bullets. For example, `2_147.483648e12_345` or `0x1_00CA.FEF00Dp+24` From 1a1299e871e0f879cca5516f215d8bfb065409f8 Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 6 May 2022 22:07:04 +0000 Subject: [PATCH 02/46] Fix bitwise link --- docs/design/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/README.md b/docs/design/README.md index d272501d6e20c..da0def802ab76 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1179,7 +1179,7 @@ Breaking apart the template use in `Stack`: > References: > -> - +> - [Bitwise and shift operators](expressions/bitwise.md#extensibility) > - Proposal > [#1191: Bitwise operators](https://github.com/carbon-language/carbon-lang/pull/1191) From 56bf46926093058f7ebda12b89e218ab7400a42d Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 9 May 2022 21:37:35 +0000 Subject: [PATCH 03/46] Primitive types --- docs/design/README.md | 198 +++++++++++++++++++++++++++++------------- 1 file changed, 140 insertions(+), 58 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index da0def802ab76..121507ceecac7 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -14,21 +14,22 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [A note on example code](#a-note-on-example-code) - [Hello, Carbon](#hello-carbon) - [Code and comments](#code-and-comments) +- [Build modes](#build-modes) - [Types](#types) -- [Primitive types](#primitive-types) - - [`bool`](#bool) - - [Integer types](#integer-types) - - [Integer literals](#integer-literals) - - [Floating-point types](#floating-point-types) - - [Floating-point literals](#floating-point-literals) - - [String type](#string-type) - - [String literals](#string-literals) -- [Composite types](#composite-types) - - [Tuples](#tuples) - - [Struct types](#struct-types) - - [Struct literals](#struct-literals) - - [Pointer types](#pointer-types) - - [Arrays and slices](#arrays-and-slices) + - [Primitive types](#primitive-types) + - [`bool`](#bool) + - [Integer types](#integer-types) + - [Integer literals](#integer-literals) + - [Floating-point types](#floating-point-types) + - [Floating-point literals](#floating-point-literals) + - [String types](#string-types) + - [String literals](#string-literals) + - [Composite types](#composite-types) + - [Tuples](#tuples) + - [Struct types](#struct-types) + - [Struct literals](#struct-literals) + - [Pointer types](#pointer-types) + - [Arrays and slices](#arrays-and-slices) - [Functions](#functions) - [Blocks and statements](#blocks-and-statements) - [Expressions](#expressions) @@ -158,23 +159,35 @@ required to be the only non-whitespace on the line. // Compute an approximation of π ``` +## Build modes + +The behavior of Carbon programs depends on the _build mode_: + +- In a _development build_, the priority is diagnosing problems and fast build + time. +- In a _performance build_, the priority is fastest execution time and lowest + memory usage. +- In a _hardened build_, the first priority is safety and second is + performance. + ## Types Carbon's core types are broken down into three categories: -- [Primitive types](#primitive-types) -- [Composite types](#composite-types) +- Primitive types +- Composite types - [User-defined types](#user-defined-types) -The first two are intrinsic and directly built in the language. The last aspect -of types allows for defining new types. +The first two are intrinsic and directly built in the language and are discussed +in this section. The last category of types allows for defining new types, and +is described [later](#user-defined-types). Expressions compute values in Carbon, and these values are always strongly typed much like in C++. However, an important difference from C++ is that types are themselves modeled as values; specifically, compile-time constant values. However, in simple cases this doesn't make much difference. -## Primitive types +### Primitive types > References: [Primitive types](primitive_types.md) @@ -185,31 +198,58 @@ available through the [prelude package](#name-lookup-for-common-types). Primitive types fall into the following categories: -- A boolean type `bool` -- Signed and unsigned integer types. -- IEEE-754 floating-point types. -- String types. +- the boolean type `bool`, +- signed and unsigned integer types, +- IEEE-754 floating-point types, and +- string types. -### `bool` +#### `bool` The type `bool` is a boolean type with two possible values: `true` and `false`. +[Comparison expressions](#expressions) produce `bool` values. The condition +arguments in [control-flow statements](#control-flow), like [`if`](#if-and-else) +and [`while`](#while), and +[`if`-`then`-`else` conditional expressions](#expressions) take `bool` values. -### Integer types +#### Integer types > References: > +> - Question-for-leads issue +> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543) > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> - Proposal +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) -> **TODO:** - -Signed integer types: `i8`, `i16`, `i32`, `i64`, `i128`, `i256`, and -`Carbon.Int(N)`. Overflow in either direction is an error. - -Unsigned integer types: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, and -`Carbon.Unsigned(N)`. Overflow wraps. - -#### Integer literals +The signed-integer type with bit width `N` may be written `Carbon.Int(N)`. For +convenience and brevity, the common power-of-two sizes may be written with an +`i` followed by the size: `i8`, `i16`, `i32`, `i64`, `i128`, or `i256`. +Signed-integer +[overflow](expressions/arithmetic.md#overflow-and-other-error-conditions) is a +programming error: + +- In a development build, overflow will be caught immediately when it happens + at runtime. +- In a performance build, the optimizer can assume that such conditions don't + occur. As a consequence, if they do, the behavior of the program is not + defined. +- In a hardened build, overflow does not result in undefined behavior. + Instead, either the program will be aborted, or the arithmetic will evaluate + to a mathematically incorrect result, such as a two's complement result or + zero. + +The unsigned-integer types are: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, and +`Carbon.UInt(N)`. Unsigned integer types wrap around on overflow, we strongly +advise that they are not used except when those semantics are desired. These +types are intended for [hashing](https://en.wikipedia.org/wiki/Hash_function), +[cryptography](https://en.wikipedia.org/wiki/Cryptography), and +[PRNG](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) use cases. +Values which can never be negative, like sizes, but for which wrapping does not +make sense +[should use signed integer types](/proposals/p1083.md#dont-let-unsigned-arithmetic-wrap). + +##### Integer literals > References: > @@ -221,28 +261,35 @@ Unsigned integer types: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, and > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) -> **TODO:** +Integers may be written in decimal, hexadecimal, or binary: -Decimal, hexadecimal, and binary integer literals and decimal and hexadecimal -floating-point literals are supported, with `_` as a digit separator. For -example, `42`, `0b1011_1101` and `0x1.EEFp+5`. Numeric literals are -case-sensitive: `0x`, `0b`, `e+`, and `p+` must be lowercase, whereas -hexadecimal digits must be uppercase. A digit is required on both sides of a -period. +- `12345` (decimal) +- `0x1FE` (hexadecimal) +- `0b1010` (binary) -### Floating-point types +Underscores `_` may be as a digit separator, but only in conventional locations. +Numeric literals are case-sensitive: `0x`, `0b` must be lowercase, whereas +hexadecimal digits must be uppercase. Integer literals never contain a `.`. + +Unlike in C++, literals do not have a suffix to indicate their type. Instead, +numeric literals have a type derived from their value, and can be implicitly +converted to any type that can represent that value. + +#### Floating-point types > References: > > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> - Proposal +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) -> **TODO:** - -Floating point type with semantics based on IEEE-754: `f16`, `f32`, `f64`, and -`f128`. [`BFloat16`](primitive_types.md#bfloat16) is also provided. +Floating-point types in Carbon have IEEE 754 semantics, use the round-to-nearest +rounding mode, and do not set any floating-point exception state. They are named +with an `f` and the number of bits: `f16`, `f32`, `f64`, and `f128`. +[`BFloat16`](primitive_types.md#bfloat16) is also provided. -#### Floating-point literals +##### Floating-point literals > References: > @@ -256,17 +303,27 @@ Floating point type with semantics based on IEEE-754: `f16`, `f32`, `f64`, and > - Proposal > [#866: Allow ties in floating literals](https://github.com/carbon-language/carbon-lang/pull/866) -> **TODO:** +Decimal and hexadecimal real-number literals are supported: -### String type +- `123.456` (digits on both sides of the `.`) +- `123.456e789` (optional `+` or `-` after the `e`) +- `0x1.Ap123` (optional `+` or `-` after the `p`) -> **TODO:** +Real-number literals always have a period (`.`) and a digit on each side of the +period. When a real-number literal is interpreted as a value of a floating-point +type, its value is the representable real number closest to the value of the +literal. In the case of a tie, the nearest value whose mantissa is even is +selected. + +#### String types + +There are two string types: - `String` - a byte sequence treated as containing UTF-8 encoded text. - `StringView` - a read-only reference to a byte sequence treated as containing UTF-8 encoded text. -#### String literals +##### String literals > References: > @@ -274,11 +331,36 @@ Floating point type with semantics based on IEEE-754: `f16`, `f32`, `f64`, and > - Proposal > [#199: String literals](https://github.com/carbon-language/carbon-lang/pull/199) -> **TODO:** +String literals may be written on a single line using a double quotation mark +(`"`) at the beginning and end of the string, as in `"example"`. + +Multi-line string literals, called _block string literals_, begin and end with +three double quotation marks (`"""`), and may have a file type indicator after +the first `"""`. + +```carbon +// Block string literal: +var block: String = """ + The winds grow high; so do your stomachs, lords. + How irksome is this music to my heart! + When such strings jar, what hope of harmony? + I pray, my lords, let me compound this strife. + -- History of Henry VI, Part II, Act II, Scene 1, W. Shakespeare + """; +``` + +The indentation of a block string literal's terminating line is removed from all +preceding lines. + +Strings may contain +[escape sequences](lexical_conventions/string_literals.md#escape-sequences) +introduced with a backslash (`\`). +[Raw string literals](lexical_conventions/string_literals.md#raw-string-literals) +are available for representing strings with `\`s and `"`s. -## Composite types +### Composite types -### Tuples +#### Tuples > References: [Tuples](tuples.md) @@ -326,7 +408,7 @@ fn RemoveLast(x: (i32, i32, i32)) -> (i32, i32) { } ``` -### Struct types +#### Struct types > References: > @@ -340,7 +422,7 @@ fn RemoveLast(x: (i32, i32, i32)) -> (i32, i32) { _structural data class_, also known as a _struct type_ or _struct_ -#### Struct literals +##### Struct literals > References: [Struct literals](classes.md#literals) @@ -348,11 +430,11 @@ _structural data class_, also known as a _struct type_ or _struct_ _structural data class literal_, also known as a _struct literal_ -### Pointer types +#### Pointer types > **TODO:** -### Arrays and slices +#### Arrays and slices > **TODO:** From 89bf48aa7d75e2cddff2e9fceea40cda03c94fe5 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 10 May 2022 18:47:35 +0000 Subject: [PATCH 04/46] Checkpoint progress. --- docs/design/README.md | 75 +++++++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 121507ceecac7..0f319d13a948a 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -63,6 +63,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Naming conventions](#naming-conventions) - [Aliases](#aliases) - [Name lookup](#name-lookup) + - [Name visibility](#name-visibility) - [Name lookup for common types](#name-lookup-for-common-types) - [Generics](#generics) - [Interfaces and implementations](#interfaces-and-implementations) @@ -279,6 +280,8 @@ converted to any type that can represent that value. > References: > +> - Question-for-leads issue +> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543) > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) > - Proposal @@ -364,12 +367,9 @@ are available for representing strings with `\`s and `"`s. > References: [Tuples](tuples.md) -> **TODO:** - -The primary composite type involves simple aggregation of other types as a -tuple. In formal type theory, tuples are product types. - -An example use of tuples is to return multiple values from a function: +A tuple is a simple aggregation of types. In formal type theory, tuples are +product types. An example use of tuples is to return multiple values from a +function: ```carbon fn DoubleBoth(x: i32, y: i32) -> (i32, i32) { @@ -386,7 +386,8 @@ Both of these are expressions using the tuple syntax `(, )`. The only difference is the type of the tuple expression: one is a tuple of types, the other a tuple of values. -Element access uses subscript syntax: +The components of a tuple are accessed positionally, so element access uses +subscript syntax: ```carbon fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { @@ -394,19 +395,10 @@ fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { } ``` -Tuples also support multiple indices and slicing to restructure tuple elements: - -```carbon -// This reverses the tuple using multiple indices. -fn Reverse(x: (i32, i32, i32)) -> (i32, i32, i32) { - return x[2, 1, 0]; -} - -// This slices the tuple by extracting elements [0, 2). -fn RemoveLast(x: (i32, i32, i32)) -> (i32, i32) { - return x[0 .. 2]; -} -``` +Tuple types are _structural_, which means two tuple types are equal if they have +the same components. This is in contrast to _nominal_ types that have a name +that identifies a specific declaration. Two nominal types are equal if their +names resolve to the same declaration. #### Struct types @@ -417,10 +409,14 @@ fn RemoveLast(x: (i32, i32, i32)) -> (i32, i32) { > [#561: Basic classes: use cases, struct literals, struct types, and future work](https://github.com/carbon-language/carbon-lang/pull/561) > - Proposal > [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) +> - Proposal +> [#710: Default comparison for data classes](https://github.com/carbon-language/carbon-lang/issues/710) -> **TODO:** +The other structural type is called a _structural data class_, also known as a +_struct type_ or _struct_. In contrast to a tuple, a struct's members are +identified by name instead of position. -_structural data class_, also known as a _struct type_ or _struct_ +> **TODO:** ##### Struct literals @@ -447,6 +443,8 @@ _structural data class literal_, also known as a _struct literal_ > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) > - Proposal > [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438) +> - Question-for-leads issue +> [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) Functions are the core unit of behavior. For example, this declares a function that adds two 64-bit integers: @@ -970,7 +968,13 @@ two methods `Distance` and `Offset`: #### Access control -> References: [Access control](classes.md#access-control) +> References: +> +> - [Access control for class members](classes.md#access-control) +> - Question-for-leads issue +> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665) +> - Question-for-leads issue +> [#971: Private interfaces in public API files](https://github.com/carbon-language/carbon-lang/issues/971) > **TODO:** @@ -1008,6 +1012,8 @@ FIXME: Rename to "Choice types" > [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107) > - Proposal > [#752: api file default publicn](https://github.com/carbon-language/carbon-lang/pull/752) +> - Question-for-leads issue +> [#1136: what is the top-level scope in a source file, and what names are found there?](https://github.com/carbon-language/carbon-lang/issues/1136) - **Files** are grouped into libraries, which are in turn grouped into packages. @@ -1072,8 +1078,12 @@ Our naming conventions are: ### Aliases -> References: [Aliases](aliases.md) +> References: > +> - [Aliases](aliases.md) +> - Question-for-leads issue +> [#749: Alias syntax](https://github.com/carbon-language/carbon-lang/issues/749) + > **TODO:** References need to be evolved. Carbon provides a facility to declare a new name as an alias for a value. This @@ -1102,12 +1112,29 @@ textually after this can refer to `MyInt`, and it will transparently refer to Unqualified name lookup will always find a file-local result, including aliases. +### Name visibility + +> References: +> +> - FIXME: Name visibility and access control at file scope +> - Question-for-leads issue +> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665) +> - Proposal +> [#752: api file default public](https://github.com/carbon-language/carbon-lang/pull/752) + +> **TODO:** + #### Name lookup for common types FIXME: should this be renamed to "The prelude"? > References: [Name lookup](name_lookup.md) > +> - Question-for-leads issue +> [#750: Naming conventions for Carbon-provided features](https://github.com/carbon-language/carbon-lang/issues/750) +> - Question-for-leads issue +> [#1058: How should interfaces for core functionality be named?](https://github.com/carbon-language/carbon-lang/issues/1058) +> > **TODO:** References need to be evolved. Common types that we expect to be used universally will be provided for every From cd7f4a041cbc5765e788fae024ba997d4c99125b Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 10 May 2022 18:48:08 +0000 Subject: [PATCH 05/46] Checkpoint progress. --- docs/design/README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 0f319d13a948a..43b8477a360e4 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -63,8 +63,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Naming conventions](#naming-conventions) - [Aliases](#aliases) - [Name lookup](#name-lookup) - - [Name visibility](#name-visibility) - [Name lookup for common types](#name-lookup-for-common-types) + - [Name visibility](#name-visibility) - [Generics](#generics) - [Interfaces and implementations](#interfaces-and-implementations) - [Checked and template parameters](#checked-and-template-parameters) @@ -1112,18 +1112,6 @@ textually after this can refer to `MyInt`, and it will transparently refer to Unqualified name lookup will always find a file-local result, including aliases. -### Name visibility - -> References: -> -> - FIXME: Name visibility and access control at file scope -> - Question-for-leads issue -> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665) -> - Proposal -> [#752: api file default public](https://github.com/carbon-language/carbon-lang/pull/752) - -> **TODO:** - #### Name lookup for common types FIXME: should this be renamed to "The prelude"? @@ -1141,6 +1129,18 @@ Common types that we expect to be used universally will be provided for every file, including `i32` and `Bool`. These will likely be defined in a special "prelude" package. +### Name visibility + +> References: +> +> - FIXME: Name visibility and access control at file scope +> - Question-for-leads issue +> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665) +> - Proposal +> [#752: api file default public](https://github.com/carbon-language/carbon-lang/pull/752) + +> **TODO:** + ## Generics > **TODO:** From 68ba1c77f61edf0e66cd1a7f284a75d35e1ebda1 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 10 May 2022 22:41:01 +0000 Subject: [PATCH 06/46] Add link to generics/details --- docs/design/generics/details.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/design/generics/details.md b/docs/design/generics/details.md index 334d5faeddf71..4e5319c12e6c6 100644 --- a/docs/design/generics/details.md +++ b/docs/design/generics/details.md @@ -2931,7 +2931,8 @@ parameter. [2](https://github.com/apple/swift/blob/main/docs/Generics.rst#constraint-inference)) and [Rust](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=0b2d645bd205f24a7a6e2330d652c32e) -support some form of this feature as part of their type inference. +support some form of this feature as part of their type inference (and +[the Rust community is considering expanding support](http://smallcultfollowing.com/babysteps//blog/2022/04/12/implied-bounds-and-perfect-derive/#expanded-implied-bounds)). #### Must be legal type argument constraints From fedd53693f650cc3334bcf138554560dfd4c4561 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 10 May 2022 22:54:29 +0000 Subject: [PATCH 07/46] Checkpoint progress. --- docs/design/README.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 43b8477a360e4..e53816818af4b 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -26,8 +26,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [String literals](#string-literals) - [Composite types](#composite-types) - [Tuples](#tuples) + - [Structural and nominal types](#structural-and-nominal-types) - [Struct types](#struct-types) - - [Struct literals](#struct-literals) - [Pointer types](#pointer-types) - [Arrays and slices](#arrays-and-slices) - [Functions](#functions) @@ -395,6 +395,8 @@ fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { } ``` +##### Structural and nominal types + Tuple types are _structural_, which means two tuple types are equal if they have the same components. This is in contrast to _nominal_ types that have a name that identifies a specific declaration. Two nominal types are equal if their @@ -412,19 +414,19 @@ names resolve to the same declaration. > - Proposal > [#710: Default comparison for data classes](https://github.com/carbon-language/carbon-lang/issues/710) -The other structural type is called a _structural data class_, also known as a -_struct type_ or _struct_. In contrast to a tuple, a struct's members are -identified by name instead of position. - -> **TODO:** - -##### Struct literals - -> References: [Struct literals](classes.md#literals) +The other [structural type](#structural-and-nominal-types) is called a +_structural data class_, also known as a _struct type_ or _struct_. In contrast +to a tuple, a struct's members are identified by name instead of position. -> **TODO:** +Both struct types and values are written inside curly braces (`{`...`}`). In +both cases, they have a comma-separated list of members that start with a period +(`.`) followed by the field name. -_structural data class literal_, also known as a _struct literal_ +- In a struct type, the field name is followed by a colon (`:`) and the type, + as in: `{.name: String, .count: i32}`. +- In a struct value, called a _structural data class literal_ or a _struct + literal_, the field name is followed by an equal sign (`=`) and the value, + as in `{.key = "Joe", .count = 3}`. #### Pointer types @@ -868,7 +870,9 @@ order. Both [structural data classes](#struct-types) and nominal classes are considered class types, but they are commonly referred to as "structs" and "classes" -respectively when that is not confusing. +respectively when that is not confusing. Like structs, classes refer to their +members by name. Unlike structs, classes are +[nominal types](#structural-and-nominal-types). #### Assignment, copying @@ -877,7 +881,7 @@ respectively when that is not confusing. > - Proposal > [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) -You may use a [struct literal](#struct-literals), to assign or initialize a +You may use a [struct literal](#struct-types), to assign or initialize a variable with a class type. ```carbon From e445cd740e03d82e91b91bbd5644fe5c82809e93 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 10 May 2022 23:11:05 +0000 Subject: [PATCH 08/46] Pointers --- docs/design/README.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index e53816818af4b..d564eed744121 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -26,7 +26,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [String literals](#string-literals) - [Composite types](#composite-types) - [Tuples](#tuples) - - [Structural and nominal types](#structural-and-nominal-types) + - [Structural and nominal types](#structural-and-nominal-types) - [Struct types](#struct-types) - [Pointer types](#pointer-types) - [Arrays and slices](#arrays-and-slices) @@ -395,7 +395,7 @@ fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { } ``` -##### Structural and nominal types +#### Structural and nominal types Tuple types are _structural_, which means two tuple types are equal if they have the same components. This is in contrast to _nominal_ types that have a name @@ -430,7 +430,26 @@ both cases, they have a comma-separated list of members that start with a period #### Pointer types -> **TODO:** +> References: +> +> - Question-for-leads issue +> [#520: should we use whitespace-sensitive operator fixity?](https://github.com/carbon-language/carbon-lang/issues/520) +> - Question-for-leads issue +> [#523: what syntax should we use for pointer types?](https://github.com/carbon-language/carbon-lang/issues/523) + +The type of pointers-to-values-of-type-`T` is written `T*`. Carbon pointers do +not support +[pointer arithmetic](), +the only pointer [operations](#expressions) are: + +- Dereference: given a pointer `p`, `*p` gives the value `p` points to as an + [l-value](). +- Address-of: given an + [l-value]() + `x`, `&x` returns a pointer to `x`. + +In Carbon, one use of pointers is to pass `&x` into a function that will modify +`x`. #### Arrays and slices From 487887b6e7483112462fac6478813cd425f475ad Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 11 May 2022 21:42:48 +0000 Subject: [PATCH 09/46] Arrays --- docs/design/README.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/design/README.md b/docs/design/README.md index d564eed744121..de1438b846ffb 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -453,7 +453,27 @@ In Carbon, one use of pointers is to pass `&x` into a function that will modify #### Arrays and slices -> **TODO:** +The type of an array of holding 4 `i32` values is written `[i32; 4]`. There is +an implicit conversion from tuples to arrays of the same length as long as every +component of the tuple may be implicitly converted to the destination element +type. In cases where the size of the array may be deduced, it may be omitted, as +in: + +```carbon +var i: i32 = 1; +// `[i32;]` equivalent to `[i32; 3]` here. +var a: [i32;] = (i, i, i); +``` + +Elements of an array may be accessed using square brackets (`[`...`]`), as in +`a[i]`: + +```carbon +a[i] = 2; +Console.Print(a[0]); +``` + +> **TODO:** Slices ## Functions From bd049aa6ccd0a00c26e8c77030c69dbb9025f608 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 12 May 2022 01:32:55 +0000 Subject: [PATCH 10/46] Checkpoint progress. --- docs/design/README.md | 63 ++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index de1438b846ffb..f8d9afdd9561c 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -38,6 +38,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [`auto`](#auto) - [Pattern matching](#pattern-matching) - [Pattern matching in local variables](#pattern-matching-in-local-variables) + - [Assignment statements](#assignment-statements) - [Control flow](#control-flow) - [`if` and `else`](#if-and-else) - [Loops](#loops) @@ -496,7 +497,7 @@ fn Add(a: i64, b: i64) -> i64; Breaking this apart: -- `fn` is the keyword used to indicate a function. +- `fn` is the keyword used to introduce a function. - Its name is `Add`. - It accepts two `i64` parameters, `a` and `b`. - It returns an `i64` result. @@ -560,20 +561,29 @@ literal number like `42`: an expression that computes the integer value 42. Some common expressions in Carbon include: -- Literals: `42`, `3.1419`, `"Hello World!"` -- Operators: +- Literals: - - Increment and decrement: `++i`, `--j` - - These do not return any result. - - Unary negation: `-x` - - Arithmetic: `1 + 2`, `3 - 4`, `2 * 5`, `6 / 3` - - Bitwise: `2 & 3`, `2 | 4`, `3 ^ 1`, `^7` - - Bit shift: `1 << 3`, `8 >> 1` - - Comparison: `2 == 2`, `3 != 4`, `5 < 6`, `7 > 6`, `8 <= 8`, `8 >= 8` - - Logical: `a and b`, `c or d`, `not e` - - Conditional: `if c then t else f` + - [boolean](#bool): `true`, `false` + - [integer](#integer-literals): `42`, `-7` + - [real-number](#floating-point-literals): `3.1419`, `6.022e+23` + - [string](#string-literals): `"Hello World!"` + - [tuple](#tuples): `(1, 2, 3)` + - [struct](#struct-types): `{.word = "the", .count = 56}` -- Parenthesized expressions: `(7 + 8) * (3 - 1)` +- [Operators](expressions#operators): + + - [Arithmetic](expressions/arithmetic.md): `-x`, `1 + 2`, `3 - 4`, + `2 * 5`, `6 / 3`, `5 % 3` + - [Bitwise](expressions/bitwise.md): `2 & 3`, `2 | 4`, `3 ^ 1`, `^7` + - [Bit shift](expressions/bitwise.md): `1 << 3`, `8 >> 1` + - [Comparison](expressions/comparison_operators.md): `2 == 2`, `3 != 4`, + `5 < 6`, `7 > 6`, `8 <= 8`, `8 >= 8` + - [Conversion](expressions/as_expressions.md): `2 as i32` + - [Logical](expressions/logical_operators.md): `a and b`, `c or d`, + `not e` + +- [Conditional](expressions/if.md): `if c then t else f` +- Parenthesized: `(7 + 8) * (3 - 1)` ### Variables @@ -589,14 +599,16 @@ Some common expressions in Carbon include: > - Proposal > [#618: var ordering](https://github.com/carbon-language/carbon-lang/pull/618) -Blocks introduce nested scopes and can contain local variable declarations that -work similarly to function parameters. +Blocks introduce nested scopes and can contain variable declarations that are +local to that block, similarly to function parameters. For example: ```carbon -fn DoSomething() { +fn DoSomething() -> i64 { var x: i64 = 42; + x = x + 2; + return x; } ``` @@ -607,6 +619,10 @@ Breaking this apart: - Its type is `i64`. - It is initialized with the value `42`. +Unlike function parameters, `x` is an +[l-value](), +which means it has storage and an address, and so can be modified. + ### `let` > **TODO:** @@ -663,6 +679,21 @@ To break this apart: - The `i32` returned by `Bar()` matches and is bound to `p`, then returned. - The `(f32, f32)` returned by `Bar()` matches and is discarded by `_: auto`. +### Assignment statements + +> **TODO:** + +[l-value]() + +- Assignment: `x = y`. `x` is assigned the value of `y`. +- Increment and decrement: `++i`, `--j`. `i` is set to `i + 1`, `j` is set to + `j - 1`. +- Compound assignment: `x += y`, `x -= y`, `x *= y`, `x /= y`, `x &= y`, + `x |= y`, `x ^= y`, `x <<= y`, `x >>= y`. `x += y` is equivalent to + `x = x + y`. + +> **TODO:** Destructuring assignment + ### Control flow > References: From 281c63e70fe5f48772660a7db893774474b7c177 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 12 May 2022 21:13:49 +0000 Subject: [PATCH 11/46] Checkpoint progress. --- docs/design/README.md | 63 ++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index f8d9afdd9561c..bdad9fd31b513 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -515,21 +515,25 @@ defines what this function does would follow. > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -The body or definition of a function is provided by a block of code containing -statements. The body of a function is also a new, nested scope inside the -function's scope, meaning that parameter names are available. +The body or definition of a function is provided by a block of code in curly +braces (`{`...`}`) containing statements. The body of a function is also a new +scope nested inside the function's scope. Nested here means that parameter names +from the function's scope are available in addition to any names introduced in +the function body. Statements within a block are terminated by a semicolon. Each statement can, -among other things, be an expression. +among other things, be an expression. Some +[control-flow statements](#control-flow) have their own blocks of code. These +are nested within the enclosing scope. -For example, here is a function definition using a block of statements, one of -which is nested: +For example, here is a function definition with a block of statements defining +the body of the function, and a nested block as part of a `while` statement: ```carbon fn Foo() { Bar(); - { - Baz(); + while (Baz()) { + Quux(); } } ``` @@ -570,6 +574,8 @@ Some common expressions in Carbon include: - [tuple](#tuples): `(1, 2, 3)` - [struct](#struct-types): `{.word = "the", .count = 56}` +- [Names](#names) and [member access](expressions/member_access.md) + - [Operators](expressions#operators): - [Arithmetic](expressions/arithmetic.md): `-x`, `1 + 2`, `3 - 4`, @@ -585,6 +591,10 @@ Some common expressions in Carbon include: - [Conditional](expressions/if.md): `if c then t else f` - Parenthesized: `(7 + 8) * (3 - 1)` +When an expression appears in a context in which an expression of a specific +type is expected, [implicit conversions](expressions/implicit_conversions.md) +are applied to convert the expression to the target type. + ### Variables > References: @@ -704,8 +714,12 @@ To break this apart: > - Proposal > [#623: Require braces](https://github.com/carbon-language/carbon-lang/pull/623) -Blocks of statements are generally executed sequentially. However, statements -are the primary place where this flow of execution can be controlled. +Blocks of statements are generally executed sequentially. Control-flow +statements give additional control over the flow of execution and which +statements are executed. + +Some control-flow statements have include [block](#blocks-and-statements) +arguments. Those blocks will always be within curly braces `{`...`}`. #### `if` and `else` @@ -715,15 +729,26 @@ are the primary place where this flow of execution can be controlled. > - Proposal > [#285: if/else](https://github.com/carbon-language/carbon-lang/pull/285) -`if` and `else` provide conditional execution of statements. For example: +`if` and `else` provide conditional execution of statements. It consists of: + +- An `if` introducer followed by a condition in parenthesis. If the condition + evaluates to `true`, the block following the condition is executed, + otherwise it is skipped. +- This may be followed by zero or more `else if` clauses, whose conditions are + evaluated if all prior conditions evaluate to `false`, with a block that is + executed if that evaluation is to `true`. +- A final optional `else` clause, with a block that is executed if all + conditions evaluate to `false`. + +For example: ```carbon if (fruit.IsYellow()) { - Print("Banana!"); + Console.Print("Banana!"); } else if (fruit.IsOrange()) { - Print("Orange!"); + Console.Print("Orange!"); } else { - Print("Vegetable!"); + Console.Print("Vegetable!"); } ``` @@ -752,10 +777,10 @@ example, this prints `0`, `1`, `2`, then `Done!`: ```carbon var x: i32 = 0; while (x < 3) { - Print(x); + Console.Print(x); ++x; } -Print("Done!"); +Console.Print("Done!"); ``` ##### `for` @@ -771,7 +796,7 @@ example, this prints all names in `names`: ```carbon for (var name: String in names) { - Print(name); + Console.Print(name); } ``` @@ -788,7 +813,7 @@ manual step is hit (if no manual step is hit, all steps are processed): ```carbon for (var step: Step in steps) { if (step.IsManual()) { - Print("Reached manual step!"); + Console.Print("Reached manual step!"); break; } step.Process(); @@ -811,7 +836,7 @@ while (!f.EOF()) { if (line.IsEmpty()) { continue; } - Print(line); + Console.Print(line); } ``` From 1a7b2c29c3049d7b7254ff4c6bb8c4db2bcef412 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 12 May 2022 22:47:46 +0000 Subject: [PATCH 12/46] `let` and `auto` --- docs/design/README.md | 46 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index bdad9fd31b513..ad851f8428dfc 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -635,19 +635,61 @@ which means it has storage and an address, and so can be modified. ### `let` -> **TODO:** +To bind a name to a value without associating a specific storage location, use +`let` instead of `var`. + +```carbon +fn DoSomething() -> i64 { + let x: i64 = 42; + return x + 2; +} +``` + +The `let` binds `x` to the _value_ `42`. `x` is an r-value, so it can not be +modified, for example by being the left side of an assignment statement. + +Function parameters are passed by value, and so act like they were defined in a +`let` implicitly. **FIXME:** Is this just the default, or can you write `var` in +a function signature to give parameters dedicated storage so they may be +modified? ### `auto` > References: > > - [Type inference](type_inference.md) +> - [Function return clause](functions.md#return-clause) > - Proposal > [#826: Function return type inference](https://github.com/carbon-language/carbon-lang/pull/826) > - Proposal > [#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851) -> **TODO:** +The keyword `auto` may be used in place of the type in a `var` or `let` +statement in a function body. In this case, the type is the static type of the +initializer expression. + +``` +var x: i64 = 2; +// The type of `y` is inferred to be `i64`. +let y: auto = x + 3; +// The type of `z` is inferred to be `bool`. +var z: auto = (y > 1); +``` + +It may also be used as the return type in a function definition. In this case, +the body of the function must have exactly one `return` statement, and the type +of the function is set to the static type of the expression argument of that +`return`. + +``` +// Return type is inferred to be `bool`, the type of `a > 0`. +fn Positive(a: i64) -> auto { + return a > 0; +} +``` + +Note that `auto` is not allowed in a function declaration without a function +body. ### Pattern matching From d3ed03e6c911ed774cd44bc0b8b4cac50e4f3c36 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 12 May 2022 23:40:50 +0000 Subject: [PATCH 13/46] Use current syntax in `pattern_matching.md` --- docs/design/pattern_matching.md | 42 ++++++++++++++++----------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/design/pattern_matching.md b/docs/design/pattern_matching.md index 834c39445009c..dbf6618ea5513 100644 --- a/docs/design/pattern_matching.md +++ b/docs/design/pattern_matching.md @@ -38,22 +38,22 @@ overload resolution. ### Pattern match control flow The most powerful form and easiest to explain form of pattern matching is a -dedicated control flow construct that subsumes the `switch` of C and C++ into +dedicated control flow construct that subsumes the `switch` of C and C++ i32o something much more powerful, `match`. This is not a novel construct, and is widely used in existing languages (Swift and Rust among others) and is currently under active investigation for C++. Carbon's `match` can be used as follows: ``` -fn Bar() -> (Int, (Float, Float)); -fn Foo() -> Float { +fn Bar() -> (i32, (f32, f32)); +fn Foo() -> f32 { match (Bar()) { - case (42, (Float x, Float y)) => { + case (42, (x: f32, y: f32)) => { return x - y; } - case (Int p, (Float x, Float _)) if (p < 13) => { + case (p: i32, (x: f32, _: f32)) if (p < 13) => { return p * x; } - case (Int p, auto _) if (p > 3) => { + case (p: i32, _: auto) if (p > 3) => { return p * Pi; } default => { @@ -70,35 +70,35 @@ value, and execute that block. If none match, then it executes the default block. Each `case` contains a pattern. The first part is a value pattern -(`(Int p, auto _)` for example) followed by an optional boolean predicate -introduced by the `if` keyword. The value pattern has to match, and then the -predicate has to evaluate to true for the overall pattern to match. Value -patterns can be composed of the following: +(`(p: i32, _: auto)` for example) optionally followed by an `if` and boolean +predicate. The value pattern has to match, and then the predicate has to +evaluate to `true` for the overall pattern to match. Value patterns can be +composed of the following: - An expression (`42` for example), whose value must be equal to match. -- An optional type (`Int` for example), followed by a `:` and either an - identifier to bind to the value or the special identifier `_` to discard the - value once matched. -- A destructuring pattern containing a sequence of value patterns - (`(Float x, Float y)`) which match against tuples and tuple like values by +- An identifier to bind the value to, followed by a colon (`:`) and a type + (`i32` for example). An underscore (`_`) may be used instead of the + identifier to discard the value once matched. +- A tuple destructuring pattern containing a tuple of value patterns + (`(x: f32, y: f32)`) which match against tuples and tuple-like values by recursively matching on their elements. - An unwrapping pattern containing a nested value pattern which matches against a variant or variant-like value by unwrapping it. In order to match a value, whatever is specified in the pattern must match. -Using `auto` for a type will always match, making `auto _` the wildcard pattern. +Using `auto` for a type will always match, making `_: auto` the wildcard +pattern. ### Pattern matching in local variables Value patterns may be used when declaring local variables to conveniently destructure them and do other type manipulations. However, the patterns must -match at compile time which is why the boolean predicate cannot be used -directly. +match at compile time, so they can't use an `if` clause. ``` -fn Bar() -> (Int, (Float, Float)); -fn Foo() -> Int { - var (Int p, auto _) = Bar(); +fn Bar() -> (i32, (f32, f32)); +fn Foo() -> i32 { + var (p: i32, _: auto) = Bar(); return p; } ``` From d5a9fc38f6e2c44b6a6e520ef8e6ce35c3d713ec Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 13 May 2022 18:08:23 +0000 Subject: [PATCH 14/46] Checkpoint progress. --- docs/design/README.md | 90 ++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index ad851f8428dfc..fec06cb727a95 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -37,7 +37,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [`let`](#let) - [`auto`](#auto) - [Pattern matching](#pattern-matching) - - [Pattern matching in local variables](#pattern-matching-in-local-variables) - [Assignment statements](#assignment-statements) - [Control flow](#control-flow) - [`if` and `else`](#if-and-else) @@ -48,7 +47,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [`continue`](#continue) - [`return`](#return) - [`returned var`](#returned-var) - - [`match` control flow](#match-control-flow) + - [`match`](#match) - [User-defined types](#user-defined-types) - [Classes](#classes) - [Assignment, copying](#assignment-copying) @@ -274,8 +273,9 @@ Numeric literals are case-sensitive: `0x`, `0b` must be lowercase, whereas hexadecimal digits must be uppercase. Integer literals never contain a `.`. Unlike in C++, literals do not have a suffix to indicate their type. Instead, -numeric literals have a type derived from their value, and can be implicitly -converted to any type that can represent that value. +numeric literals have a type derived from their value, and can be +[implicitly converted](expressions/implicit_conversions.md) to any type that can +represent that value. #### Floating-point types @@ -455,10 +455,10 @@ In Carbon, one use of pointers is to pass `&x` into a function that will modify #### Arrays and slices The type of an array of holding 4 `i32` values is written `[i32; 4]`. There is -an implicit conversion from tuples to arrays of the same length as long as every -component of the tuple may be implicitly converted to the destination element -type. In cases where the size of the array may be deduced, it may be omitted, as -in: +an [implicit conversion](expressions/implicit_conversions.md) from tuples to +arrays of the same length as long as every component of the tuple may be +implicitly converted to the destination element type. In cases where the size of +the array may be deduced, it may be omitted, as in: ```carbon var i: i32 = 1; @@ -698,53 +698,62 @@ body. > - [Pattern matching](pattern_matching.md) > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -> -> **TODO:** References need to be evolved. - -The most prominent mechanism to manipulate and work with types in Carbon is -pattern matching. This may seem like a deviation from C++, but in fact this is -largely about building a clear, coherent model for a fundamental part of C++: -overload resolution. -#### Pattern matching in local variables - -> References: [Pattern matching](pattern_matching.md) -> -> **TODO:** References need to be evolved. +Patterns are used in a variety of Carbon language constructs, including +[function parameters](#functions), [variable declarations](#variables), and +[`let` declarations](#let). -Value patterns may be used when declaring local variables to conveniently -destructure them and do other type manipulations. However, the patterns must -match at compile time, so a boolean predicate cannot be used directly. +The most common pattern is a _binding pattern_, consisting of a new name, a +colon (`:`), and a type. It can only match values that may be +[implicitly converted](expressions/implicit_conversions.md) to that type. An `_` +may be used instead of the name to ignore the value. +There are also _destructuring patterns_, such as _tuple destructuring_. A tuple +destructuring pattern looks like a tuple of patterns. It may only be used to +match tuple values whose components match the component patterns of the tuple. An example use is: ```carbon +// `Bar()` returns a tuple consisting of an +// `i32` value and 2-tuple of `f32` values. fn Bar() -> (i32, (f32, f32)); -fn Foo() -> i32 { - var (p: i32, _: auto) = Bar(); + +fn Foo() -> i64 { + // Pattern in `var` declaration: + var (p: i64, _: auto) = Bar(); return p; } ``` -To break this apart: +The pattern used in the `var` declaration destructures the tuple value returned +by `Bar()`. The first component pattern, `p: i64`, corresponds to the first +component of the value returned by `Bar()`, which has type `i32`. This is +allowed since there is an implicit conversion from `i32` to `i64`. The result of +this conversion is assigned to the name `p`. The second component pattern, +`_: auto`, matches the second component of the value returned by `Bar()`, which +has type `(f32, f32)`. The [`auto`](#auto) matches any type and the `_` means +the value is discarded. -- The `i32` returned by `Bar()` matches and is bound to `p`, then returned. -- The `(f32, f32)` returned by `Bar()` matches and is discarded by `_: auto`. +Additional kinds of patterns are allowed in [`match` statements](#match). ### Assignment statements -> **TODO:** - +Assignment statements mutate the value of the [l-value]() +described on the left-hand side of the assignment. -- Assignment: `x = y`. `x` is assigned the value of `y`. -- Increment and decrement: `++i`, `--j`. `i` is set to `i + 1`, `j` is set to - `j - 1`. -- Compound assignment: `x += y`, `x -= y`, `x *= y`, `x /= y`, `x &= y`, - `x |= y`, `x ^= y`, `x <<= y`, `x >>= y`. `x += y` is equivalent to - `x = x + y`. +- Assignment: `x = y;`. `x` is assigned the value of `y`. +- Destructuring assignment: `(x, y) = z;`. `z` must be a tuple with the same + number of compents as the left-hand side. `x` is assigned the value of + `z[0]` and `y` is assigned the value of `z[1]`. +- Increment and decrement: `++i;`, `--j;`. `i` is set to `i + 1`, `j` is set + to `j - 1`. +- Compound assignment: `x += y;`, `x -= y;`, `x *= y;`, `x /= y;`, `x &= y;`, + `x |= y;`, `x ^= y;`, `x <<= y;`, `x >>= y;`. `x @= y;` is equivalent to + `x = x @ y;` for each operator `@`. -> **TODO:** Destructuring assignment +Unlike C++, these assignments are statements, not operators, and don't return a +value. ### Control flow @@ -760,8 +769,9 @@ Blocks of statements are generally executed sequentially. Control-flow statements give additional control over the flow of execution and which statements are executed. -Some control-flow statements have include [block](#blocks-and-statements) -arguments. Those blocks will always be within curly braces `{`...`}`. +Some control-flow statements include [block](#blocks-and-statements) arguments. +Those blocks will always be within curly braces `{`...`}`, unlike C++ which also +allows an individual statement without curly braces. #### `if` and `else` @@ -913,7 +923,7 @@ fn Sum(a: i32, b: i32) -> i32 { > **TODO:** -#### `match` control flow +#### `match` > References: [Pattern matching](pattern_matching.md) > From 67593b9424738d306685f798e6aa8a18e127d239 Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 13 May 2022 21:18:50 +0000 Subject: [PATCH 15/46] Checkpoint progress. --- docs/design/README.md | 117 ++++++++++++++++++----------- docs/design/control_flow/return.md | 10 +-- 2 files changed, 78 insertions(+), 49 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index fec06cb727a95..1b975cbee15e3 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -813,13 +813,13 @@ This code will: #### Loops -> References: [Control flow](control_flow/loops.md) +> References: [Loops](control_flow/loops.md) ##### `while` > References: > -> - [Control flow](control_flow/loops.md#while) +> - [`while` loops](control_flow/loops.md#while) > - Proposal > [#340: Add C++-like `while` loops](https://github.com/carbon-language/carbon-lang/pull/340) @@ -839,7 +839,7 @@ Console.Print("Done!"); > References: > -> - [Control flow](control_flow/loops.md#for) +> - [`for` loops](control_flow/loops.md#for) > - Proposal > [#353: Add C++-like `for` loops](https://github.com/carbon-language/carbon-lang/pull/353) @@ -852,15 +852,16 @@ for (var name: String in names) { } ``` -`PrintNames()` prints each `String` in the `names` `List` in iteration order. +This prints each `String` value in `names`. ##### `break` -> References: [Control flow](control_flow/loops.md#break) +> References: [`break`](control_flow/loops.md#break) The `break` statement immediately ends a `while` or `for` loop. Execution will -resume at the end of the loop's scope. For example, this processes steps until a -manual step is hit (if no manual step is hit, all steps are processed): +continue starting from the end of the loop's scope. For example, this processes +steps until a manual step is hit (if no manual step is hit, all steps are +processed): ```carbon for (var step: Step in steps) { @@ -874,7 +875,7 @@ for (var step: Step in steps) { ##### `continue` -> References: [Control flow](control_flow/loops.md#continue) +> References: [`continue`](control_flow/loops.md#continue) The `continue` statement immediately goes to the next loop of a `while` or `for`. In a `while`, execution continues with the `while` expression. For @@ -896,7 +897,7 @@ while (!f.EOF()) { > References: > -> - [Control flow](control_flow/return.md) +> - [`return`](control_flow/return.md) > - [`return` statements](functions.md#return-statements) > - Proposal > [#415: return](https://github.com/carbon-language/carbon-lang/pull/415) @@ -904,33 +905,76 @@ while (!f.EOF()) { > [#538: return with no argument](https://github.com/carbon-language/carbon-lang/pull/538) The `return` statement ends the flow of execution within a function, returning -execution to the caller. If the function returns a value to the caller, that -value is provided by an expression in the return statement. For example: +execution to the caller. ```carbon -fn Sum(a: i32, b: i32) -> i32 { - return a + b; +// Prints the integers 1 .. `n` and then +// returns to the caller. +fn PrintFirstN(n: i32) { + var i: i32 = 0; + while (true) { + i += 1; + if (i > n) { + // None of the rest of the function is + // executed after a `return`. + return; + } + Console.Print(i); + } +} +``` + +If the function returns a value to the caller, that value is provided by an +expression in the return statement. For example: + +```carbon +fn Sign(i: i32) -> i32 { + if (i > 0) { + return 1; + } + if (i < 0) { + return -1; + } + return 0; } + +Assert(Sign(-3) == -1); ``` ##### `returned var` > References: > -> - [Control flow](control_flow/return.md#returned-var) +> - [`returned var`](control_flow/return.md#returned-var) > - Proposal > [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) -> **TODO:** +To avoid a copy when returning a variable, add a `returned` prefix to the +variable's declaration and use `return var` instead of returning an expression, +as in: + +```carbon +fn MakeCircle(radius: i32) -> Circle { + returned var c: Circle; + c.radius = radius; + // `return c` would be invalid because `returned` is in use. + return var; +} +``` + +This is instead of +[the "named return value optimization" of C++](https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization). #### `match` > References: [Pattern matching](pattern_matching.md) -> -> **TODO:** References need to be evolved. `match` is a control flow similar to `switch` of C/C++ and mirrors similar -constructs in other languages, such as Swift. +constructs in other languages, such as Swift. The `match` is followed by an +expression, whose value is matched against `case` declarations in order. The +code for the first matching `case` is executed. An optional `default` code block +may be placed after the `case` declaratoins, it will be executed if none of the +`case` declarations match. An example `match` is: @@ -938,7 +982,7 @@ An example `match` is: fn Bar() -> (i32, (f32, f32)); fn Foo() -> f32 { - match (Bar()...) { + match (Bar()) { case (42, (x: f32, y: f32)) => { return x - y; } @@ -955,31 +999,16 @@ fn Foo() -> f32 { } ``` -Breaking apart this `match`: - -- It accepts a value that will be inspected; in this case, the result of the - call to `Bar()`. - - It then will find the _first_ `case` that matches this value, and - execute that block. - - If none match, then it executes the default block. -- Each `case` pattern contains a value pattern, such as `(p: i32, _: auto)`, - followed by an optional boolean predicate introduced by the `if` keyword. - - The value pattern must first match, and then the predicate must also - evaluate to true for the overall `case` pattern to match. - - Using `auto` for a type will always match. - -Value patterns may be composed of the following: - -- An expression, such as `42`, whose value must be equal to match. -- An identifier to bind the value, followed by a `:` and followed by a type, - such as `i32`. - - The special identifier `_` may be used to discard the value once - matched. -- A destructuring pattern containing a sequence of value patterns, such as - `(x: f32, y: f32)`, which match against tuples and tuple-like values by - recursively matching on their elements. -- An unwrapping pattern containing a nested value pattern which matches - against a variant or variant-like value by unwrapping it. +A `case` pattern can contain +[binding and destructuring patterns](#pattern-matching). In addition, it can +contain patterns that may or may not match based on the runtime value of the +`match` expression: + +- A _value pattern_ is an expression, such as `42`, whose value must be equal + to match. +- An _if pattern_, consisting of an `if` and a boolean predicate at the end of + the pattern like `if (p < 13)`, matches if the predicate evaluates to + `true`. ## User-defined types diff --git a/docs/design/control_flow/return.md b/docs/design/control_flow/return.md index 84456600d8347..ac92fc94fbb2d 100644 --- a/docs/design/control_flow/return.md +++ b/docs/design/control_flow/return.md @@ -30,14 +30,14 @@ If the function returns a value to the caller, that value is provided by an expression in the return statement. For example: ```carbon -fn Sum(a: Int, b: Int) -> Int { +fn Sum(a: i32, b: i32) -> i32 { return a + b; } ``` When a return type is specified, a function must _always_ `return` before control flow can reach the end of the function body. In other words, -`fn DoNothing() -> Int {}` would be invalid because execution will reach the end +`fn DoNothing() -> i32 {}` would be invalid because execution will reach the end of the function body without returning a value. ### Returning empty tuples @@ -93,7 +93,7 @@ Returning expressions is not allowed while a `returned var` is in scope. For example: ```carbon -fn MakeCircle(radius: Int) -> Circle { +fn MakeCircle(radius: i32) -> Circle { returned var c: Circle; c.radius = radius; // `return c` would be invalid because `returned` is in use. @@ -106,7 +106,7 @@ If control flow exits the scope of a `returned` variable in any way other than `return` may again be used with expressions. For example: ```carbon -fn MakePointInArea(Area area, Int preferred_x, Int preferred_y) -> Point { +fn MakePointInArea(area: Area, preferred_x: i32, preferred_y: i32) -> Point { if (preferred_x >= 0 && preferred_y >= 0) { returned var p: Point = { .x = preferred_x, .y = preferred_y }; if (area.Contains(p)) { @@ -148,7 +148,7 @@ declared by the caller. For example, here the `returned var vector` in copy: ```carbon -fn CreateVector(x: Int, y: Int) -> Vector { +fn CreateVector(x: i32, y: i32) -> Vector { returned var vector: Vector; vector.x = x; vector.y = y; From d0c41041deff09304683b83cb89821187818fda0 Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 13 May 2022 23:16:58 +0000 Subject: [PATCH 16/46] Checkpoint progress. --- docs/design/README.md | 131 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 7 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 1b975cbee15e3..6b8876b43cfe6 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -52,10 +52,12 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Classes](#classes) - [Assignment, copying](#assignment-copying) - [Member access](#member-access) + - [Class function](#class-function) - [Methods](#methods) - [Inheritance](#inheritance) - [Access control](#access-control) - [Destructors](#destructors) + - [Other members](#other-members) - [Variants](#variants) - [Names](#names) - [Packages, libraries, namespaces](#packages-libraries-namespaces) @@ -1037,12 +1039,11 @@ class Widget { Breaking apart `Widget`: -- `Widget` has three `i32` members: `x`, `y`, and `z`. -- `Widget` has one `String` member: `payload`. -- Given an instance `dial`, a member can be referenced with `dial.paylod`. +- `Widget` has three `i32` field: `x`, `y`, and `z`. +- `Widget` has one `String` field: `payload`. +- Given an instance `dial`, a field can be referenced with `dial.paylod`. -The order of the member declarations determines the members' memory-layout -order. +The order of the field declarations determines the fields' memory-layout order. Both [structural data classes](#struct-types) and nominal classes are considered class types, but they are commonly referred to as "structs" and "classes" @@ -1058,7 +1059,8 @@ members by name. Unlike structs, classes are > [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) You may use a [struct literal](#struct-types), to assign or initialize a -variable with a class type. +variable with a class type in any scope that has [access](#access-control) to +all of its fields, as in: ```carbon var sprocket: Widget = {.x = 3, .y = 4, .z = 5, .payload = "Sproing"}; @@ -1084,6 +1086,33 @@ notation: Assert(sprocket.x == thingy.x); ``` +Every class has a member named `Self` equal to the class type. + +#### Class function + +Classes may also contain functions as members of the type. This is commonly used +to define a function that creates instances. Carbon does not have separate +[constructors]() +like C++ does. + +```carbon +class Point { + // Class function that instantiates `Point`. + // `Self` in class scope means the class currently being defined. + fn Origin() -> Self { + return {.x = 0, .y = 0}; + } + var x: i32; + var y: i32; +} +``` + +Note that if the definition of a function is provided inside the class scope, +the body is treated as if it was defined immediately after the outermost class +definition. This means that members such as the fields will be considered +defined even if their definitions are later in the source than the class +function. + #### Methods > References: @@ -1096,17 +1125,20 @@ Class type definitions can include methods: ```carbon class Point { + // Method defined inline fn Distance[me: Self](x2: i32, y2: i32) -> f32 { var dx: i32 = x2 - me.x; var dy: i32 = y2 - me.y; return Math.Sqrt(dx * dx - dy * dy); } + // Mutating method fn Offset[addr me: Self*](dx: i32, dy: i32); var x: i32; var y: i32; } +// Out-of-line definition of method declared inline. fn Point.Offset[addr me: Self*](dx: i32, dy: i32) { me->x += dx; me->y += dy; @@ -1121,7 +1153,7 @@ Assert(origin.Distance(3, 4) == 0.0); This defines a `Point` class type with two integer data members `x` and `y` and two methods `Distance` and `Offset`: -- Methods are defined as functions with a `me` parameter inside square +- Methods are defined as class functions with a `me` parameter inside square brackets `[`...`]` before the regular explicit parameter list in parens `(`...`)`. - Methods are called using using the member syntax, `origin.Distance(`...`)` @@ -1144,6 +1176,87 @@ two methods `Distance` and `Offset`: > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +Classes by default are +[_final_](), +which means they may not be extended. A class may be declared as allowing +extension using either the `base class` or `abstract class` introducer instead +of `class`. An `abstract class` is a base class that may not itself be +instantiated. + +```carbon +base class MyBaseClass { ... } +``` + +Either kind of base class maybe _extended_ to get a _derived class_. Derived +classes are final unless they are themselved declared `base` or `abstract`. +Classes may only extend a single class. Carbon only supports single inheritance, +and will use mixins instead of multiple inheritance. + +```carbon +base class MiddleDerived extends MyBaseClass { ... } +class FinalDerived extends MiddleDerived { ... } +// ❌ Forbidden: class Illegal extends FinalDerived { ... } +``` + +A base class may define +[virtual methods](https://en.wikipedia.org/wiki/Virtual_function). These are +methods whose implementation may be overridden in a derived class. By default +methods are _non-virtual_, the declaration of a virtual methods must be prefixed +by one of these three keywords: + +- A method marked `virtual` has a definition in this class but not in any + base. +- A method marked `abstract` does not have have a definition in this class, + but must have a definition in any non-`abstract` derived class. +- A method marked `impl` has a definition in this class, overriding any + definition in a base class. + +A pointer to a derived class may be cast to a pointer to one of its base +classes. Calling a virtual method through a pointer to a base class will use the +overridden definition provided in the derived class. + +For purposes of construction, a derived class acts like its first field is +called `base` with the type of its immediate base class. + +```carbon +class MyDerivedType extends MyBaseType { + fn Create() -> MyDerivedType { + return {.base = MyBaseType.Create(), .derived_field = 7}; + } + var derived_field: i32; +} +``` + +Abstract classes can't be instantiated, so instead they should define class +functions returning `partial Self`. Those functions should be marked +[`protected`](#access-control) so they may only be used by derived classes. + +```carbon +abstract class AbstractClass { + protected fn Create() -> partial Self { + return {.field_1 = 3, .field_2 = 9}; + } + // ... + var field_1: i32; + var field_2: i32; +} +// ❌ Error: can't instantiate abstract class +var abc: AbstractClass = ...; + +class DerivedFromAbstract extends AbstractClass { + fn Create() -> Self { + // AbstractClass.Create() returns a + // `partial AbstractClass` that can be used as + // the `.base` member when constructing a value + // of a derived class + return {.base = AbstractClass.Create(), + .derived_field = 42 }; + } + + var derived_field: i32; +} +``` + > **TODO:** #### Access control @@ -1168,6 +1281,10 @@ two methods `Distance` and `Offset`: > **TODO:** +#### Other members + +> **TODO:** `let`, `alias`, class functions, nested classes + ### Variants FIXME: Rename to "Choice types" From 6ed743025af9b1baeb8ff29e3a6f041a5b75ad9b Mon Sep 17 00:00:00 2001 From: Josh L Date: Sat, 14 May 2022 00:07:05 +0000 Subject: [PATCH 17/46] Checkpoint progress. --- 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 6b8876b43cfe6..b2ad6cae942d4 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -52,7 +52,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Classes](#classes) - [Assignment, copying](#assignment-copying) - [Member access](#member-access) - - [Class function](#class-function) + - [Class functions and factory functions](#class-functions-and-factory-functions) - [Methods](#methods) - [Inheritance](#inheritance) - [Access control](#access-control) @@ -1088,7 +1088,7 @@ Assert(sprocket.x == thingy.x); Every class has a member named `Self` equal to the class type. -#### Class function +#### Class functions and factory functions Classes may also contain functions as members of the type. This is commonly used to define a function that creates instances. Carbon does not have separate @@ -1113,6 +1113,21 @@ definition. This means that members such as the fields will be considered defined even if their definitions are later in the source than the class function. +The [`returned var` feature](#returned-var) can be used if the address of the +instance being created is needed in a factory function, as in: + +```carbon +class Registered { + fn Create() -> Self { + returned var result: Self = {...}; + StoreMyPointerSomewhere(&result); + return var; + } +} +``` + +This approach can also be used for types that can't be copied or moved. + #### Methods > References: @@ -1248,7 +1263,7 @@ class DerivedFromAbstract extends AbstractClass { // AbstractClass.Create() returns a // `partial AbstractClass` that can be used as // the `.base` member when constructing a value - // of a derived class + // of a derived class. return {.base = AbstractClass.Create(), .derived_field = 42 }; } @@ -1257,8 +1272,6 @@ class DerivedFromAbstract extends AbstractClass { } ``` -> **TODO:** - #### Access control > References: From 6745f854a281e9ceefe1b76913c288e0ac31ab8e Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 16 May 2022 22:50:43 +0000 Subject: [PATCH 18/46] Checkpoint progress. --- docs/design/README.md | 56 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index b2ad6cae942d4..d9382620f4d7d 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -58,7 +58,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Access control](#access-control) - [Destructors](#destructors) - [Other members](#other-members) - - [Variants](#variants) + - [Choice types](#choice-types) - [Names](#names) - [Packages, libraries, namespaces](#packages-libraries-namespaces) - [Names and scopes](#names-and-scopes) @@ -1282,7 +1282,16 @@ class DerivedFromAbstract extends AbstractClass { > - Question-for-leads issue > [#971: Private interfaces in public API files](https://github.com/carbon-language/carbon-lang/issues/971) -> **TODO:** +Class members are by default publicly accessible. The `private` keyword prefix +can be added to the member's declaration to restrict it to members of the class +or any friends. A `private virtual` or `private abstract` method may be +implemented in derived classes, even though it may not be called. + +Friends may be declared using a `friend` declaration inside the class naming an +existing function or type. Unlike C++, `friend` declarations may only refer to +names resolvable to the compiler and don't act like forward declarations. + +`protected` is like `private`, but also gives access to derived classes. #### Destructors @@ -1292,15 +1301,50 @@ class DerivedFromAbstract extends AbstractClass { > - Proposal > [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) -> **TODO:** +A destructor for a class is a custom code executed when the lifetime of a value +of that type ends. They are defined with the `destructor` keyword followed by +either `[me: Self]` or `[addr me: Self*]` (as is done with [methods](#methods)) +and the block of code in the class definition, as in: + +```carbon +class MyClass { + destructor [me: Self] { ... } +} +``` + +or: + +```carbon +class MyClass { + // Can modify `me` in the body. + destructor [addr me: Self*] { ... } +} +``` + +The destructor for a class is run before the destructors of its data members. +The data members are destroyed in reverse order of declaration. Derived classes +are destroyed before their base classes. + +A destructor in a abstract or base class may be declared `virtual` like with +[methods](#inheritance). Destructors in classes derived from one with a virtual +destructor must be declared with the `impl` keyword prefix. It is illegal to +delete an instance of a derived class through a pointer to a base class unless +the base class is declared `virtual` or `impl`. To delete a pointer to a +non-abstract base class when it is known not to point to a value with a derived +type, use `UnsafeDelete`. #### Other members -> **TODO:** `let`, `alias`, class functions, nested classes +Classes may also contain other kinds of declarations, which results in them +having names inside the class' scope: -### Variants +- [`alias`](#aliases) +- [`let`](#let) to define constants. **TODO:** Are these constants associated + with the class or the instance? +- `class`, to define a + [_member class_ or _nested class_](https://en.wikipedia.org/wiki/Inner_class) -FIXME: Rename to "Choice types" +### Choice types > References: > From 5573b78839dc6ace73ae3983577f132ddd444887 Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 16 May 2022 23:39:04 +0000 Subject: [PATCH 19/46] Checkpoint progress. --- docs/design/README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/design/README.md b/docs/design/README.md index d9382620f4d7d..433e346c4ed5f 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -710,6 +710,9 @@ colon (`:`), and a type. It can only match values that may be [implicitly converted](expressions/implicit_conversions.md) to that type. An `_` may be used instead of the name to ignore the value. +> **TODO:** Using `var` before a binding pattern to allocate storage so the new +> name can be modified? + There are also _destructuring patterns_, such as _tuple destructuring_. A tuple destructuring pattern looks like a tuple of patterns. It may only be used to match tuple values whose components match the component patterns of the tuple. @@ -1355,6 +1358,36 @@ having names inside the class' scope: > **TODO:** +```carbon +choice Result(T:! Type, Error:! Type) { + Success(value: T), + Failure(error: Error), + Cancelled +} + +fn ParseAsInt(s: String) -> Result(i32, String) { + var r: i32 = 0; + ... + if (not IsDigit(s[i])) { + return .Failure("Invalid character"); + } + ... + return .Success(r); +} + +match (ParseAsInt(s)) { + case .Success(value: i32) => { + return value; + } + case .Failure(error: String) => { + Display(error); + } + case .Cancelled => { + Terminate(); + } +} +``` + ## Names ### Packages, libraries, namespaces From 001b0a13afd184ccab400c8845950da858f2d185 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 17 May 2022 17:53:00 +0000 Subject: [PATCH 20/46] Checkpoint progress. --- docs/design/README.md | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 433e346c4ed5f..10f7a57c12f71 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -75,6 +75,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Functions with template parameters](#functions-with-template-parameters) - [Generic types](#generic-types) - [Types with template parameters](#types-with-template-parameters) + - [Generic choice types](#generic-choice-types) - [Operator overloading](#operator-overloading) - [Implicit and explicit conversion](#implicit-and-explicit-conversion) - [Comparison operators](#comparison-operators) @@ -366,6 +367,8 @@ are available for representing strings with `\`s and `"`s. ### Composite types +> **TODO:** Maybe rename to "structural types"? + #### Tuples > References: [Tuples](tuples.md) @@ -451,6 +454,10 @@ the only pointer [operations](#expressions) are: [l-value]() `x`, `&x` returns a pointer to `x`. +There are no [null pointers](https://en.wikipedia.org/wiki/Null_pointer) in +Carbon. To represent a pointer that may not refer to a valid object, use the +type `Optional(T*)`. + In Carbon, one use of pointers is to pass `&x` into a function that will modify `x`. @@ -1017,6 +1024,8 @@ contain patterns that may or may not match based on the runtime value of the ## User-defined types +> **TODO:** Maybe rename to "nominal types"? + ### Classes > References: @@ -1049,7 +1058,7 @@ Breaking apart `Widget`: The order of the field declarations determines the fields' memory-layout order. Both [structural data classes](#struct-types) and nominal classes are considered -class types, but they are commonly referred to as "structs" and "classes" +_class types_, but they are commonly referred to as "structs" and "classes" respectively when that is not confusing. Like structs, classes refer to their members by name. Unlike structs, classes are [nominal types](#structural-and-nominal-types). @@ -1089,7 +1098,7 @@ notation: Assert(sprocket.x == thingy.x); ``` -Every class has a member named `Self` equal to the class type. +Every class has a member named `Self` equal to the class type itself. #### Class functions and factory functions @@ -1359,19 +1368,20 @@ having names inside the class' scope: > **TODO:** ```carbon -choice Result(T:! Type, Error:! Type) { - Success(value: T), - Failure(error: Error), +choice IntResult { + Success(value: i32), + Failure(error: String), Cancelled } -fn ParseAsInt(s: String) -> Result(i32, String) { +fn ParseAsInt(s: String) -> IntResult { var r: i32 = 0; - ... - if (not IsDigit(s[i])) { + for (c: i32 in s) { + if (not IsDigit(c)) { return .Failure("Invalid character"); } - ... + // ... + } return .Success(r); } @@ -1624,6 +1634,16 @@ Breaking apart the template use in `Stack`: - `var ... Array(T)` instantiates a parameterized type `Array` when `Stack` is instantiated. +#### Generic choice types + +```carbon +choice Result(T:! Type, Error:! Type) { + Success(value: T), + Failure(error: Error), + Cancelled +} +``` + ### Operator overloading > References: From 84e589f92303b27e240e5305ba0c2ae1513be68c Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 18 May 2022 00:10:28 +0000 Subject: [PATCH 21/46] Checkpoint progress. --- docs/design/README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/design/README.md b/docs/design/README.md index 10f7a57c12f71..30c8608974405 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -450,6 +450,7 @@ the only pointer [operations](#expressions) are: - Dereference: given a pointer `p`, `*p` gives the value `p` points to as an [l-value](). + `p->m` is syntactic sugar for `(*p).m`. - Address-of: given an [l-value]() `x`, `&x` returns a pointer to `x`. @@ -604,6 +605,9 @@ When an expression appears in a context in which an expression of a specific type is expected, [implicit conversions](expressions/implicit_conversions.md) are applied to convert the expression to the target type. +> **TODO:** indexing `a[`...`]`, function call `f(`...`)`, dereference `*p`, +> member access `x.m` and `p->m`, and address of `&x` + ### Variables > References: @@ -1063,6 +1067,8 @@ respectively when that is not confusing. Like structs, classes refer to their members by name. Unlike structs, classes are [nominal types](#structural-and-nominal-types). +> **TODO:** Forward declarations + #### Assignment, copying > References: [Classes](classes.md#construction) @@ -1365,7 +1371,10 @@ having names inside the class' scope: > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -> **TODO:** +A _choice type_ is a [tagged union](https://en.wikipedia.org/wiki/Tagged_union), +that can store different types of data in a storage space that can hold the +largest. A choice type has a name, and a list of cases separated by commas +(`,`). Each case has a name and a optional parameter list. ```carbon choice IntResult { @@ -1373,18 +1382,29 @@ choice IntResult { Failure(error: String), Cancelled } +``` +The value of a choice type is one of the cases, plus the values of the +parameters to that case, if any. A value can be constructed by naming the case +and providing values for the parameters, if any: + +```carbon fn ParseAsInt(s: String) -> IntResult { var r: i32 = 0; for (c: i32 in s) { if (not IsDigit(c)) { + // Equivalent to `IntResult.Failure(...)` return .Failure("Invalid character"); } // ... } return .Success(r); } +``` +Choice type values may be consumed using a [`match` statement](#match): + +```carbon match (ParseAsInt(s)) { case .Success(value: i32) => { return value; @@ -1398,6 +1418,14 @@ match (ParseAsInt(s)) { } ``` +They can also represent an +[enumerated type](https://en.wikipedia.org/wiki/Enumerated_type), if no +additional data is associated with the choices, as in: + +```carbon +choice LikeABoolean { False, True } +``` + ## Names ### Packages, libraries, namespaces From 95ca7f1ad39c4099de66c8214154082f33060c97 Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 18 May 2022 00:19:19 +0000 Subject: [PATCH 22/46] Address some TODOs, shorten --- docs/design/README.md | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 30c8608974405..c2976532ee9f3 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -51,7 +51,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [User-defined types](#user-defined-types) - [Classes](#classes) - [Assignment, copying](#assignment-copying) - - [Member access](#member-access) - [Class functions and factory functions](#class-functions-and-factory-functions) - [Methods](#methods) - [Inheritance](#inheritance) @@ -597,6 +596,9 @@ Some common expressions in Carbon include: - [Conversion](expressions/as_expressions.md): `2 as i32` - [Logical](expressions/logical_operators.md): `a and b`, `c or d`, `not e` + - Indexing: `a[3]` + - Function call: `f(4)` + - Pointer and member: `*p`, `x.m`, `p->m`, `&x` - [Conditional](expressions/if.md): `if c then t else f` - Parenthesized: `(7 + 8) * (3 - 1)` @@ -605,9 +607,6 @@ When an expression appears in a context in which an expression of a specific type is expected, [implicit conversions](expressions/implicit_conversions.md) are applied to convert the expression to the target type. -> **TODO:** indexing `a[`...`]`, function call `f(`...`)`, dereference `*p`, -> member access `x.m` and `p->m`, and address of `&x` - ### Variables > References: @@ -1037,6 +1036,8 @@ contain patterns that may or may not match based on the runtime value of the > - [Classes](classes.md#nominal-class-types) > - Proposal > [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722) +> - Proposal +> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) _Nominal classes_, or just _classes_, are a way for users to define their own data strutures or record types. @@ -1061,14 +1062,17 @@ Breaking apart `Widget`: The order of the field declarations determines the fields' memory-layout order. +Every class has a member named `Self` equal to the class type itself. + +Like functions, a class may be forward declared, ending the declaration with a +semicolon (`;`) instead of the block in curly braces (`{`...`}`). + Both [structural data classes](#struct-types) and nominal classes are considered _class types_, but they are commonly referred to as "structs" and "classes" respectively when that is not confusing. Like structs, classes refer to their members by name. Unlike structs, classes are [nominal types](#structural-and-nominal-types). -> **TODO:** Forward declarations - #### Assignment, copying > References: [Classes](classes.md#construction) @@ -1090,22 +1094,9 @@ You may also copy one struct into another of the same type. ```carbon var thingy: Widget = sprocket; sprocket = thingy; -``` - -#### Member access - -> References: Proposal -> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) - -The data members of a variable with a class type may be accessed using dot `.` -notation: - -```carbon Assert(sprocket.x == thingy.x); ``` -Every class has a member named `Self` equal to the class type itself. - #### Class functions and factory functions Classes may also contain functions as members of the type. This is commonly used @@ -1358,7 +1349,8 @@ having names inside the class' scope: - [`alias`](#aliases) - [`let`](#let) to define constants. **TODO:** Are these constants associated - with the class or the instance? + with the class or the instance? Do we need to another syntax to distinguish + constants associated with the class like `class let` or `static let`? - `class`, to define a [_member class_ or _nested class_](https://en.wikipedia.org/wiki/Inner_class) From eaab8805bc995556a86c2ed9374bca50a8b57b6e Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 18 May 2022 00:23:55 +0000 Subject: [PATCH 23/46] Fix search-replace error --- docs/design/pattern_matching.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/pattern_matching.md b/docs/design/pattern_matching.md index dbf6618ea5513..86d85eb76cb72 100644 --- a/docs/design/pattern_matching.md +++ b/docs/design/pattern_matching.md @@ -38,7 +38,7 @@ overload resolution. ### Pattern match control flow The most powerful form and easiest to explain form of pattern matching is a -dedicated control flow construct that subsumes the `switch` of C and C++ i32o +dedicated control flow construct that subsumes the `switch` of C and C++ into something much more powerful, `match`. This is not a novel construct, and is widely used in existing languages (Swift and Rust among others) and is currently under active investigation for C++. Carbon's `match` can be used as follows: From a2ae084e40a27e6e9ef1059735bde055ddeb415e Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 20 May 2022 21:13:31 +0000 Subject: [PATCH 24/46] Reference #1283. Condense operator overloading --- docs/design/README.md | 57 +++++++++++-------------------------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index c2976532ee9f3..31f6089b40c81 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -76,10 +76,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Types with template parameters](#types-with-template-parameters) - [Generic choice types](#generic-choice-types) - [Operator overloading](#operator-overloading) - - [Implicit and explicit conversion](#implicit-and-explicit-conversion) - - [Comparison operators](#comparison-operators) - - [Arithmetic operators](#arithmetic-operators) - - [Bitwise and shift operators](#bitwise-and-shift-operators) - [Common type](#common-type) - [Bidirectional interoperability with C/C++](#bidirectional-interoperability-with-cc) - [Unfinished tales](#unfinished-tales) @@ -982,7 +978,11 @@ This is instead of #### `match` -> References: [Pattern matching](pattern_matching.md) +> References: +> +> - [Pattern matching](pattern_matching.md) +> - Question-for-leads issue +> [#1283: how should pattern matching and implicit conversion interact?](https://github.com/carbon-language/carbon-lang/issues/1283) `match` is a control flow similar to `switch` of C/C++ and mirrors similar constructs in other languages, such as Swift. The `match` is followed by an @@ -1669,57 +1669,28 @@ choice Result(T:! Type, Error:! Type) { > References: > > - [Operator overloading](generics/details.md#operator-overloading) -> - Question-for-leads issue -> [#1058: How should interfaces for core functionality be named?](https://github.com/carbon-language/carbon-lang/issues/1058) > - Proposal -> [#1178: Rework operator interfaces](https://github.com/carbon-language/carbon-lang/pull/1178) - -> **TODO:** - -#### Implicit and explicit conversion - -> References: -> -> - [Implicit conversions](expressions/implicit_conversions.md#extensibility) -> - [`as` expressions](expressions/as_expressions.md#extensibility) +> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) > - Proposal > [#845: as expressions](https://github.com/carbon-language/carbon-lang/pull/845) - -> **TODO:** - -#### Comparison operators - -> References: -> -> - [Comparison operators](expressions/comparison_operators.md#extensibility) +> - Question-for-leads issue +> [#1058: How should interfaces for core functionality be named?](https://github.com/carbon-language/carbon-lang/issues/1058) > - Proposal -> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) +> - Proposal +> [#1191: Bitwise operators](https://github.com/carbon-language/carbon-lang/pull/1191) > - Proposal > [#1178: Rework operator interfaces](https://github.com/carbon-language/carbon-lang/pull/1178) > **TODO:** -#### Arithmetic operators - -> References: -> +> - [Implicit conversions](expressions/implicit_conversions.md#extensibility) +> - [`as` expressions](expressions/as_expressions.md#extensibility) +> - [Comparison operators](expressions/comparison_operators.md#extensibility) > - [Arithmetic expressions](expressions/arithmetic.md#extensibility) -> - Proposal -> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) - -> **TODO:** - -#### Bitwise and shift operators - -> References: -> > - [Bitwise and shift operators](expressions/bitwise.md#extensibility) -> - Proposal -> [#1191: Bitwise operators](https://github.com/carbon-language/carbon-lang/pull/1191) - -> **TODO:** #### Common type From f097d9eb70e898f0a2151d4d70c2aeb9dc65c3d0 Mon Sep 17 00:00:00 2001 From: josh11b Date: Fri, 20 May 2022 20:41:59 -0700 Subject: [PATCH 25/46] Apply suggestions from code review Co-authored-by: Geoff Romer --- docs/design/README.md | 62 ++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 31f6089b40c81..c9789261b38e9 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -160,7 +160,7 @@ required to be the only non-whitespace on the line. ## Build modes -The behavior of Carbon programs depends on the _build mode_: +The behavior of the Carbon compiler depends on the _build mode_: - In a _development build_, the priority is diagnosing problems and fast build time. @@ -368,9 +368,9 @@ are available for representing strings with `\`s and `"`s. > References: [Tuples](tuples.md) -A tuple is a simple aggregation of types. In formal type theory, tuples are -product types. An example use of tuples is to return multiple values from a -function: +A tuple is a fixed-size collection of values that can have different types, +where each value is identified by its position in the tuple. An example use +of tuples is to return multiple values from a function: ```carbon fn DoubleBoth(x: i32, y: i32) -> (i32, i32) { @@ -385,10 +385,11 @@ Breaking this example apart: Both of these are expressions using the tuple syntax `(, )`. The only difference is the type of the tuple -expression: one is a tuple of types, the other a tuple of values. +expression: one is a tuple of types, the other a tuple of values. In other +words, a tuple type is a tuple _of_ types. The components of a tuple are accessed positionally, so element access uses -subscript syntax: +subscript syntax, but the index must be a compile-time constant: ```carbon fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { @@ -440,7 +441,7 @@ both cases, they have a comma-separated list of members that start with a period The type of pointers-to-values-of-type-`T` is written `T*`. Carbon pointers do not support -[pointer arithmetic](), +[pointer arithmetic](); the only pointer [operations](#expressions) are: - Dereference: given a pointer `p`, `*p` gives the value `p` points to as an @@ -493,8 +494,8 @@ Console.Print(a[0]); > - Question-for-leads issue > [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) -Functions are the core unit of behavior. For example, this declares a function -that adds two 64-bit integers: +Functions are the core unit of behavior. For example, this is a declaration +of a function that adds two 64-bit integers: ```carbon fn Add(a: i64, b: i64) -> i64; @@ -509,8 +510,13 @@ Breaking this apart: You would call this function like `Add(1, 2)`. -This just declares the function, a definition that includes the body that -defines what this function does would follow. +A function definition is a function declaration that has a body block +instead of a semicolon: + +```carbon +fn Add(a: i64, b: i64) -> i64 { + return a + b; +} ### Blocks and statements @@ -596,8 +602,8 @@ Some common expressions in Carbon include: - Function call: `f(4)` - Pointer and member: `*p`, `x.m`, `p->m`, `&x` -- [Conditional](expressions/if.md): `if c then t else f` -- Parenthesized: `(7 + 8) * (3 - 1)` +- [Conditionals](expressions/if.md): `if c then t else f` +- Parentheses: `(7 + 8) * (3 - 1)` When an expression appears in a context in which an expression of a specific type is expected, [implicit conversions](expressions/implicit_conversions.md) @@ -654,7 +660,8 @@ fn DoSomething() -> i64 { ``` The `let` binds `x` to the _value_ `42`. `x` is an r-value, so it can not be -modified, for example by being the left side of an assignment statement. +modified, for example by being the left side of an assignment statement, +and its address cannot be taken. Function parameters are passed by value, and so act like they were defined in a `let` implicitly. **FIXME:** Is this just the default, or can you write `var` in @@ -685,8 +692,8 @@ var z: auto = (y > 1); ``` It may also be used as the return type in a function definition. In this case, -the body of the function must have exactly one `return` statement, and the type -of the function is set to the static type of the expression argument of that +the body of the function must have exactly one `return` statement, and the return +type of the function is set to the static type of the expression argument of that `return`. ``` @@ -763,7 +770,7 @@ described on the left-hand side of the assignment. `x |= y;`, `x ^= y;`, `x <<= y;`, `x >>= y;`. `x @= y;` is equivalent to `x = x @ y;` for each operator `@`. -Unlike C++, these assignments are statements, not operators, and don't return a +Unlike C++, these assignments are statements, not expressions, and don't return a value. ### Control flow @@ -792,9 +799,10 @@ allows an individual statement without curly braces. > - Proposal > [#285: if/else](https://github.com/carbon-language/carbon-lang/pull/285) -`if` and `else` provide conditional execution of statements. It consists of: +`if` and `else` provide conditional execution of statements. An `if` +statement consists of: -- An `if` introducer followed by a condition in parenthesis. If the condition +- An `if` introducer followed by a condition in parentheses. If the condition evaluates to `true`, the block following the condition is executed, otherwise it is skipped. - This may be followed by zero or more `else if` clauses, whose conditions are @@ -834,7 +842,7 @@ This code will: > - Proposal > [#340: Add C++-like `while` loops](https://github.com/carbon-language/carbon-lang/pull/340) -`while` statements loop for as long as the passed expression returns `True`. For +`while` statements loop for as long as the passed expression returns `true`. For example, this prints `0`, `1`, `2`, then `Done!`: ```carbon @@ -985,8 +993,8 @@ This is instead of > [#1283: how should pattern matching and implicit conversion interact?](https://github.com/carbon-language/carbon-lang/issues/1283) `match` is a control flow similar to `switch` of C/C++ and mirrors similar -constructs in other languages, such as Swift. The `match` is followed by an -expression, whose value is matched against `case` declarations in order. The +constructs in other languages, such as Swift. The `match` keyword is followed by an +expression in parentheses, whose value is matched against `case` declarations in order. The code for the first matching `case` is executed. An optional `default` code block may be placed after the `case` declaratoins, it will be executed if none of the `case` declarations match. @@ -1058,13 +1066,13 @@ Breaking apart `Widget`: - `Widget` has three `i32` field: `x`, `y`, and `z`. - `Widget` has one `String` field: `payload`. -- Given an instance `dial`, a field can be referenced with `dial.paylod`. +- Given an instance `dial`, a field can be referenced with `dial.payload`. The order of the field declarations determines the fields' memory-layout order. Every class has a member named `Self` equal to the class type itself. -Like functions, a class may be forward declared, ending the declaration with a +Like functions, classes may be forward declared, ending the declaration with a semicolon (`;`) instead of the block in curly braces (`{`...`}`). Both [structural data classes](#struct-types) and nominal classes are considered @@ -1298,7 +1306,7 @@ implemented in derived classes, even though it may not be called. Friends may be declared using a `friend` declaration inside the class naming an existing function or type. Unlike C++, `friend` declarations may only refer to -names resolvable to the compiler and don't act like forward declarations. +names resolvable by the compiler, and don't act like forward declarations. `protected` is like `private`, but also gives access to derived classes. @@ -1310,7 +1318,7 @@ names resolvable to the compiler and don't act like forward declarations. > - Proposal > [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) -A destructor for a class is a custom code executed when the lifetime of a value +A destructor for a class is custom code executed when the lifetime of a value of that type ends. They are defined with the `destructor` keyword followed by either `[me: Self]` or `[addr me: Self*]` (as is done with [methods](#methods)) and the block of code in the class definition, as in: @@ -1366,7 +1374,7 @@ having names inside the class' scope: A _choice type_ is a [tagged union](https://en.wikipedia.org/wiki/Tagged_union), that can store different types of data in a storage space that can hold the largest. A choice type has a name, and a list of cases separated by commas -(`,`). Each case has a name and a optional parameter list. +(`,`). Each case has a name and an optional parameter list. ```carbon choice IntResult { From 61b13917db556ce2b2548c676afe2f0093154bde Mon Sep 17 00:00:00 2001 From: Josh L Date: Sat, 21 May 2022 03:45:00 +0000 Subject: [PATCH 26/46] Fix formatting --- docs/design/README.md | 45 ++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index c9789261b38e9..9e779f72bebc4 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -369,8 +369,8 @@ are available for representing strings with `\`s and `"`s. > References: [Tuples](tuples.md) A tuple is a fixed-size collection of values that can have different types, -where each value is identified by its position in the tuple. An example use -of tuples is to return multiple values from a function: +where each value is identified by its position in the tuple. An example use of +tuples is to return multiple values from a function: ```carbon fn DoubleBoth(x: i32, y: i32) -> (i32, i32) { @@ -494,8 +494,8 @@ Console.Print(a[0]); > - Question-for-leads issue > [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) -Functions are the core unit of behavior. For example, this is a declaration -of a function that adds two 64-bit integers: +Functions are the core unit of behavior. For example, this is a declaration of a +function that adds two 64-bit integers: ```carbon fn Add(a: i64, b: i64) -> i64; @@ -510,13 +510,14 @@ Breaking this apart: You would call this function like `Add(1, 2)`. -A function definition is a function declaration that has a body block -instead of a semicolon: +A function definition is a function declaration that has a body block instead of +a semicolon: ```carbon fn Add(a: i64, b: i64) -> i64 { return a + b; } +``` ### Blocks and statements @@ -660,8 +661,8 @@ fn DoSomething() -> i64 { ``` The `let` binds `x` to the _value_ `42`. `x` is an r-value, so it can not be -modified, for example by being the left side of an assignment statement, -and its address cannot be taken. +modified, for example by being the left side of an assignment statement, and its +address cannot be taken. Function parameters are passed by value, and so act like they were defined in a `let` implicitly. **FIXME:** Is this just the default, or can you write `var` in @@ -692,9 +693,9 @@ var z: auto = (y > 1); ``` It may also be used as the return type in a function definition. In this case, -the body of the function must have exactly one `return` statement, and the return -type of the function is set to the static type of the expression argument of that -`return`. +the body of the function must have exactly one `return` statement, and the +return type of the function is set to the static type of the expression argument +of that `return`. ``` // Return type is inferred to be `bool`, the type of `a > 0`. @@ -770,8 +771,8 @@ described on the left-hand side of the assignment. `x |= y;`, `x ^= y;`, `x <<= y;`, `x >>= y;`. `x @= y;` is equivalent to `x = x @ y;` for each operator `@`. -Unlike C++, these assignments are statements, not expressions, and don't return a -value. +Unlike C++, these assignments are statements, not expressions, and don't return +a value. ### Control flow @@ -799,8 +800,8 @@ allows an individual statement without curly braces. > - Proposal > [#285: if/else](https://github.com/carbon-language/carbon-lang/pull/285) -`if` and `else` provide conditional execution of statements. An `if` -statement consists of: +`if` and `else` provide conditional execution of statements. An `if` statement +consists of: - An `if` introducer followed by a condition in parentheses. If the condition evaluates to `true`, the block following the condition is executed, @@ -993,11 +994,11 @@ This is instead of > [#1283: how should pattern matching and implicit conversion interact?](https://github.com/carbon-language/carbon-lang/issues/1283) `match` is a control flow similar to `switch` of C/C++ and mirrors similar -constructs in other languages, such as Swift. The `match` keyword is followed by an -expression in parentheses, whose value is matched against `case` declarations in order. The -code for the first matching `case` is executed. An optional `default` code block -may be placed after the `case` declaratoins, it will be executed if none of the -`case` declarations match. +constructs in other languages, such as Swift. The `match` keyword is followed by +an expression in parentheses, whose value is matched against `case` declarations +in order. The code for the first matching `case` is executed. An optional +`default` code block may be placed after the `case` declaratoins, it will be +executed if none of the `case` declarations match. An example `match` is: @@ -1318,8 +1319,8 @@ names resolvable by the compiler, and don't act like forward declarations. > - Proposal > [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) -A destructor for a class is custom code executed when the lifetime of a value -of that type ends. They are defined with the `destructor` keyword followed by +A destructor for a class is custom code executed when the lifetime of a value of +that type ends. They are defined with the `destructor` keyword followed by either `[me: Self]` or `[addr me: Self*]` (as is done with [methods](#methods)) and the block of code in the class definition, as in: From 5cf01f0bc2f98aa21a544380dcad0118936dea41 Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 23 May 2022 22:23:03 +0000 Subject: [PATCH 27/46] Move references to end of their section --- docs/design/README.md | 402 +++++++++++++++++++++--------------------- 1 file changed, 201 insertions(+), 201 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 9e779f72bebc4..6b1fb77b2f9c4 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -135,15 +135,6 @@ these types are strongly-typed as well. ## Code and comments -> References: -> -> - [Source files](code_and_name_organization/source_files.md) -> - [lexical conventions](lexical_conventions) -> - Proposal -> [#142: Unicode source files](https://github.com/carbon-language/carbon-lang/pull/142) -> - Proposal -> [#198: Comments](https://github.com/carbon-language/carbon-lang/pull/198) - All source code is UTF-8 encoded text. Comments, identifiers, and strings are allowed to have non-ASCII characters. @@ -158,6 +149,15 @@ required to be the only non-whitespace on the line. // Compute an approximation of π ``` +> References: +> +> - [Source files](code_and_name_organization/source_files.md) +> - [lexical conventions](lexical_conventions) +> - Proposal +> [#142: Unicode source files](https://github.com/carbon-language/carbon-lang/pull/142) +> - Proposal +> [#198: Comments](https://github.com/carbon-language/carbon-lang/pull/198) + ## Build modes The behavior of the Carbon compiler depends on the _build mode_: @@ -188,8 +188,6 @@ However, in simple cases this doesn't make much difference. ### Primitive types -> References: [Primitive types](primitive_types.md) - These types are fundamental to the language as they aren't either formed from or modifying other types. They also have semantics that are defined from first principles rather than in terms of other operations. These will be made @@ -202,6 +200,8 @@ Primitive types fall into the following categories: - IEEE-754 floating-point types, and - string types. +> References: [Primitive types](primitive_types.md) + #### `bool` The type `bool` is a boolean type with two possible values: `true` and `false`. @@ -212,15 +212,6 @@ and [`while`](#while), and #### Integer types -> References: -> -> - Question-for-leads issue -> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543) -> - Proposal -> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) -> - Proposal -> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) - The signed-integer type with bit width `N` may be written `Carbon.Int(N)`. For convenience and brevity, the common power-of-two sizes may be written with an `i` followed by the size: `i8`, `i16`, `i32`, `i64`, `i128`, or `i256`. @@ -248,17 +239,16 @@ Values which can never be negative, like sizes, but for which wrapping does not make sense [should use signed integer types](/proposals/p1083.md#dont-let-unsigned-arithmetic-wrap). -##### Integer literals - > References: > -> - [Integer literals](lexical_conventions/numeric_literals.md#integer-literals) -> - Proposal -> [#143: Numeric literals](https://github.com/carbon-language/carbon-lang/pull/143) -> - Proposal -> [#144: Numeric literal semantics](https://github.com/carbon-language/carbon-lang/pull/144) +> - Question-for-leads issue +> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543) > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> - Proposal +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) + +##### Integer literals Integers may be written in decimal, hexadecimal, or binary: @@ -275,35 +265,33 @@ numeric literals have a type derived from their value, and can be [implicitly converted](expressions/implicit_conversions.md) to any type that can represent that value. -#### Floating-point types - > References: > -> - Question-for-leads issue -> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543) +> - [Integer literals](lexical_conventions/numeric_literals.md#integer-literals) > - Proposal -> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> [#143: Numeric literals](https://github.com/carbon-language/carbon-lang/pull/143) > - Proposal -> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) +> [#144: Numeric literal semantics](https://github.com/carbon-language/carbon-lang/pull/144) +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) + +#### Floating-point types Floating-point types in Carbon have IEEE 754 semantics, use the round-to-nearest rounding mode, and do not set any floating-point exception state. They are named with an `f` and the number of bits: `f16`, `f32`, `f64`, and `f128`. [`BFloat16`](primitive_types.md#bfloat16) is also provided. -##### Floating-point literals - > References: > -> - [Real-number literals](lexical_conventions/numeric_literals.md#real-number-literals) -> - Proposal -> [#143: Numeric literals](https://github.com/carbon-language/carbon-lang/pull/143) -> - Proposal -> [#144: Numeric literal semantics](https://github.com/carbon-language/carbon-lang/pull/144) +> - Question-for-leads issue +> [#543: pick names for fixed-size integer types](https://github.com/carbon-language/carbon-lang/issues/543) > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) > - Proposal -> [#866: Allow ties in floating literals](https://github.com/carbon-language/carbon-lang/pull/866) +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) + +##### Floating-point literals Decimal and hexadecimal real-number literals are supported: @@ -317,6 +305,18 @@ type, its value is the representable real number closest to the value of the literal. In the case of a tie, the nearest value whose mantissa is even is selected. +> References: +> +> - [Real-number literals](lexical_conventions/numeric_literals.md#real-number-literals) +> - Proposal +> [#143: Numeric literals](https://github.com/carbon-language/carbon-lang/pull/143) +> - Proposal +> [#144: Numeric literal semantics](https://github.com/carbon-language/carbon-lang/pull/144) +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> - Proposal +> [#866: Allow ties in floating literals](https://github.com/carbon-language/carbon-lang/pull/866) + #### String types There are two string types: @@ -327,12 +327,6 @@ There are two string types: ##### String literals -> References: -> -> - [String literals](lexical_conventions/string_literals.md) -> - Proposal -> [#199: String literals](https://github.com/carbon-language/carbon-lang/pull/199) - String literals may be written on a single line using a double quotation mark (`"`) at the beginning and end of the string, as in `"example"`. @@ -360,14 +354,18 @@ introduced with a backslash (`\`). [Raw string literals](lexical_conventions/string_literals.md#raw-string-literals) are available for representing strings with `\`s and `"`s. +> References: +> +> - [String literals](lexical_conventions/string_literals.md) +> - Proposal +> [#199: String literals](https://github.com/carbon-language/carbon-lang/pull/199) + ### Composite types > **TODO:** Maybe rename to "structural types"? #### Tuples -> References: [Tuples](tuples.md) - A tuple is a fixed-size collection of values that can have different types, where each value is identified by its position in the tuple. An example use of tuples is to return multiple values from a function: @@ -397,6 +395,8 @@ fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { } ``` +> References: [Tuples](tuples.md) + #### Structural and nominal types Tuple types are _structural_, which means two tuple types are equal if they have @@ -406,16 +406,6 @@ names resolve to the same declaration. #### Struct types -> References: -> -> - [Struct types](classes.md#struct-types) -> - Proposal -> [#561: Basic classes: use cases, struct literals, struct types, and future work](https://github.com/carbon-language/carbon-lang/pull/561) -> - Proposal -> [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) -> - Proposal -> [#710: Default comparison for data classes](https://github.com/carbon-language/carbon-lang/issues/710) - The other [structural type](#structural-and-nominal-types) is called a _structural data class_, also known as a _struct type_ or _struct_. In contrast to a tuple, a struct's members are identified by name instead of position. @@ -430,14 +420,17 @@ both cases, they have a comma-separated list of members that start with a period literal_, the field name is followed by an equal sign (`=`) and the value, as in `{.key = "Joe", .count = 3}`. -#### Pointer types - > References: > -> - Question-for-leads issue -> [#520: should we use whitespace-sensitive operator fixity?](https://github.com/carbon-language/carbon-lang/issues/520) -> - Question-for-leads issue -> [#523: what syntax should we use for pointer types?](https://github.com/carbon-language/carbon-lang/issues/523) +> - [Struct types](classes.md#struct-types) +> - Proposal +> [#561: Basic classes: use cases, struct literals, struct types, and future work](https://github.com/carbon-language/carbon-lang/pull/561) +> - Proposal +> [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) +> - Proposal +> [#710: Default comparison for data classes](https://github.com/carbon-language/carbon-lang/issues/710) + +#### Pointer types The type of pointers-to-values-of-type-`T` is written `T*`. Carbon pointers do not support @@ -458,6 +451,13 @@ type `Optional(T*)`. In Carbon, one use of pointers is to pass `&x` into a function that will modify `x`. +> References: +> +> - Question-for-leads issue +> [#520: should we use whitespace-sensitive operator fixity?](https://github.com/carbon-language/carbon-lang/issues/520) +> - Question-for-leads issue +> [#523: what syntax should we use for pointer types?](https://github.com/carbon-language/carbon-lang/issues/523) + #### Arrays and slices The type of an array of holding 4 `i32` values is written `[i32; 4]`. There is @@ -484,16 +484,6 @@ Console.Print(a[0]); ## Functions -> References: -> -> - [Functions](functions.md) -> - Proposal -> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -> - Proposal -> [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438) -> - Question-for-leads issue -> [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) - Functions are the core unit of behavior. For example, this is a declaration of a function that adds two 64-bit integers: @@ -519,13 +509,17 @@ fn Add(a: i64, b: i64) -> i64 { } ``` -### Blocks and statements - > References: > -> - [Blocks and statements](blocks_and_statements.md) +> - [Functions](functions.md) > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438) +> - Question-for-leads issue +> [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) + +### Blocks and statements The body or definition of a function is provided by a block of code in curly braces (`{`...`}`) containing statements. The body of a function is also a new @@ -550,27 +544,13 @@ fn Foo() { } ``` -### Expressions - > References: > -> - [Expressions](expressions/) +> - [Blocks and statements](blocks_and_statements.md) > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -> - Proposal -> [#555: Operator precedence](https://github.com/carbon-language/carbon-lang/pull/555) -> - Proposal -> [#601: Operator tokens](https://github.com/carbon-language/carbon-lang/pull/601) -> - Proposal -> [#680: And, or, not](https://github.com/carbon-language/carbon-lang/pull/680) -> - Proposal -> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) -> - Proposal -> [#845: as expressions](https://github.com/carbon-language/carbon-lang/pull/845) -> - Proposal -> [#911: Conditional expressions](https://github.com/carbon-language/carbon-lang/pull/911) -> - Proposal -> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) + +### Expressions Expressions describe some computed value. The simplest example would be a literal number like `42`: an expression that computes the integer value 42. @@ -610,19 +590,27 @@ When an expression appears in a context in which an expression of a specific type is expected, [implicit conversions](expressions/implicit_conversions.md) are applied to convert the expression to the target type. -### Variables - > References: > -> - [Variables](variables.md) +> - [Expressions](expressions/) > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) > - Proposal -> [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) +> [#555: Operator precedence](https://github.com/carbon-language/carbon-lang/pull/555) > - Proposal -> [#339: Add `var [ = ];` syntax for variables](https://github.com/carbon-language/carbon-lang/pull/339) +> [#601: Operator tokens](https://github.com/carbon-language/carbon-lang/pull/601) > - Proposal -> [#618: var ordering](https://github.com/carbon-language/carbon-lang/pull/618) +> [#680: And, or, not](https://github.com/carbon-language/carbon-lang/pull/680) +> - Proposal +> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) +> - Proposal +> [#845: as expressions](https://github.com/carbon-language/carbon-lang/pull/845) +> - Proposal +> [#911: Conditional expressions](https://github.com/carbon-language/carbon-lang/pull/911) +> - Proposal +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) + +### Variables Blocks introduce nested scopes and can contain variable declarations that are local to that block, similarly to function parameters. @@ -648,6 +636,18 @@ Unlike function parameters, `x` is an [l-value](), which means it has storage and an address, and so can be modified. +> References: +> +> - [Variables](variables.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) +> - Proposal +> [#339: Add `var [ = ];` syntax for variables](https://github.com/carbon-language/carbon-lang/pull/339) +> - Proposal +> [#618: var ordering](https://github.com/carbon-language/carbon-lang/pull/618) + ### `let` To bind a name to a value without associating a specific storage location, use @@ -671,15 +671,6 @@ modified? ### `auto` -> References: -> -> - [Type inference](type_inference.md) -> - [Function return clause](functions.md#return-clause) -> - Proposal -> [#826: Function return type inference](https://github.com/carbon-language/carbon-lang/pull/826) -> - Proposal -> [#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851) - The keyword `auto` may be used in place of the type in a `var` or `let` statement in a function body. In this case, the type is the static type of the initializer expression. @@ -707,13 +698,16 @@ fn Positive(a: i64) -> auto { Note that `auto` is not allowed in a function declaration without a function body. -### Pattern matching - > References: > -> - [Pattern matching](pattern_matching.md) +> - [Type inference](type_inference.md) +> - [Function return clause](functions.md#return-clause) > - Proposal -> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> [#826: Function return type inference](https://github.com/carbon-language/carbon-lang/pull/826) +> - Proposal +> [#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851) + +### Pattern matching Patterns are used in a variety of Carbon language constructs, including [function parameters](#functions), [variable declarations](#variables), and @@ -755,6 +749,12 @@ the value is discarded. Additional kinds of patterns are allowed in [`match` statements](#match). +> References: +> +> - [Pattern matching](pattern_matching.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) + ### Assignment statements Assignment statements mutate the value of the @@ -776,14 +776,6 @@ a value. ### Control flow -> References: -> -> - [Control flow](control_flow/README.md) -> - Proposal -> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -> - Proposal -> [#623: Require braces](https://github.com/carbon-language/carbon-lang/pull/623) - Blocks of statements are generally executed sequentially. Control-flow statements give additional control over the flow of execution and which statements are executed. @@ -792,13 +784,15 @@ Some control-flow statements include [block](#blocks-and-statements) arguments. Those blocks will always be within curly braces `{`...`}`, unlike C++ which also allows an individual statement without curly braces. -#### `if` and `else` - > References: > -> - [Control flow](control_flow/conditionals.md) +> - [Control flow](control_flow/README.md) > - Proposal -> [#285: if/else](https://github.com/carbon-language/carbon-lang/pull/285) +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#623: Require braces](https://github.com/carbon-language/carbon-lang/pull/623) + +#### `if` and `else` `if` and `else` provide conditional execution of statements. An `if` statement consists of: @@ -831,18 +825,18 @@ This code will: `True`. - Print `Vegetable!` if both of the above return `False`. +> References: +> +> - [Control flow](control_flow/conditionals.md) +> - Proposal +> [#285: if/else](https://github.com/carbon-language/carbon-lang/pull/285) + #### Loops > References: [Loops](control_flow/loops.md) ##### `while` -> References: -> -> - [`while` loops](control_flow/loops.md#while) -> - Proposal -> [#340: Add C++-like `while` loops](https://github.com/carbon-language/carbon-lang/pull/340) - `while` statements loop for as long as the passed expression returns `true`. For example, this prints `0`, `1`, `2`, then `Done!`: @@ -855,13 +849,13 @@ while (x < 3) { Console.Print("Done!"); ``` -##### `for` - > References: > -> - [`for` loops](control_flow/loops.md#for) +> - [`while` loops](control_flow/loops.md#while) > - Proposal -> [#353: Add C++-like `for` loops](https://github.com/carbon-language/carbon-lang/pull/353) +> [#340: Add C++-like `while` loops](https://github.com/carbon-language/carbon-lang/pull/340) + +##### `for` `for` statements support range-based looping, typically over containers. For example, this prints all names in `names`: @@ -874,9 +868,13 @@ for (var name: String in names) { This prints each `String` value in `names`. -##### `break` +> References: +> +> - [`for` loops](control_flow/loops.md#for) +> - Proposal +> [#353: Add C++-like `for` loops](https://github.com/carbon-language/carbon-lang/pull/353) -> References: [`break`](control_flow/loops.md#break) +##### `break` The `break` statement immediately ends a `while` or `for` loop. Execution will continue starting from the end of the loop's scope. For example, this processes @@ -893,9 +891,9 @@ for (var step: Step in steps) { } ``` -##### `continue` +> References: [`break`](control_flow/loops.md#break) -> References: [`continue`](control_flow/loops.md#continue) +##### `continue` The `continue` statement immediately goes to the next loop of a `while` or `for`. In a `while`, execution continues with the `while` expression. For @@ -913,16 +911,9 @@ while (!f.EOF()) { } ``` -#### `return` +> References: [`continue`](control_flow/loops.md#continue) -> References: -> -> - [`return`](control_flow/return.md) -> - [`return` statements](functions.md#return-statements) -> - Proposal -> [#415: return](https://github.com/carbon-language/carbon-lang/pull/415) -> - Proposal -> [#538: return with no argument](https://github.com/carbon-language/carbon-lang/pull/538) +#### `return` The `return` statement ends the flow of execution within a function, returning execution to the caller. @@ -961,13 +952,16 @@ fn Sign(i: i32) -> i32 { Assert(Sign(-3) == -1); ``` -##### `returned var` - > References: > -> - [`returned var`](control_flow/return.md#returned-var) +> - [`return`](control_flow/return.md) +> - [`return` statements](functions.md#return-statements) > - Proposal -> [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) +> [#415: return](https://github.com/carbon-language/carbon-lang/pull/415) +> - Proposal +> [#538: return with no argument](https://github.com/carbon-language/carbon-lang/pull/538) + +##### `returned var` To avoid a copy when returning a variable, add a `returned` prefix to the variable's declaration and use `return var` instead of returning an expression, @@ -985,13 +979,13 @@ fn MakeCircle(radius: i32) -> Circle { This is instead of [the "named return value optimization" of C++](https://en.wikipedia.org/wiki/Copy_elision#Return_value_optimization). -#### `match` - > References: > -> - [Pattern matching](pattern_matching.md) -> - Question-for-leads issue -> [#1283: how should pattern matching and implicit conversion interact?](https://github.com/carbon-language/carbon-lang/issues/1283) +> - [`returned var`](control_flow/return.md#returned-var) +> - Proposal +> [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) + +#### `match` `match` is a control flow similar to `switch` of C/C++ and mirrors similar constructs in other languages, such as Swift. The `match` keyword is followed by @@ -1034,20 +1028,18 @@ contain patterns that may or may not match based on the runtime value of the the pattern like `if (p < 13)`, matches if the predicate evaluates to `true`. +> References: +> +> - [Pattern matching](pattern_matching.md) +> - Question-for-leads issue +> [#1283: how should pattern matching and implicit conversion interact?](https://github.com/carbon-language/carbon-lang/issues/1283) + ## User-defined types > **TODO:** Maybe rename to "nominal types"? ### Classes -> References: -> -> - [Classes](classes.md#nominal-class-types) -> - Proposal -> [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722) -> - Proposal -> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) - _Nominal classes_, or just _classes_, are a way for users to define their own data strutures or record types. @@ -1082,12 +1074,15 @@ respectively when that is not confusing. Like structs, classes refer to their members by name. Unlike structs, classes are [nominal types](#structural-and-nominal-types). -#### Assignment, copying - -> References: [Classes](classes.md#construction) +> References: > +> - [Classes](classes.md#nominal-class-types) > - Proposal -> [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) +> [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722) +> - Proposal +> [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) + +#### Assignment, copying You may use a [struct literal](#struct-types), to assign or initialize a variable with a class type in any scope that has [access](#access-control) to @@ -1106,6 +1101,11 @@ sprocket = thingy; Assert(sprocket.x == thingy.x); ``` +> References: [Classes](classes.md#construction) +> +> - Proposal +> [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) + #### Class functions and factory functions Classes may also contain functions as members of the type. This is commonly used @@ -1148,12 +1148,6 @@ This approach can also be used for types that can't be copied or moved. #### Methods -> References: -> -> - [Methods](classes.md#methods) -> - Proposal -> [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722) - Class type definitions can include methods: ```carbon @@ -1199,15 +1193,13 @@ two methods `Distance` and `Offset`: - Methods may be declared lexically inline like `Distance`, or lexically out of line like `Offset`. -#### Inheritance - > References: > -> - [Inheritance](classes.md#inheritance) -> - Proposal -> [#777: Inheritance](https://github.com/carbon-language/carbon-lang/pull/777) +> - [Methods](classes.md#methods) > - Proposal -> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) +> [#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722) + +#### Inheritance Classes by default are [_final_](), @@ -1290,15 +1282,15 @@ class DerivedFromAbstract extends AbstractClass { } ``` -#### Access control - > References: > -> - [Access control for class members](classes.md#access-control) -> - Question-for-leads issue -> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665) -> - Question-for-leads issue -> [#971: Private interfaces in public API files](https://github.com/carbon-language/carbon-lang/issues/971) +> - [Inheritance](classes.md#inheritance) +> - Proposal +> [#777: Inheritance](https://github.com/carbon-language/carbon-lang/pull/777) +> - Proposal +> [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) + +#### Access control Class members are by default publicly accessible. The `private` keyword prefix can be added to the member's declaration to restrict it to members of the class @@ -1311,13 +1303,15 @@ names resolvable by the compiler, and don't act like forward declarations. `protected` is like `private`, but also gives access to derived classes. -#### Destructors - > References: > -> - [Destructors](classes.md#destructors) -> - Proposal -> [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) +> - [Access control for class members](classes.md#access-control) +> - Question-for-leads issue +> [#665: `private` vs `public` _syntax_ strategy, as well as other visibility tools like `external`/`api`/etc.](https://github.com/carbon-language/carbon-lang/issues/665) +> - Question-for-leads issue +> [#971: Private interfaces in public API files](https://github.com/carbon-language/carbon-lang/issues/971) + +#### Destructors A destructor for a class is custom code executed when the lifetime of a value of that type ends. They are defined with the `destructor` keyword followed by @@ -1351,6 +1345,12 @@ the base class is declared `virtual` or `impl`. To delete a pointer to a non-abstract base class when it is known not to point to a value with a derived type, use `UnsafeDelete`. +> References: +> +> - [Destructors](classes.md#destructors) +> - Proposal +> [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) + #### Other members Classes may also contain other kinds of declarations, which results in them @@ -1365,13 +1365,6 @@ having names inside the class' scope: ### Choice types -> References: -> -> - Proposal -> [#157: Design direction for sum types](https://github.com/carbon-language/carbon-lang/pull/157) -> - Proposal -> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) - A _choice type_ is a [tagged union](https://en.wikipedia.org/wiki/Tagged_union), that can store different types of data in a storage space that can hold the largest. A choice type has a name, and a list of cases separated by commas @@ -1427,6 +1420,13 @@ additional data is associated with the choices, as in: choice LikeABoolean { False, True } ``` +> References: +> +> - Proposal +> [#157: Design direction for sum types](https://github.com/carbon-language/carbon-lang/pull/157) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) + ## Names ### Packages, libraries, namespaces From b60288c7e59d40bbf1af53f9bd0f88e622e29902 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 24 May 2022 19:05:37 +0000 Subject: [PATCH 28/46] Implement suggestions from review --- docs/design/README.md | 131 ++++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 68 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 6b1fb77b2f9c4..90fd71ae44e98 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -11,25 +11,25 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ## Table of contents - [Overview](#overview) - - [A note on example code](#a-note-on-example-code) + - [This document is provisional](#this-document-is-provisional) - [Hello, Carbon](#hello-carbon) - [Code and comments](#code-and-comments) - [Build modes](#build-modes) -- [Types](#types) - - [Primitive types](#primitive-types) - - [`bool`](#bool) - - [Integer types](#integer-types) - - [Integer literals](#integer-literals) - - [Floating-point types](#floating-point-types) - - [Floating-point literals](#floating-point-literals) - - [String types](#string-types) - - [String literals](#string-literals) - - [Composite types](#composite-types) - - [Tuples](#tuples) - - [Structural and nominal types](#structural-and-nominal-types) - - [Struct types](#struct-types) - - [Pointer types](#pointer-types) - - [Arrays and slices](#arrays-and-slices) +- [Types are values](#types-are-values) + - [Structural and nominal types](#structural-and-nominal-types) +- [Primitive types](#primitive-types) + - [`bool`](#bool) + - [Integer types](#integer-types) + - [Integer literals](#integer-literals) + - [Floating-point types](#floating-point-types) + - [Floating-point literals](#floating-point-literals) + - [String types](#string-types) + - [String literals](#string-literals) +- [Composite types](#composite-types) + - [Tuples](#tuples) + - [Struct types](#struct-types) + - [Pointer types](#pointer-types) + - [Arrays and slices](#arrays-and-slices) - [Functions](#functions) - [Blocks and statements](#blocks-and-statements) - [Expressions](#expressions) @@ -100,10 +100,12 @@ This document is _not_ a complete programming manual, and, nor does it provide detailed and comprehensive justification for design decisions. These descriptions are found in linked dedicated designs. -### A note on example code +### This document is provisional -Some syntax used in example code is provisional or placeholder, and may change -later. +This document includes much that is provisional or placeholder. This means that +the syntax used, language rules, standard library, and other aspects of the +design have things that have not been decided through the Carbon process. This +preliminary material fills in gaps until aspects of the design can be filled in. ## Hello, Carbon @@ -169,28 +171,27 @@ The behavior of the Carbon compiler depends on the _build mode_: - In a _hardened build_, the first priority is safety and second is performance. -## Types +> References: [Safety strategy](/docs/project/principles/safety_strategy.md) -Carbon's core types are broken down into three categories: - -- Primitive types -- Composite types -- [User-defined types](#user-defined-types) - -The first two are intrinsic and directly built in the language and are discussed -in this section. The last category of types allows for defining new types, and -is described [later](#user-defined-types). +## Types are values Expressions compute values in Carbon, and these values are always strongly typed much like in C++. However, an important difference from C++ is that types are themselves modeled as values; specifically, compile-time constant values. However, in simple cases this doesn't make much difference. -### Primitive types +### Structural and nominal types + +Some types are _structural_, which means they are equal if they have the same +components. This is in contrast to _nominal_ types that have a name that +identifies a specific declaration. Two nominal types are equal if their names +resolve to the same declaration. If a nominal type is [generic](#generics), and +so has parameters, then the parameters must also be equal for the types to be +equal. + +## Primitive types -These types are fundamental to the language as they aren't either formed from or -modifying other types. They also have semantics that are defined from first -principles rather than in terms of other operations. These will be made +Some types are used as the building blocks for other types and are made available through the [prelude package](#name-lookup-for-common-types). Primitive types fall into the following categories: @@ -202,7 +203,7 @@ Primitive types fall into the following categories: > References: [Primitive types](primitive_types.md) -#### `bool` +### `bool` The type `bool` is a boolean type with two possible values: `true` and `false`. [Comparison expressions](#expressions) produce `bool` values. The condition @@ -210,7 +211,7 @@ arguments in [control-flow statements](#control-flow), like [`if`](#if-and-else) and [`while`](#while), and [`if`-`then`-`else` conditional expressions](#expressions) take `bool` values. -#### Integer types +### Integer types The signed-integer type with bit width `N` may be written `Carbon.Int(N)`. For convenience and brevity, the common power-of-two sizes may be written with an @@ -248,7 +249,7 @@ make sense > - Proposal > [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) -##### Integer literals +#### Integer literals Integers may be written in decimal, hexadecimal, or binary: @@ -256,9 +257,10 @@ Integers may be written in decimal, hexadecimal, or binary: - `0x1FE` (hexadecimal) - `0b1010` (binary) -Underscores `_` may be as a digit separator, but only in conventional locations. -Numeric literals are case-sensitive: `0x`, `0b` must be lowercase, whereas -hexadecimal digits must be uppercase. Integer literals never contain a `.`. +Underscores `_` may be as a digit separator, but for decimal and hexadecimal +literals, they can only appear in conventional locations. Numeric literals are +case-sensitive: `0x`, `0b` must be lowercase, whereas hexadecimal digits must be +uppercase. Integer literals never contain a `.`. Unlike in C++, literals do not have a suffix to indicate their type. Instead, numeric literals have a type derived from their value, and can be @@ -275,7 +277,7 @@ represent that value. > - Proposal > [#820: Implicit conversions](https://github.com/carbon-language/carbon-lang/pull/820) -#### Floating-point types +### Floating-point types Floating-point types in Carbon have IEEE 754 semantics, use the round-to-nearest rounding mode, and do not set any floating-point exception state. They are named @@ -291,7 +293,7 @@ with an `f` and the number of bits: `f16`, `f32`, `f64`, and `f128`. > - Proposal > [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) -##### Floating-point literals +#### Floating-point literals Decimal and hexadecimal real-number literals are supported: @@ -317,7 +319,7 @@ selected. > - Proposal > [#866: Allow ties in floating literals](https://github.com/carbon-language/carbon-lang/pull/866) -#### String types +### String types There are two string types: @@ -325,7 +327,7 @@ There are two string types: - `StringView` - a read-only reference to a byte sequence treated as containing UTF-8 encoded text. -##### String literals +#### String literals String literals may be written on a single line using a double quotation mark (`"`) at the beginning and end of the string, as in `"example"`. @@ -360,11 +362,9 @@ are available for representing strings with `\`s and `"`s. > - Proposal > [#199: String literals](https://github.com/carbon-language/carbon-lang/pull/199) -### Composite types +## Composite types -> **TODO:** Maybe rename to "structural types"? - -#### Tuples +### Tuples A tuple is a fixed-size collection of values that can have different types, where each value is identified by its position in the tuple. An example use of @@ -395,20 +395,15 @@ fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { } ``` -> References: [Tuples](tuples.md) - -#### Structural and nominal types +Tuple types are [structural](#structural-and-nominal-types). -Tuple types are _structural_, which means two tuple types are equal if they have -the same components. This is in contrast to _nominal_ types that have a name -that identifies a specific declaration. Two nominal types are equal if their -names resolve to the same declaration. +> References: [Tuples](tuples.md) -#### Struct types +### Struct types -The other [structural type](#structural-and-nominal-types) is called a -_structural data class_, also known as a _struct type_ or _struct_. In contrast -to a tuple, a struct's members are identified by name instead of position. +Carbon also has [structural types](#structural-and-nominal-types) whose members +are identified by name instead of position. These are called _structural data +classes_, also known as a _struct types_ or _structs_. Both struct types and values are written inside curly braces (`{`...`}`). In both cases, they have a comma-separated list of members that start with a period @@ -430,7 +425,7 @@ both cases, they have a comma-separated list of members that start with a period > - Proposal > [#710: Default comparison for data classes](https://github.com/carbon-language/carbon-lang/issues/710) -#### Pointer types +### Pointer types The type of pointers-to-values-of-type-`T` is written `T*`. Carbon pointers do not support @@ -448,8 +443,8 @@ There are no [null pointers](https://en.wikipedia.org/wiki/Null_pointer) in Carbon. To represent a pointer that may not refer to a valid object, use the type `Optional(T*)`. -In Carbon, one use of pointers is to pass `&x` into a function that will modify -`x`. +Pointers are the main Carbon mechanism for allowing a function to modify a +variable of the caller. > References: > @@ -458,7 +453,7 @@ In Carbon, one use of pointers is to pass `&x` into a function that will modify > - Question-for-leads issue > [#523: what syntax should we use for pointer types?](https://github.com/carbon-language/carbon-lang/issues/523) -#### Arrays and slices +### Arrays and slices The type of an array of holding 4 `i32` values is written `[i32; 4]`. There is an [implicit conversion](expressions/implicit_conversions.md) from tuples to @@ -581,7 +576,7 @@ Some common expressions in Carbon include: `not e` - Indexing: `a[3]` - Function call: `f(4)` - - Pointer and member: `*p`, `x.m`, `p->m`, `&x` + - Pointer: `*p`, `p->m`, `&x` - [Conditionals](expressions/if.md): `if c then t else f` - Parentheses: `(7 + 8) * (3 - 1)` @@ -820,10 +815,10 @@ if (fruit.IsYellow()) { This code will: -- Print `Banana!` if `fruit.IsYellow()` is `True`. -- Print `Orange!` if `fruit.IsYellow()` is `False` and `fruit.IsOrange()` is - `True`. -- Print `Vegetable!` if both of the above return `False`. +- Print `Banana!` if `fruit.IsYellow()` is `true`. +- Print `Orange!` if `fruit.IsYellow()` is `false` and `fruit.IsOrange()` is + `true`. +- Print `Vegetable!` if both of the above return `false`. > References: > @@ -1063,7 +1058,7 @@ Breaking apart `Widget`: The order of the field declarations determines the fields' memory-layout order. -Every class has a member named `Self` equal to the class type itself. +Every class has a constant member named `Self` equal to the class type itself. Like functions, classes may be forward declared, ending the declaration with a semicolon (`;`) instead of the block in curly braces (`{`...`}`). From 45c1277ac135e32c303b72552ca8fc64a205b26e Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 24 May 2022 20:52:37 +0000 Subject: [PATCH 29/46] Implement suggestions from review --- docs/design/README.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 90fd71ae44e98..047b5eda582d2 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1079,16 +1079,17 @@ members by name. Unlike structs, classes are #### Assignment, copying -You may use a [struct literal](#struct-types), to assign or initialize a -variable with a class type in any scope that has [access](#access-control) to -all of its fields, as in: +There is an [implicit conversions](expressions/implicit_conversions.md) defined +between a [struct literal](#struct-types) and a class type with the same fields, +in any scope that has [access](#access-control) to all of the class' fields. +This may be used to assign or initialize a variable with a class type, as in: ```carbon var sprocket: Widget = {.x = 3, .y = 4, .z = 5, .payload = "Sproing"}; sprocket = {.x = 2, .y = 1, .z = 0, .payload = "Bounce"}; ``` -You may also copy one struct into another of the same type. +You may also copy a value of a class type into a variable of the same type. ```carbon var thingy: Widget = sprocket; @@ -1096,15 +1097,20 @@ sprocket = thingy; Assert(sprocket.x == thingy.x); ``` -> References: [Classes](classes.md#construction) +> References: > +> - [Classes: Construction](classes.md#construction) > - Proposal > [#981: Implicit conversions for aggregates](https://github.com/carbon-language/carbon-lang/pull/981) #### Class functions and factory functions -Classes may also contain functions as members of the type. This is commonly used -to define a function that creates instances. Carbon does not have separate +Classes may also contain _class functions_. These are functions that are +accessed as members of the type, like +[static member functions in C++](), +as opposed to [methods](#methods) that are members of instances. They are +commonly used to define a function that creates instances. Carbon does not have +separate [constructors]() like C++ does. From 918d2ec30380f6cfd783e8a9d679cf00761b6207 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 24 May 2022 20:57:38 +0000 Subject: [PATCH 30/46] Implement suggestions from review --- docs/design/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/design/README.md b/docs/design/README.md index 047b5eda582d2..ec3c01bb1fd3c 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1537,7 +1537,8 @@ textually after this can refer to `MyInt`, and it will transparently refer to > > **TODO:** References need to be evolved. -Unqualified name lookup will always find a file-local result, including aliases. +Unqualified name lookup will always find a file-local result, including aliases, +or names that are defined as part of the prelude. #### Name lookup for common types From bed9f424e1cdc930f3bed128369f29cbfefe35b6 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 26 May 2022 00:39:18 +0000 Subject: [PATCH 31/46] Implement suggestions from review --- docs/design/README.md | 183 ++++++++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 79 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index ec3c01bb1fd3c..54a589b431767 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -30,9 +30,10 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Struct types](#struct-types) - [Pointer types](#pointer-types) - [Arrays and slices](#arrays-and-slices) +- [Expressions](#expressions) +- [Declarations, Definitions, and Scopes](#declarations-definitions-and-scopes) - [Functions](#functions) - [Blocks and statements](#blocks-and-statements) - - [Expressions](#expressions) - [Variables](#variables) - [`let`](#let) - [`auto`](#auto) @@ -177,15 +178,17 @@ The behavior of the Carbon compiler depends on the _build mode_: Expressions compute values in Carbon, and these values are always strongly typed much like in C++. However, an important difference from C++ is that types are -themselves modeled as values; specifically, compile-time constant values. -However, in simple cases this doesn't make much difference. +themselves modeled as values; specifically, compile-time constant values. This +means that the grammar for writing a type is the expression](#expressions) +grammar. Expressions written where a type is expected must be able to be +evaluated at compile-time and must evaluate to a type value. ### Structural and nominal types Some types are _structural_, which means they are equal if they have the same components. This is in contrast to _nominal_ types that have a name that -identifies a specific declaration. Two nominal types are equal if their names -resolve to the same declaration. If a nominal type is [generic](#generics), and +identifies a specific definition. Two nominal types are equal if their names +resolve to the same definition. If a nominal type is [generic](#generics), and so has parameters, then the parameters must also be equal for the types to be equal. @@ -477,6 +480,71 @@ Console.Print(a[0]); > **TODO:** Slices +## Expressions + +Expressions describe some computed value. The simplest example would be a +literal number like `42`: an expression that computes the integer value 42. + +Some common expressions in Carbon include: + +- Literals: + + - [boolean](#bool): `true`, `false` + - [integer](#integer-literals): `42`, `-7` + - [real-number](#floating-point-literals): `3.1419`, `6.022e+23` + - [string](#string-literals): `"Hello World!"` + - [tuple](#tuples): `(1, 2, 3)` + - [struct](#struct-types): `{.word = "the", .count = 56}` + +- [Names](#names) and [member access](expressions/member_access.md) + +- [Operators](expressions#operators): + + - [Arithmetic](expressions/arithmetic.md): `-x`, `1 + 2`, `3 - 4`, + `2 * 5`, `6 / 3`, `5 % 3` + - [Bitwise](expressions/bitwise.md): `2 & 3`, `2 | 4`, `3 ^ 1`, `^7` + - [Bit shift](expressions/bitwise.md): `1 << 3`, `8 >> 1` + - [Comparison](expressions/comparison_operators.md): `2 == 2`, `3 != 4`, + `5 < 6`, `7 > 6`, `8 <= 8`, `8 >= 8` + - [Conversion](expressions/as_expressions.md): `2 as i32` + - [Logical](expressions/logical_operators.md): `a and b`, `c or d`, + `not e` + - [Indexing](#arrays-and-slices): `a[3]` + - [Function](#functions) call: `f(4)` + - [Pointer](#pointer-types): `*p`, `p->m`, `&x` + +- [Conditionals](expressions/if.md): `if c then t else f` +- Parentheses: `(7 + 8) * (3 - 1)` + +When an expression appears in a context in which an expression of a specific +type is expected, [implicit conversions](expressions/implicit_conversions.md) +are applied to convert the expression to the target type. + +> References: +> +> - [Expressions](expressions/) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#555: Operator precedence](https://github.com/carbon-language/carbon-lang/pull/555) +> - Proposal +> [#601: Operator tokens](https://github.com/carbon-language/carbon-lang/pull/601) +> - Proposal +> [#680: And, or, not](https://github.com/carbon-language/carbon-lang/pull/680) +> - Proposal +> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) +> - Proposal +> [#845: as expressions](https://github.com/carbon-language/carbon-lang/pull/845) +> - Proposal +> [#911: Conditional expressions](https://github.com/carbon-language/carbon-lang/pull/911) +> - Proposal +> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) + +## Declarations, Definitions, and Scopes + +**FIXME**: Content needed here. +[Scope]() + ## Functions Functions are the core unit of behavior. For example, this is a declaration of a @@ -516,19 +584,25 @@ fn Add(a: i64, b: i64) -> i64 { ### Blocks and statements -The body or definition of a function is provided by a block of code in curly -braces (`{`...`}`) containing statements. The body of a function is also a new -scope nested inside the function's scope. Nested here means that parameter names -from the function's scope are available in addition to any names introduced in -the function body. +A _code block_ or _block_ is a sequence of _statements_. Blocks define a +[scope](#declarations-definitions-and-scopes) and, like other scopes, is +enclosed in curly braces (`{`...`}`). Each statement is terminated by a +semicolon, and can be one of: -Statements within a block are terminated by a semicolon. Each statement can, -among other things, be an expression. Some -[control-flow statements](#control-flow) have their own blocks of code. These -are nested within the enclosing scope. +- an [expression](#expressions), +- a [variable declaration](#variables), +- a [`let` declaration](#let), +- an [assignment statement](#assignment-statements), or +- a [control-flow statement](#control-flow). -For example, here is a function definition with a block of statements defining -the body of the function, and a nested block as part of a `while` statement: +Statements within a block are normally executed in the order the appear in the +source code, except when modified by control-flow statements. + +The body of a function is defined by a block, and some +[control-flow statements](#control-flow) have their own blocks of code. These +are nested within the enclosing scope. For example, here is a function +definition with a block of statements defining the body of the function, and a +nested block as part of a `while` statement: ```carbon fn Foo() { @@ -545,66 +619,6 @@ fn Foo() { > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -### Expressions - -Expressions describe some computed value. The simplest example would be a -literal number like `42`: an expression that computes the integer value 42. - -Some common expressions in Carbon include: - -- Literals: - - - [boolean](#bool): `true`, `false` - - [integer](#integer-literals): `42`, `-7` - - [real-number](#floating-point-literals): `3.1419`, `6.022e+23` - - [string](#string-literals): `"Hello World!"` - - [tuple](#tuples): `(1, 2, 3)` - - [struct](#struct-types): `{.word = "the", .count = 56}` - -- [Names](#names) and [member access](expressions/member_access.md) - -- [Operators](expressions#operators): - - - [Arithmetic](expressions/arithmetic.md): `-x`, `1 + 2`, `3 - 4`, - `2 * 5`, `6 / 3`, `5 % 3` - - [Bitwise](expressions/bitwise.md): `2 & 3`, `2 | 4`, `3 ^ 1`, `^7` - - [Bit shift](expressions/bitwise.md): `1 << 3`, `8 >> 1` - - [Comparison](expressions/comparison_operators.md): `2 == 2`, `3 != 4`, - `5 < 6`, `7 > 6`, `8 <= 8`, `8 >= 8` - - [Conversion](expressions/as_expressions.md): `2 as i32` - - [Logical](expressions/logical_operators.md): `a and b`, `c or d`, - `not e` - - Indexing: `a[3]` - - Function call: `f(4)` - - Pointer: `*p`, `p->m`, `&x` - -- [Conditionals](expressions/if.md): `if c then t else f` -- Parentheses: `(7 + 8) * (3 - 1)` - -When an expression appears in a context in which an expression of a specific -type is expected, [implicit conversions](expressions/implicit_conversions.md) -are applied to convert the expression to the target type. - -> References: -> -> - [Expressions](expressions/) -> - Proposal -> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -> - Proposal -> [#555: Operator precedence](https://github.com/carbon-language/carbon-lang/pull/555) -> - Proposal -> [#601: Operator tokens](https://github.com/carbon-language/carbon-lang/pull/601) -> - Proposal -> [#680: And, or, not](https://github.com/carbon-language/carbon-lang/pull/680) -> - Proposal -> [#702: Comparison operators](https://github.com/carbon-language/carbon-lang/pull/702) -> - Proposal -> [#845: as expressions](https://github.com/carbon-language/carbon-lang/pull/845) -> - Proposal -> [#911: Conditional expressions](https://github.com/carbon-language/carbon-lang/pull/911) -> - Proposal -> [#1083: Arithmetic expressions](https://github.com/carbon-language/carbon-lang/pull/1083) - ### Variables Blocks introduce nested scopes and can contain variable declarations that are @@ -775,9 +789,20 @@ Blocks of statements are generally executed sequentially. Control-flow statements give additional control over the flow of execution and which statements are executed. -Some control-flow statements include [block](#blocks-and-statements) arguments. -Those blocks will always be within curly braces `{`...`}`, unlike C++ which also -allows an individual statement without curly braces. +Some control-flow statements include [blocks](#blocks-and-statements). Those +blocks will always be within curly braces `{`...`}`. + +```carbon +// Curly braces { ... } are required. +if (condition) { + ExecutedWhenTrue(); +} else { + ExecutedWhenFalse(); +} +``` + +This is unlike C++, which allows control-flow constructs to omit curly braces +around a single statement. > References: > From ebd577a0aea9995fa0c0812b0e35ffc7f568eefd Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 26 May 2022 01:29:04 +0000 Subject: [PATCH 32/46] Fill in declarations & scope section --- docs/design/README.md | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 54a589b431767..f8e6604961078 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -61,7 +61,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Choice types](#choice-types) - [Names](#names) - [Packages, libraries, namespaces](#packages-libraries-namespaces) - - [Names and scopes](#names-and-scopes) + - [Legal names](#legal-names) - [Naming conventions](#naming-conventions) - [Aliases](#aliases) - [Name lookup](#name-lookup) @@ -542,13 +542,24 @@ are applied to convert the expression to the target type. ## Declarations, Definitions, and Scopes -**FIXME**: Content needed here. -[Scope]() +_Declarations_ introduce a new [name](#names) and say what that name represents. +For some kinds of entities, like [functions](#functions), there are two kinds of +declarations: _forward declarations_ and _definitions_. In this case, there +should be exactly one definition for the name, but there can be additional +forward declarations that introduce the name before it is defined. Forward +declarations allow cyclic references, and can be used to declare a name in an +[api file](#packages-libraries-namespaces) that is defined in an +[impl file](#packages-libraries-namespaces). + +A name is valid until the end of the innermost enclosing +[_scope_](). Except for +the outermost scope, scopes are enclosed in curly braces (`{`...`}`). ## Functions -Functions are the core unit of behavior. For example, this is a declaration of a -function that adds two 64-bit integers: +Functions are the core unit of behavior. For example, this is a +[declaration](#declarations-definitions-and-scopes) of a function that adds two +64-bit integers: ```carbon fn Add(a: i64, b: i64) -> i64; @@ -1495,18 +1506,18 @@ import Geometry library("OneSide"); fn Foo(Geometry.Shapes.Flat.Circle circle) { ... } ``` -### Names and scopes +### Legal names > References: [Lexical conventions](lexical_conventions) > > **TODO:** References need to be evolved. Various constructs introduce a named entity in Carbon. These can be functions, -types, variables, or other kinds of entities that we'll cover. A name in Carbon -is formed from a word, which is a sequence of letters, numbers, and underscores, -and which starts with a letter. We intend to follow Unicode's Annex 31 in -selecting valid identifier characters, but a concrete set of valid characters -has not been selected yet. +types, variables, or other kinds of entities. A name in Carbon is formed from a +word, which is a sequence of letters, numbers, and underscores, and which starts +with a letter. We intend to follow Unicode's Annex 31 in selecting valid +identifier characters, but a concrete set of valid characters has not been +selected yet. ### Naming conventions From 0d194d9861f19a6f1fbe27f1fdf86cebb990144a Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 26 May 2022 19:19:00 +0000 Subject: [PATCH 33/46] Checkpoint progress. --- docs/design/README.md | 66 +++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 25 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index f8e6604961078..6f56d06a2aa88 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -57,7 +57,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Inheritance](#inheritance) - [Access control](#access-control) - [Destructors](#destructors) - - [Other members](#other-members) - [Choice types](#choice-types) - [Names](#names) - [Packages, libraries, namespaces](#packages-libraries-namespaces) @@ -568,7 +567,8 @@ fn Add(a: i64, b: i64) -> i64; Breaking this apart: - `fn` is the keyword used to introduce a function. -- Its name is `Add`. +- Its name is `Add`. This is the name added to the enclosing + [scope](#declarations-definitions-and-scopes). - It accepts two `i64` parameters, `a` and `b`. - It returns an `i64` result. @@ -583,6 +583,9 @@ fn Add(a: i64, b: i64) -> i64 { } ``` +The names of the parameters are in scope until the end of the definition or +declaration. + > References: > > - [Functions](functions.md) @@ -632,8 +635,9 @@ fn Foo() { ### Variables -Blocks introduce nested scopes and can contain variable declarations that are -local to that block, similarly to function parameters. +Blocks introduce nested scopes and can contain variable +[declarations](#declarations-definitions-and-scopes) that are local to that +block, similarly to function parameters. For example: @@ -648,7 +652,8 @@ fn DoSomething() -> i64 { Breaking this apart: - `var` is the keyword used to indicate a variable. -- Its name is `x`. +- Its name is `x`. This is the name added to the enclosing + [scope](#declarations-definitions-and-scopes). - Its type is `i64`. - It is initialized with the value `42`. @@ -656,6 +661,9 @@ Unlike function parameters, `x` is an [l-value](), which means it has storage and an address, and so can be modified. +Note that there are no forward declarations of variables, all variable +declarations are [definitions](#declarations-definitions-and-scopes). + > References: > > - [Variables](variables.md) @@ -1071,10 +1079,14 @@ contain patterns that may or may not match based on the runtime value of the ### Classes -_Nominal classes_, or just _classes_, are a way for users to define their own -data strutures or record types. +_Nominal classes_, or just +[_classes_](), are a +way for users to define their own +[data strutures](https://en.wikipedia.org/wiki/Data_structure) or +[record types](). -For example: +This is an example of a class +[definition](#declarations-definitions-and-scopes): ```carbon class Widget { @@ -1086,18 +1098,34 @@ class Widget { } ``` -Breaking apart `Widget`: +Breaking this apart: -- `Widget` has three `i32` field: `x`, `y`, and `z`. +- This defines a class named `Widget`. `Widget` is the name added to the + enclosing [scope](#declarations-definitions-and-scopes). +- The name `Widget` is followed by curly braces (`{`...`}`), making this a + [definition](#declarations-definitions-and-scopes). A + [forward declaration](#declarations-definitions-and-scopes) would instead + have a semicolon(`;`). +- Those braces delimit the class' + [scope](#declarations-definitions-and-scopes). +- `Widget` has three `i32` fields: `x`, `y`, and `z`. - `Widget` has one `String` field: `payload`. - Given an instance `dial`, a field can be referenced with `dial.payload`. The order of the field declarations determines the fields' memory-layout order. -Every class has a constant member named `Self` equal to the class type itself. +Classes may have other kinds of members beyond fields declared in a class scope: -Like functions, classes may be forward declared, ending the declaration with a -semicolon (`;`) instead of the block in curly braces (`{`...`}`). +- [Class functions](#class-functions-and-factory-functions) +- [Methods](#methods) +- [`alias`](#aliases) +- [`let`](#let) to define constants. **TODO:** Are these constants associated + with the class or the instance? Do we need to another syntax to distinguish + constants associated with the class like `class let` or `static let`? +- `class`, to define a + [_member class_ or _nested class_](https://en.wikipedia.org/wiki/Inner_class) +- Every class has a constant member named `Self` equal to the class type + itself. Both [structural data classes](#struct-types) and nominal classes are considered _class types_, but they are commonly referred to as "structs" and "classes" @@ -1388,18 +1416,6 @@ type, use `UnsafeDelete`. > - Proposal > [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) -#### Other members - -Classes may also contain other kinds of declarations, which results in them -having names inside the class' scope: - -- [`alias`](#aliases) -- [`let`](#let) to define constants. **TODO:** Are these constants associated - with the class or the instance? Do we need to another syntax to distinguish - constants associated with the class like `class let` or `static let`? -- `class`, to define a - [_member class_ or _nested class_](https://en.wikipedia.org/wiki/Inner_class) - ### Choice types A _choice type_ is a [tagged union](https://en.wikipedia.org/wiki/Tagged_union), From 6da19d11179ed94013167985b64aa2957a21cad4 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 26 May 2022 20:26:54 +0000 Subject: [PATCH 34/46] Checkpoint progress. --- docs/design/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 6f56d06a2aa88..eda501212a8fa 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -743,8 +743,8 @@ Patterns are used in a variety of Carbon language constructs, including The most common pattern is a _binding pattern_, consisting of a new name, a colon (`:`), and a type. It can only match values that may be -[implicitly converted](expressions/implicit_conversions.md) to that type. An `_` -may be used instead of the name to ignore the value. +[implicitly converted](expressions/implicit_conversions.md) to that type. A +underscore (`_`) may be used instead of the name to ignore the value. > **TODO:** Using `var` before a binding pattern to allocate storage so the new > name can be modified? @@ -1102,7 +1102,8 @@ Breaking this apart: - This defines a class named `Widget`. `Widget` is the name added to the enclosing [scope](#declarations-definitions-and-scopes). -- The name `Widget` is followed by curly braces (`{`...`}`), making this a +- The name `Widget` is followed by curly braces (`{`...`}`) containing the + class _body_, making this a [definition](#declarations-definitions-and-scopes). A [forward declaration](#declarations-definitions-and-scopes) would instead have a semicolon(`;`). @@ -1114,7 +1115,7 @@ Breaking this apart: The order of the field declarations determines the fields' memory-layout order. -Classes may have other kinds of members beyond fields declared in a class scope: +Classes may have other kinds of members beyond fields declared in its scope: - [Class functions](#class-functions-and-factory-functions) - [Methods](#methods) @@ -1124,8 +1125,8 @@ Classes may have other kinds of members beyond fields declared in a class scope: constants associated with the class like `class let` or `static let`? - `class`, to define a [_member class_ or _nested class_](https://en.wikipedia.org/wiki/Inner_class) -- Every class has a constant member named `Self` equal to the class type - itself. +- Every class automatically has a [constant member](#let) named `Self` equal + to the class type itself. Both [structural data classes](#struct-types) and nominal classes are considered _class types_, but they are commonly referred to as "structs" and "classes" From a849aff3db21d07522c031dd14ac0ec3c59fc0bd Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 31 May 2022 16:05:25 +0000 Subject: [PATCH 35/46] Big reorg and update --- docs/design/README.md | 408 ++++++++++++++++++++++++------------------ 1 file changed, 231 insertions(+), 177 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index eda501212a8fa..0d24469c44e61 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -32,12 +32,17 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Arrays and slices](#arrays-and-slices) - [Expressions](#expressions) - [Declarations, Definitions, and Scopes](#declarations-definitions-and-scopes) +- [Patterns](#patterns) + - [Binding patterns](#binding-patterns) + - [Destructuring patterns](#destructuring-patterns) + - [Refutable patterns](#refutable-patterns) +- [Name-binding declarations](#name-binding-declarations) + - [Constant `let` declarations](#constant-let-declarations) + - [Variable `var` declarations](#variable-var-declarations) + - [`auto`](#auto) - [Functions](#functions) + - [`auto` return type](#auto-return-type) - [Blocks and statements](#blocks-and-statements) - - [Variables](#variables) - - [`let`](#let) - - [`auto`](#auto) - - [Pattern matching](#pattern-matching) - [Assignment statements](#assignment-statements) - [Control flow](#control-flow) - [`if` and `else`](#if-and-else) @@ -548,121 +553,144 @@ should be exactly one definition for the name, but there can be additional forward declarations that introduce the name before it is defined. Forward declarations allow cyclic references, and can be used to declare a name in an [api file](#packages-libraries-namespaces) that is defined in an -[impl file](#packages-libraries-namespaces). +[impl file](#packages-libraries-namespaces). A name that has been declared but +not defined is called _incomplete_, and in some cases there are limitations on +what can be done with an incomplete name. A name is valid until the end of the innermost enclosing [_scope_](). Except for the outermost scope, scopes are enclosed in curly braces (`{`...`}`). -## Functions +## Patterns -Functions are the core unit of behavior. For example, this is a -[declaration](#declarations-definitions-and-scopes) of a function that adds two -64-bit integers: +A _pattern_ says how to receive some data that is being matched against. There +are two kinds of patterns: -```carbon -fn Add(a: i64, b: i64) -> i64; -``` +- _Refutable_ patterns can fail to match based on the runtime value being + matched. +- _Irrefutable_ patterns must match at compile time. -Breaking this apart: - -- `fn` is the keyword used to introduce a function. -- Its name is `Add`. This is the name added to the enclosing - [scope](#declarations-definitions-and-scopes). -- It accepts two `i64` parameters, `a` and `b`. -- It returns an `i64` result. - -You would call this function like `Add(1, 2)`. - -A function definition is a function declaration that has a body block instead of -a semicolon: - -```carbon -fn Add(a: i64, b: i64) -> i64 { - return a + b; -} -``` - -The names of the parameters are in scope until the end of the definition or -declaration. +Irrefutable patterns are used in [function parameters](#functions), +[variable `var` declarations](#variable-var-declarations), and +[constant `let` declarations](#constant-let-declarations). +[`match` statements](#match) can include both refutable patterns and irrefutable +patterns. > References: > -> - [Functions](functions.md) +> - [Pattern matching](pattern_matching.md) > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) -> - Proposal -> [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438) -> - Question-for-leads issue -> [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) -### Blocks and statements +### Binding patterns -A _code block_ or _block_ is a sequence of _statements_. Blocks define a -[scope](#declarations-definitions-and-scopes) and, like other scopes, is -enclosed in curly braces (`{`...`}`). Each statement is terminated by a -semicolon, and can be one of: +The most common irrefutable pattern is a _binding pattern_, consisting of a new +name, a colon (`:`), and a type. It can only match values that may be +[implicitly converted](expressions/implicit_conversions.md) to that type. A +underscore (`_`) may be used instead of the name to ignore the value. -- an [expression](#expressions), -- a [variable declaration](#variables), -- a [`let` declaration](#let), -- an [assignment statement](#assignment-statements), or -- a [control-flow statement](#control-flow). +Binding patterns default to `let` bindings except inside a context where the +`var` keyword is used: -Statements within a block are normally executed in the order the appear in the -source code, except when modified by control-flow statements. +- The result of a `let` binding is the name is bound to an + [r-value](). + This means the value can not be modified, and its address cannot be taken. +- A `var` binding has dedicated storage, and so the name is an + [l-value]() + which can be modified and has a stable address. -The body of a function is defined by a block, and some -[control-flow statements](#control-flow) have their own blocks of code. These -are nested within the enclosing scope. For example, here is a function -definition with a block of statements defining the body of the function, and a -nested block as part of a `while` statement: +A [generic binding](#checked-and-template-parameters) uses `:!` instead of a +colon (`:`) and can only match compile-time values. + +The keyword `auto` may be used in place of the type in a binding pattern, as +long as the type can be deduced from the type of a value in the same +declaration. + +### Destructuring patterns + +There are also irrefutable _destructuring patterns_, such as _tuple +destructuring_. A tuple destructuring pattern looks like a tuple of patterns. It +may only be used to match tuple values whose components match the component +patterns of the tuple. An example use is: ```carbon -fn Foo() { - Bar(); - while (Baz()) { - Quux(); - } +// `Bar()` returns a tuple consisting of an +// `i32` value and 2-tuple of `f32` values. +fn Bar() -> (i32, (f32, f32)); + +fn Foo() -> i64 { + // Pattern in `var` declaration: + var (p: i64, _: auto) = Bar(); + return p; } ``` +The pattern used in the `var` declaration destructures the tuple value returned +by `Bar()`. The first component pattern, `p: i64`, corresponds to the first +component of the value returned by `Bar()`, which has type `i32`. This is +allowed since there is an implicit conversion from `i32` to `i64`. The result of +this conversion is assigned to the name `p`. The second component pattern, +`_: auto`, matches the second component of the value returned by `Bar()`, which +has type `(f32, f32)`. + +### Refutable patterns + +Additional kinds of patterns are allowed in [`match` statements](#match), that +may or may not match based on the runtime value of the `match` expression: + +- A _value pattern_ is an expression, such as `42`, whose value must be equal + to match. +- A _dynamic cast pattern_ is tests the dynamic type, as described in + [inheritance](#inheritance). + +In addition, an `if` expression may optionally follow a full refutable pattern, +with a boolean predicate that must evaluate to `true` to match. See +[`match`](#match) for an example. + > References: > -> - [Blocks and statements](blocks_and_statements.md) -> - Proposal -> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - [Pattern matching](pattern_matching.md) +> - Question-for-leads issue +> [#1283: how should pattern matching and implicit conversion interact?](https://github.com/carbon-language/carbon-lang/issues/1283) -### Variables +## Name-binding declarations -Blocks introduce nested scopes and can contain variable -[declarations](#declarations-definitions-and-scopes) that are local to that -block, similarly to function parameters. +There are two kinds of name-binding declarations: -For example: +- constant declarations, introduced with `let`, and +- variable declarations, introduced with `var`. + +There are no forward declarations of these, all name-binding declarations are +[definitions](#declarations-definitions-and-scopes). + +### Constant `let` declarations + +A `let` declaration matches an [irrefutable pattern](#patterns) to a value. In +this example, the name `x` is bound to the value `42` with type `i64`: ```carbon -fn DoSomething() -> i64 { - var x: i64 = 42; - x = x + 2; - return x; -} +let x: i64 = 42; ``` -Breaking this apart: +Here `x: i64` is the pattern, which is followed by an equal sign (`=`) and the +value to match, `42`. The names from [binding patterns](#binding-patterns) are +introduced into the enclosing [scope](#declarations-definitions-and-scopes). -- `var` is the keyword used to indicate a variable. -- Its name is `x`. This is the name added to the enclosing - [scope](#declarations-definitions-and-scopes). -- Its type is `i64`. -- It is initialized with the value `42`. +### Variable `var` declarations -Unlike function parameters, `x` is an -[l-value](), -which means it has storage and an address, and so can be modified. +A `var` declaration is similar, except with `var` bindings, so `x` here is an +[l-value]() with +storage and an address, and so may be modified: + +```carbon +var x: i64 = 42; +x = 7; +``` -Note that there are no forward declarations of variables, all variable -declarations are [definitions](#declarations-definitions-and-scopes). +Variables with a type that has +[an unformed state](https://github.com/carbon-language/carbon-lang/pull/257) do +not need to be initialized in the variable declaration, but do need to be +assigned before they are used. > References: > @@ -676,32 +704,10 @@ declarations are [definitions](#declarations-definitions-and-scopes). > - Proposal > [#618: var ordering](https://github.com/carbon-language/carbon-lang/pull/618) -### `let` - -To bind a name to a value without associating a specific storage location, use -`let` instead of `var`. - -```carbon -fn DoSomething() -> i64 { - let x: i64 = 42; - return x + 2; -} -``` - -The `let` binds `x` to the _value_ `42`. `x` is an r-value, so it can not be -modified, for example by being the left side of an assignment statement, and its -address cannot be taken. - -Function parameters are passed by value, and so act like they were defined in a -`let` implicitly. **FIXME:** Is this just the default, or can you write `var` in -a function signature to give parameters dedicated storage so they may be -modified? - ### `auto` -The keyword `auto` may be used in place of the type in a `var` or `let` -statement in a function body. In this case, the type is the static type of the -initializer expression. +If `auto` is used as the type in a `var` or `let` declaration, the type is the +static type of the initializer expression, which is required. ``` var x: i64 = 2; @@ -711,10 +717,69 @@ let y: auto = x + 3; var z: auto = (y > 1); ``` -It may also be used as the return type in a function definition. In this case, -the body of the function must have exactly one `return` statement, and the -return type of the function is set to the static type of the expression argument -of that `return`. +> References: +> +> - [Type inference](type_inference.md) +> - Proposal +> [#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851) + +## Functions + +Functions are the core unit of behavior. For example, this is a +[forward declaration](#declarations-definitions-and-scopes) of a function that +adds two 64-bit integers: + +```carbon +fn Add(a: i64, b: i64) -> i64; +``` + +Breaking this apart: + +- `fn` is the keyword used to introduce a function. +- Its name is `Add`. This is the name added to the enclosing + [scope](#declarations-definitions-and-scopes). +- The parameter list in parentheses (`(`...`)`) is a comma-separated list of + [irrefutable patterns](#patterns). +- It returns an `i64` result. Functions that return nothing omit the `->` and + return type. + +You would call this function like `Add(1, 2)`. + +A function definition is a function declaration that has a body +[block](#blocks-and-statements) instead of a semicolon: + +```carbon +fn Add(a: i64, b: i64) -> i64 { + return a + b; +} +``` + +The names of the parameters are in scope until the end of the definition or +declaration. + +The bindings in the parameter list default to +[`let` bindings](#binding-patterns), and so the parameter names are treated as +[r-values](). If +the `var` keyword is added before the binding, then the arguments will be copied +to new storage, and so can be mutated in the function body. The copy ensures +that any mutations will not be visible to the caller. + +> References: +> +> - [Functions](functions.md) +> - Proposal +> [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) +> - Proposal +> [#438: Add statement syntax for function declarations](https://github.com/carbon-language/carbon-lang/pull/438) +> - Question-for-leads issue +> [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) + +### `auto` return type + +If `auto` is used in place of the return type, the return type of the function +is inferred from the function body. It is set to [common type](#common-type) of +the static type of arguments to the [`return` statements](#return) in the +function. This is not allowed in a forward declaration. ``` // Return type is inferred to be `bool`, the type of `a > 0`. @@ -723,63 +788,47 @@ fn Positive(a: i64) -> auto { } ``` -Note that `auto` is not allowed in a function declaration without a function -body. - > References: > > - [Type inference](type_inference.md) > - [Function return clause](functions.md#return-clause) > - Proposal > [#826: Function return type inference](https://github.com/carbon-language/carbon-lang/pull/826) -> - Proposal -> [#851: auto keyword for vars](https://github.com/carbon-language/carbon-lang/pull/851) -### Pattern matching +### Blocks and statements -Patterns are used in a variety of Carbon language constructs, including -[function parameters](#functions), [variable declarations](#variables), and -[`let` declarations](#let). +A _code block_ or _block_ is a sequence of _statements_. Blocks define a +[scope](#declarations-definitions-and-scopes) and, like other scopes, is +enclosed in curly braces (`{`...`}`). Each statement is terminated by a +semicolon, and can be one of: -The most common pattern is a _binding pattern_, consisting of a new name, a -colon (`:`), and a type. It can only match values that may be -[implicitly converted](expressions/implicit_conversions.md) to that type. A -underscore (`_`) may be used instead of the name to ignore the value. +- an [expression](#expressions), +- a [variable declaration](#variable-var-declarations), +- a [`let` declaration](#constant-let-declarations), +- an [assignment statement](#assignment-statements), or +- a [control-flow statement](#control-flow). -> **TODO:** Using `var` before a binding pattern to allocate storage so the new -> name can be modified? +Statements within a block are normally executed in the order the appear in the +source code, except when modified by control-flow statements. -There are also _destructuring patterns_, such as _tuple destructuring_. A tuple -destructuring pattern looks like a tuple of patterns. It may only be used to -match tuple values whose components match the component patterns of the tuple. -An example use is: +The body of a function is defined by a block, and some +[control-flow statements](#control-flow) have their own blocks of code. These +are nested within the enclosing scope. For example, here is a function +definition with a block of statements defining the body of the function, and a +nested block as part of a `while` statement: ```carbon -// `Bar()` returns a tuple consisting of an -// `i32` value and 2-tuple of `f32` values. -fn Bar() -> (i32, (f32, f32)); - -fn Foo() -> i64 { - // Pattern in `var` declaration: - var (p: i64, _: auto) = Bar(); - return p; +fn Foo() { + Bar(); + while (Baz()) { + Quux(); + } } ``` -The pattern used in the `var` declaration destructures the tuple value returned -by `Bar()`. The first component pattern, `p: i64`, corresponds to the first -component of the value returned by `Bar()`, which has type `i32`. This is -allowed since there is an implicit conversion from `i32` to `i64`. The result of -this conversion is assigned to the name `p`. The second component pattern, -`_: auto`, matches the second component of the value returned by `Bar()`, which -has type `(f32, f32)`. The [`auto`](#auto) matches any type and the `_` means -the value is discarded. - -Additional kinds of patterns are allowed in [`match` statements](#match). - > References: > -> - [Pattern matching](pattern_matching.md) +> - [Blocks and statements](blocks_and_statements.md) > - Proposal > [#162: Basic Syntax](https://github.com/carbon-language/carbon-lang/pull/162) @@ -1028,9 +1077,10 @@ This is instead of `match` is a control flow similar to `switch` of C/C++ and mirrors similar constructs in other languages, such as Swift. The `match` keyword is followed by -an expression in parentheses, whose value is matched against `case` declarations +an expression in parentheses, whose value is matched against the `case` +declarations, each of which contains a [refutable pattern](#refutable-patterns), in order. The code for the first matching `case` is executed. An optional -`default` code block may be placed after the `case` declaratoins, it will be +`default` code block may be placed after the `case` declarations, it will be executed if none of the `case` declarations match. An example `match` is: @@ -1056,17 +1106,6 @@ fn Foo() -> f32 { } ``` -A `case` pattern can contain -[binding and destructuring patterns](#pattern-matching). In addition, it can -contain patterns that may or may not match based on the runtime value of the -`match` expression: - -- A _value pattern_ is an expression, such as `42`, whose value must be equal - to match. -- An _if pattern_, consisting of an `if` and a boolean predicate at the end of - the pattern like `if (p < 13)`, matches if the predicate evaluates to - `true`. - > References: > > - [Pattern matching](pattern_matching.md) @@ -1092,8 +1131,6 @@ This is an example of a class class Widget { var x: i32; var y: i32; - var z: i32; - var payload: String; } ``` @@ -1109,9 +1146,10 @@ Breaking this apart: have a semicolon(`;`). - Those braces delimit the class' [scope](#declarations-definitions-and-scopes). -- `Widget` has three `i32` fields: `x`, `y`, and `z`. -- `Widget` has one `String` field: `payload`. -- Given an instance `dial`, a field can be referenced with `dial.payload`. +- Fields, or + [instances variables](https://en.wikipedia.org/wiki/Instance_variable), are + defined using [`var` declarations](#variable-var-declarations). `Widget` has + two `i32` fields (`x` and `y`), and one `String` field (`payload`). The order of the field declarations determines the fields' memory-layout order. @@ -1120,13 +1158,18 @@ Classes may have other kinds of members beyond fields declared in its scope: - [Class functions](#class-functions-and-factory-functions) - [Methods](#methods) - [`alias`](#aliases) -- [`let`](#let) to define constants. **TODO:** Are these constants associated - with the class or the instance? Do we need to another syntax to distinguish - constants associated with the class like `class let` or `static let`? +- [`let`](#constant-let-declarations) to define class constants. **TODO:** + Another syntax to define constants associated with the class like + `class let` or `static let`? - `class`, to define a [_member class_ or _nested class_](https://en.wikipedia.org/wiki/Inner_class) -- Every class automatically has a [constant member](#let) named `Self` equal - to the class type itself. +- Every class automatically has a + [constant member](#constant-let-declarations) named `Self` equal to the + class type itself. + +Members of a class are [accessed](expressions/member_access.md) using the dot +(`.`) notation, so given an instance `dial` of type `Widget`, `dial.payload` +refers to its `payload` field. Both [structural data classes](#struct-types) and nominal classes are considered _class types_, but they are commonly referred to as "structs" and "classes" @@ -1150,8 +1193,8 @@ in any scope that has [access](#access-control) to all of the class' fields. This may be used to assign or initialize a variable with a class type, as in: ```carbon -var sprocket: Widget = {.x = 3, .y = 4, .z = 5, .payload = "Sproing"}; -sprocket = {.x = 2, .y = 1, .z = 0, .payload = "Bounce"}; +var sprocket: Widget = {.x = 3, .y = 4, .payload = "Sproing"}; +sprocket = {.x = 2, .y = 1, .payload = "Bounce"}; ``` You may also copy a value of a class type into a variable of the same type. @@ -1304,7 +1347,18 @@ by one of these three keywords: A pointer to a derived class may be cast to a pointer to one of its base classes. Calling a virtual method through a pointer to a base class will use the -overridden definition provided in the derived class. +overridden definition provided in the derived class. Base classes with `virtual` +methods may use +[run-time type information](https://en.wikipedia.org/wiki/Run-time_type_information) +in a match statement to dynamically test whether the dynamic type of a value is +some derived class, as in: + +```carbon +var base_ptr: MyBaseType* = ...; +match (base_ptr) { + case dyn p: MiddleDerived* => { ... } +} +``` For purposes of construction, a derived class acts like its first field is called `base` with the type of its immediate base class. From f93cec9ffb6a84f5adad1d0567f09f4efd1e2a3a Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 31 May 2022 19:17:12 +0000 Subject: [PATCH 36/46] Expand refutable patterns --- docs/design/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 0d24469c44e61..8b99d2661fea8 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -640,12 +640,15 @@ may or may not match based on the runtime value of the `match` expression: - A _value pattern_ is an expression, such as `42`, whose value must be equal to match. +- A _choice pattern_ matches one case from a choice type, as described in + [the choice types section](#choice-types). - A _dynamic cast pattern_ is tests the dynamic type, as described in [inheritance](#inheritance). In addition, an `if` expression may optionally follow a full refutable pattern, -with a boolean predicate that must evaluate to `true` to match. See -[`match`](#match) for an example. +with a boolean predicate that must evaluate to `true` to match. The names from +any bindings in the pattern are in scope and so may be used in the predicate +expression. See [`match`](#match) for an example. > References: > From e7dfab82390c55640e48dd9524fffce0c04fc557 Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 1 Jun 2022 23:01:34 +0000 Subject: [PATCH 37/46] `if` is part of `match` not refutable patterns --- docs/design/README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 8b99d2661fea8..9c64c43d6f9d2 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -645,10 +645,7 @@ may or may not match based on the runtime value of the `match` expression: - A _dynamic cast pattern_ is tests the dynamic type, as described in [inheritance](#inheritance). -In addition, an `if` expression may optionally follow a full refutable pattern, -with a boolean predicate that must evaluate to `true` to match. The names from -any bindings in the pattern are in scope and so may be used in the predicate -expression. See [`match`](#match) for an example. +See [`match`](#match) for examples of refutable patterns. > References: > @@ -1082,9 +1079,12 @@ This is instead of constructs in other languages, such as Swift. The `match` keyword is followed by an expression in parentheses, whose value is matched against the `case` declarations, each of which contains a [refutable pattern](#refutable-patterns), -in order. The code for the first matching `case` is executed. An optional -`default` code block may be placed after the `case` declarations, it will be -executed if none of the `case` declarations match. +in order. The refutable pattern may optionally be folloed by an `if` expression, +which may use the names from bindings in the pattern. + +The code for the first matching `case` is executed. An optional `default` code +block may be placed after the `case` declarations, it will be executed if none +of the `case` declarations match. An example `match` is: From d129ff4da3f28f012106a2a6b03993577930f2d9 Mon Sep 17 00:00:00 2001 From: josh11b Date: Tue, 7 Jun 2022 14:12:30 -0700 Subject: [PATCH 38/46] Apply suggestions from code review Co-authored-by: Geoff Romer --- docs/design/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 9c64c43d6f9d2..67d0a4bd4aa83 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -183,7 +183,7 @@ The behavior of the Carbon compiler depends on the _build mode_: Expressions compute values in Carbon, and these values are always strongly typed much like in C++. However, an important difference from C++ is that types are themselves modeled as values; specifically, compile-time constant values. This -means that the grammar for writing a type is the expression](#expressions) +means that the grammar for writing a type is the [expression](#expressions) grammar. Expressions written where a type is expected must be able to be evaluated at compile-time and must evaluate to a type value. @@ -264,7 +264,7 @@ Integers may be written in decimal, hexadecimal, or binary: - `0x1FE` (hexadecimal) - `0b1010` (binary) -Underscores `_` may be as a digit separator, but for decimal and hexadecimal +Underscores `_` may be used as digit separators, but for decimal and hexadecimal literals, they can only appear in conventional locations. Numeric literals are case-sensitive: `0x`, `0b` must be lowercase, whereas hexadecimal digits must be uppercase. Integer literals never contain a `.`. @@ -568,7 +568,7 @@ are two kinds of patterns: - _Refutable_ patterns can fail to match based on the runtime value being matched. -- _Irrefutable_ patterns must match at compile time. +- _Irrefutable_ patterns are guaranteed to match, so long as the code type-checks. Irrefutable patterns are used in [function parameters](#functions), [variable `var` declarations](#variable-var-declarations), and @@ -660,7 +660,7 @@ There are two kinds of name-binding declarations: - constant declarations, introduced with `let`, and - variable declarations, introduced with `var`. -There are no forward declarations of these, all name-binding declarations are +There are no forward declarations of these; all name-binding declarations are [definitions](#declarations-definitions-and-scopes). ### Constant `let` declarations @@ -797,7 +797,7 @@ fn Positive(a: i64) -> auto { ### Blocks and statements -A _code block_ or _block_ is a sequence of _statements_. Blocks define a +A _code block_ or _block_ is a sequence of _statements_. A block defines a [scope](#declarations-definitions-and-scopes) and, like other scopes, is enclosed in curly braces (`{`...`}`). Each statement is terminated by a semicolon, and can be one of: @@ -1079,7 +1079,7 @@ This is instead of constructs in other languages, such as Swift. The `match` keyword is followed by an expression in parentheses, whose value is matched against the `case` declarations, each of which contains a [refutable pattern](#refutable-patterns), -in order. The refutable pattern may optionally be folloed by an `if` expression, +in order. The refutable pattern may optionally be followed by an `if` expression, which may use the names from bindings in the pattern. The code for the first matching `case` is executed. An optional `default` code From cf9439e2500572b3cf10196435aeac041ae69c37 Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 7 Jun 2022 21:13:07 +0000 Subject: [PATCH 39/46] Fix formatting --- docs/design/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 67d0a4bd4aa83..42684430e759b 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -568,7 +568,8 @@ are two kinds of patterns: - _Refutable_ patterns can fail to match based on the runtime value being matched. -- _Irrefutable_ patterns are guaranteed to match, so long as the code type-checks. +- _Irrefutable_ patterns are guaranteed to match, so long as the code + type-checks. Irrefutable patterns are used in [function parameters](#functions), [variable `var` declarations](#variable-var-declarations), and @@ -1079,8 +1080,8 @@ This is instead of constructs in other languages, such as Swift. The `match` keyword is followed by an expression in parentheses, whose value is matched against the `case` declarations, each of which contains a [refutable pattern](#refutable-patterns), -in order. The refutable pattern may optionally be followed by an `if` expression, -which may use the names from bindings in the pattern. +in order. The refutable pattern may optionally be followed by an `if` +expression, which may use the names from bindings in the pattern. The code for the first matching `case` is executed. An optional `default` code block may be placed after the `case` declarations, it will be executed if none From e0f93fd4179b7ae76f808154bb302dbd69879256 Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 8 Jun 2022 23:12:20 +0000 Subject: [PATCH 40/46] Address review comments. --- docs/design/README.md | 49 +++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 42684430e759b..bfe6890072bc6 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -16,7 +16,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Code and comments](#code-and-comments) - [Build modes](#build-modes) - [Types are values](#types-are-values) - - [Structural and nominal types](#structural-and-nominal-types) - [Primitive types](#primitive-types) - [`bool`](#bool) - [Integer types](#integer-types) @@ -56,7 +55,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [`match`](#match) - [User-defined types](#user-defined-types) - [Classes](#classes) - - [Assignment, copying](#assignment-copying) + - [Assignment](#assignment) - [Class functions and factory functions](#class-functions-and-factory-functions) - [Methods](#methods) - [Inheritance](#inheritance) @@ -187,15 +186,6 @@ means that the grammar for writing a type is the [expression](#expressions) grammar. Expressions written where a type is expected must be able to be evaluated at compile-time and must evaluate to a type value. -### Structural and nominal types - -Some types are _structural_, which means they are equal if they have the same -components. This is in contrast to _nominal_ types that have a name that -identifies a specific definition. Two nominal types are equal if their names -resolve to the same definition. If a nominal type is [generic](#generics), and -so has parameters, then the parameters must also be equal for the types to be -equal. - ## Primitive types Some types are used as the building blocks for other types and are made @@ -402,15 +392,17 @@ fn DoubleTuple(x: (i32, i32)) -> (i32, i32) { } ``` -Tuple types are [structural](#structural-and-nominal-types). +Tuple types are +[structural](https://en.wikipedia.org/wiki/Structural_type_system). > References: [Tuples](tuples.md) ### Struct types -Carbon also has [structural types](#structural-and-nominal-types) whose members -are identified by name instead of position. These are called _structural data -classes_, also known as a _struct types_ or _structs_. +Carbon also has +[structural types](https://en.wikipedia.org/wiki/Structural_type_system) whose +members are identified by name instead of position. These are called _structural +data classes_, also known as a _struct types_ or _structs_. Both struct types and values are written inside curly braces (`{`...`}`). In both cases, they have a comma-separated list of members that start with a period @@ -586,7 +578,8 @@ patterns. ### Binding patterns The most common irrefutable pattern is a _binding pattern_, consisting of a new -name, a colon (`:`), and a type. It can only match values that may be +name, a colon (`:`), and a type. It binds the matched value of that type to that +name. It can only match values that may be [implicitly converted](expressions/implicit_conversions.md) to that type. A underscore (`_`) may be used instead of the name to ignore the value. @@ -798,10 +791,10 @@ fn Positive(a: i64) -> auto { ### Blocks and statements -A _code block_ or _block_ is a sequence of _statements_. A block defines a +A _block_ is a sequence of _statements_. A block defines a [scope](#declarations-definitions-and-scopes) and, like other scopes, is enclosed in curly braces (`{`...`}`). Each statement is terminated by a -semicolon, and can be one of: +semicolon or block, and can be one of: - an [expression](#expressions), - a [variable declaration](#variable-var-declarations), @@ -1083,9 +1076,9 @@ declarations, each of which contains a [refutable pattern](#refutable-patterns), in order. The refutable pattern may optionally be followed by an `if` expression, which may use the names from bindings in the pattern. -The code for the first matching `case` is executed. An optional `default` code -block may be placed after the `case` declarations, it will be executed if none -of the `case` declarations match. +The code for the first matching `case` is executed. An optional `default` block +may be placed after the `case` declarations, it will be executed if none of the +`case` declarations match. An example `match` is: @@ -1179,7 +1172,7 @@ Both [structural data classes](#struct-types) and nominal classes are considered _class types_, but they are commonly referred to as "structs" and "classes" respectively when that is not confusing. Like structs, classes refer to their members by name. Unlike structs, classes are -[nominal types](#structural-and-nominal-types). +[nominal types](https://en.wikipedia.org/wiki/Nominal_type_system#Nominal_typing). > References: > @@ -1189,7 +1182,7 @@ members by name. Unlike structs, classes are > - Proposal > [#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989) -#### Assignment, copying +#### Assignment There is an [implicit conversions](expressions/implicit_conversions.md) defined between a [struct literal](#struct-types) and a class type with the same fields, @@ -1201,14 +1194,6 @@ var sprocket: Widget = {.x = 3, .y = 4, .payload = "Sproing"}; sprocket = {.x = 2, .y = 1, .payload = "Bounce"}; ``` -You may also copy a value of a class type into a variable of the same type. - -```carbon -var thingy: Widget = sprocket; -sprocket = thingy; -Assert(sprocket.x == thingy.x); -``` - > References: > > - [Classes: Construction](classes.md#construction) @@ -1549,7 +1534,7 @@ choice LikeABoolean { False, True } > - Proposal > [#107: Code and name organization](https://github.com/carbon-language/carbon-lang/pull/107) > - Proposal -> [#752: api file default publicn](https://github.com/carbon-language/carbon-lang/pull/752) +> [#752: api file default public](https://github.com/carbon-language/carbon-lang/pull/752) > - Question-for-leads issue > [#1136: what is the top-level scope in a source file, and what names are found there?](https://github.com/carbon-language/carbon-lang/issues/1136) From 6926628658e4cedec1ba3a31106fd9ad795c4199 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 9 Jun 2022 15:17:56 +0000 Subject: [PATCH 41/46] Address review comments. --- docs/design/README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index bfe6890072bc6..18b8d4b37fccf 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -123,7 +123,9 @@ fn Fibonacci(limit: i64) { var (a, b): (i64, i64) = (0, 1); while (a < limit) { Console.Print(a, " "); - (a, b) = (b, a + b); + let next: i64 = a + b; + a = b; + b = next; } Console.Print("\n"); } @@ -188,9 +190,6 @@ evaluated at compile-time and must evaluate to a type value. ## Primitive types -Some types are used as the building blocks for other types and are made -available through the [prelude package](#name-lookup-for-common-types). - Primitive types fall into the following categories: - the boolean type `bool`, @@ -198,6 +197,9 @@ Primitive types fall into the following categories: - IEEE-754 floating-point types, and - string types. +These are made available through the +[prelude package](#name-lookup-for-common-types). + > References: [Primitive types](primitive_types.md) ### `bool` @@ -833,9 +835,6 @@ Assignment statements mutate the value of the described on the left-hand side of the assignment. - Assignment: `x = y;`. `x` is assigned the value of `y`. -- Destructuring assignment: `(x, y) = z;`. `z` must be a tuple with the same - number of compents as the left-hand side. `x` is assigned the value of - `z[0]` and `y` is assigned the value of `z[1]`. - Increment and decrement: `++i;`, `--j;`. `i` is set to `i + 1`, `j` is set to `j - 1`. - Compound assignment: `x += y;`, `x -= y;`, `x *= y;`, `x /= y;`, `x &= y;`, From 3162eb455191f44d3b304a9dc9b496173bf04c13 Mon Sep 17 00:00:00 2001 From: josh11b Date: Thu, 9 Jun 2022 08:42:46 -0700 Subject: [PATCH 42/46] Apply suggestions from code review Co-authored-by: Chandler Carruth --- docs/design/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 18b8d4b37fccf..ffe1db43bb266 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -120,7 +120,7 @@ import Console; // Prints the Fibonacci numbers less than `limit`. fn Fibonacci(limit: i64) { - var (a, b): (i64, i64) = (0, 1); + var (a: i64, b: i64) = (0, 1); while (a < limit) { Console.Print(a, " "); let next: i64 = a + b; @@ -232,7 +232,7 @@ programming error: The unsigned-integer types are: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, and `Carbon.UInt(N)`. Unsigned integer types wrap around on overflow, we strongly advise that they are not used except when those semantics are desired. These -types are intended for [hashing](https://en.wikipedia.org/wiki/Hash_function), +types are intended for bit manipulation or modular arithmetic as often found in [hashing](https://en.wikipedia.org/wiki/Hash_function), [cryptography](https://en.wikipedia.org/wiki/Cryptography), and [PRNG](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) use cases. Values which can never be negative, like sizes, but for which wrapping does not @@ -583,7 +583,7 @@ The most common irrefutable pattern is a _binding pattern_, consisting of a new name, a colon (`:`), and a type. It binds the matched value of that type to that name. It can only match values that may be [implicitly converted](expressions/implicit_conversions.md) to that type. A -underscore (`_`) may be used instead of the name to ignore the value. +underscore (`_`) may be used instead of the name to match a value but without binding any name to it. Binding patterns default to `let` bindings except inside a context where the `var` keyword is used: From 0c65552dd35dc8cfb2a2ef4d4beb5431f4bcc14c Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 9 Jun 2022 15:48:12 +0000 Subject: [PATCH 43/46] Fix formatting --- docs/design/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index ffe1db43bb266..475d4104cceee 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -232,7 +232,8 @@ programming error: The unsigned-integer types are: `u8`, `u16`, `u32`, `u64`, `u128`, `u256`, and `Carbon.UInt(N)`. Unsigned integer types wrap around on overflow, we strongly advise that they are not used except when those semantics are desired. These -types are intended for bit manipulation or modular arithmetic as often found in [hashing](https://en.wikipedia.org/wiki/Hash_function), +types are intended for bit manipulation or modular arithmetic as often found in +[hashing](https://en.wikipedia.org/wiki/Hash_function), [cryptography](https://en.wikipedia.org/wiki/Cryptography), and [PRNG](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) use cases. Values which can never be negative, like sizes, but for which wrapping does not @@ -583,7 +584,8 @@ The most common irrefutable pattern is a _binding pattern_, consisting of a new name, a colon (`:`), and a type. It binds the matched value of that type to that name. It can only match values that may be [implicitly converted](expressions/implicit_conversions.md) to that type. A -underscore (`_`) may be used instead of the name to match a value but without binding any name to it. +underscore (`_`) may be used instead of the name to match a value but without +binding any name to it. Binding patterns default to `let` bindings except inside a context where the `var` keyword is used: From 8187242918cb6487fc1d3aa736ed41dfac502193 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 9 Jun 2022 16:14:03 +0000 Subject: [PATCH 44/46] Address review comments. --- docs/design/README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 475d4104cceee..481920af0b8e4 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -197,8 +197,7 @@ Primitive types fall into the following categories: - IEEE-754 floating-point types, and - string types. -These are made available through the -[prelude package](#name-lookup-for-common-types). +These are made available through the [prelude](#name-lookup-for-common-types). > References: [Primitive types](primitive_types.md) @@ -295,7 +294,9 @@ with an `f` and the number of bits: `f16`, `f32`, `f64`, and `f128`. #### Floating-point literals -Decimal and hexadecimal real-number literals are supported: +Floating-point types along with [user-defined types](#user-defined-types) may +initialized from _real-number literals_. Decimal and hexadecimal real-number +literals are supported: - `123.456` (digits on both sides of the `.`) - `123.456e789` (optional `+` or `-` after the `e`) @@ -587,11 +588,11 @@ name. It can only match values that may be underscore (`_`) may be used instead of the name to match a value but without binding any name to it. -Binding patterns default to `let` bindings except inside a context where the -`var` keyword is used: +Binding patterns default to _`let` bindings_ except inside a context where the +`var` keyword is used to make it a _`var` binding_: - The result of a `let` binding is the name is bound to an - [r-value](). + [non-l-value](). This means the value can not be modified, and its address cannot be taken. - A `var` binding has dedicated storage, and so the name is an [l-value]() @@ -636,8 +637,8 @@ has type `(f32, f32)`. Additional kinds of patterns are allowed in [`match` statements](#match), that may or may not match based on the runtime value of the `match` expression: -- A _value pattern_ is an expression, such as `42`, whose value must be equal - to match. +- An _expression pattern_ is an expression, such as `42`, whose value must be + equal to match. - A _choice pattern_ matches one case from a choice type, as described in [the choice types section](#choice-types). - A _dynamic cast pattern_ is tests the dynamic type, as described in From 24b54ccfe9359e9cd052f107bb89112aa6a8f3c1 Mon Sep 17 00:00:00 2001 From: josh11b Date: Thu, 9 Jun 2022 10:41:08 -0700 Subject: [PATCH 45/46] Clarify `Self` --- docs/design/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 481920af0b8e4..c547fb3fe385b 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1162,9 +1162,9 @@ Classes may have other kinds of members beyond fields declared in its scope: `class let` or `static let`? - `class`, to define a [_member class_ or _nested class_](https://en.wikipedia.org/wiki/Inner_class) -- Every class automatically has a - [constant member](#constant-let-declarations) named `Self` equal to the - class type itself. + +Within the scope of a class, the unqualified name `Self` can be used to refer to +the class itself. Members of a class are [accessed](expressions/member_access.md) using the dot (`.`) notation, so given an instance `dial` of type `Widget`, `dial.payload` From a0e29ada473b9c69a6df23be91d0d1a7ed8bbd45 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 9 Jun 2022 19:29:37 +0000 Subject: [PATCH 46/46] Address review comments. --- docs/design/README.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index c547fb3fe385b..b38207cb51a87 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -799,13 +799,9 @@ fn Positive(a: i64) -> auto { A _block_ is a sequence of _statements_. A block defines a [scope](#declarations-definitions-and-scopes) and, like other scopes, is enclosed in curly braces (`{`...`}`). Each statement is terminated by a -semicolon or block, and can be one of: - -- an [expression](#expressions), -- a [variable declaration](#variable-var-declarations), -- a [`let` declaration](#constant-let-declarations), -- an [assignment statement](#assignment-statements), or -- a [control-flow statement](#control-flow). +semicolon or block. [Expressions](#expressions) and +[`var`](#variable-var-declarations) and [`let`](#constant-let-declarations) are +valid statements. Statements within a block are normally executed in the order the appear in the source code, except when modified by control-flow statements.