Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

var ordering #618

Merged
merged 11 commits into from
Jul 9, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions docs/design/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,7 @@ Some common expressions in Carbon include:

### Functions

> References: [Functions](functions.md) and
> [syntactic conventions](syntactic_conventions.md)
> References: [Functions](functions.md)
>
> **TODO:** References need to be evolved.

Expand Down Expand Up @@ -325,10 +324,7 @@ fn Foo() {

### Variables

> References: [Variables](variables.md) and
> [syntactic conventions](syntactic_conventions.md)
>
> **TODO:** References need to be evolved.
> References: [Variables](variables.md)

Blocks introduce nested scopes and can contain local variable declarations that
work similarly to function parameters.
Expand Down
2 changes: 1 addition & 1 deletion docs/design/control_flow/return.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ 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(Int a, Int b) -> Int {
fn Sum(a: Int, b: Int) -> Int {
return a + b;
}
```
Expand Down
2 changes: 1 addition & 1 deletion docs/design/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ primarily divided up into "functions" (or "procedures", "subroutines", or
language. Let's look at a simple example to understand how these work:

```
fn Sum(Int a, Int b) -> Int;
fn Sum(a: Int, b: Int) -> Int;
```

This declares a function called `Sum` which accepts two `Int` parameters, the
Expand Down
2 changes: 1 addition & 1 deletion docs/design/name_lookup.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace Foo {
}
}

fn F(Foo.Bar.MyInt x);
fn F(x: Foo.Bar.MyInt);
```

Carbon packages are also namespaces so to get to an imported name from the
Expand Down
75 changes: 0 additions & 75 deletions docs/design/syntactic_conventions.md

This file was deleted.

43 changes: 16 additions & 27 deletions docs/design/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,19 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

## Table of contents

- [TODO](#todo)
- [Overview](#overview)
- [Declaring constants](#declaring-constants)
- [Caveats](#caveats)
- [Alternatives](#alternatives)
- [Declaring constants](#declaring-constants-1)
- [Global variables](#global-variables)
- [Relevant proposals](#relevant-proposals)

<!-- tocstop -->

## TODO
## Overview

This is a skeletal design, added to support [the overview](README.md). It should
not be treated as accepted by the core team; rather, it is a placeholder until
we have more time to examine this detail. Please feel welcome to rewrite and
update as appropriate.
Carbon's local variable syntax is:

## Overview
> `var` _identifier_`:` _type_ _[_ `=` _value_ _]_`;`

Blocks introduce nested scopes and can contain local variable declarations that
work similarly to function parameters.
Expand All @@ -35,7 +31,7 @@ For example:

```
fn Foo() {
var Int x = 42;
var x: Int = 42;
}
```

Expand All @@ -46,31 +42,24 @@ yet, but this gives you the basic idea.

While there can be global constants, there are no global variables.

### Declaring constants
## Caveats

Constants will use template-like syntax for declarations. For example, a simple
integer constant looks like:

```carbon
var Int$$ MyVal = 42;
```
> TODO: Constant syntax is an ongoing discussion.
zygoloid marked this conversation as resolved.
Show resolved Hide resolved

## Alternatives

### Declaring constants

There is other syntax that could be used for declaring constants. There are
serious problems with the use of `const` in C++ as part of the type system.
Another alternative is `let` from Swift, although there are some questions
around how intuitive it is for this to introduce a constant. Another candidate
is `val` from Kotlin. Another thing we need to contend with is the surprise of
const and reference (semantic) types. At present we are leaning towards the
tempalte-like syntax for consistency within Carbon.

### Global variables

We are exploring several different ideas for how to design less bug-prone
patterns to replace the important use cases programmers still have for global
variables. We may be unable to fully address them, at least for migrated code,
and be forced to add some limited form of global variables back. We may also
discover that their convenience outweighs any improvements afforded.

## Relevant proposals

Most discussion of design choices and alternatives may be found in relevant
proposals.

- [`var` statement](/proposals/p0339.md)
- [`var` ordering](/proposals/p0618.md)
1 change: 1 addition & 0 deletions proposals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,6 @@ request:
- [0538 - `return` with no argument](p0538.md)
- [0540 - Remove `Void`](p0540.md)
- [0555 - Operator precedence](p0555.md)
- [0618 - var ordering](p0618.md)

<!-- endproposals -->
163 changes: 163 additions & 0 deletions proposals/p0618.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# var ordering

<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->

[Pull request](https:/carbon-language/carbon-lang/pull/618)

<!-- toc -->

## Table of contents

- [Problem](#problem)
- [Background](#background)
- [Proposal](#proposal)
- [Rationale based on Carbon's goals](#rationale-based-on-carbons-goals)
- [Alternatives considered](#alternatives-considered)
- [Type ordering](#type-ordering)
- [`<type>: <name>`](#type-name)
- [`<type> <name>`](#type-name-1)
- [`<name>: <type>`](#name-type)
- [`:` versus `in`](#-versus-in)

<!-- tocstop -->

## Problem

As stated by on
[Re-evaluate core variable & parameter identifier/type order (including a default for parameters) #542](https:/carbon-language/carbon-lang/issues/542):

> Somewhat condensed, bullet-point-y background for this question:
>
> - We've been using first `Type: variable` and then `Type variable` syntax in
> variables, parameters, and other declarations.
> - This was primarily based on a _lack of compelling data_ to select a better
> syntax, with trying to stay similar to C++ as a fallback.
> - It was _specifically_ intended to be revisited. The expected trigger for
> this was some form of broader user data (surveys at least of decent #s of
> developers, or potentially real user studies).
> - However, we have gained specific new information as we've filled out a
> great deal of the surrounding syntax. We have also gotten some data on
> parsing challenges (although perhaps surmountable challenges) of
> `Type variable`.
> - We also don't have a short/definite timeline to start getting useful data.
> - The leads should re-evaluate the core variable syntax based on the new
> information we have, but _without_ trying to wait for data.
> - We can always re-evaluate again if and when data arrives and indicates
> any need for it.
> - The leads should do this ASAP and make a decision so that we can focus our
> energy, reduce frustrating discussions, and have consistent syntax in
> examples and proposals.

## Background

Background may be found in the related
[#542](https:/carbon-language/carbon-lang/issues/542) and
[Docs](https://docs.google.com/document/d/1iuytei37LPg_tEd6xe-O6P_bpN7TIbEjNtFMLYW2Nno).

## Proposal

Two changes:

- Switch to `<name>: <type>`, replacing `<type>: <name>`.
- Use `in` instead of `:` in range-based for loops.

Note these changes were largely implemented by
[#563](https:/carbon-language/carbon-lang/pull/563).

## Rationale based on Carbon's goals

Both of these changes are done for consistency with other modern languages,
particularly Swift and Rust. The switch from `:` to `in` is for ease of
understanding and parsing.

## Alternatives considered

### Type ordering

Alternatives are pulled from
[Docs](https://docs.google.com/document/d/1iuytei37LPg_tEd6xe-O6P_bpN7TIbEjNtFMLYW2Nno).

#### `<type>: <name>`

`var message: String = "Hello world";`
jonmeow marked this conversation as resolved.
Show resolved Hide resolved

Advantages:

- Roughly matches the order of C, C++, C#, D and Java, except with extra `var`
and `:`.
- Type at the beginning puts most important information up front.
- Name followed by default matches assignment statements.

Disadvantages:

- Existing languages that use a `:` put the name before and the type after
([universally](http://rosettacode.org/wiki/Variables)).
- Beyond simple inconsistency, the overlap of : in this syntax with different
jonmeow marked this conversation as resolved.
Show resolved Hide resolved
order will add confusion for people working/familiar with multiple
languages.
- Does not end up having a consistent syntax with the "+C" options for labels.
zygoloid marked this conversation as resolved.
Show resolved Hide resolved

Opinions vary:

- Not friendly to optionally dropping the type: to represent auto type
jonmeow marked this conversation as resolved.
Show resolved Hide resolved
deduction.

#### `<type> <name>`

`var String message = "Hello world";`

Advantages

- Matches C, C++, C#, D and Java the closest.

Disadvantages:

- Creates parse ambiguity, particularly when we start adding syntax to the
name to indicate that a parameter is labeled, etc.

Currently hard to see how we can make this work, since it isn't compatible with
other choices, detailed in
[Docs](https://docs.google.com/document/d/1iuytei37LPg_tEd6xe-O6P_bpN7TIbEjNtFMLYW2Nno).

#### `<name>: <type>`

`var message: String = "Hello world";`

Advantages:

- Matches [Swift](http://rosettacode.org/wiki/Variables#Swift),
[Rust](https://doc.rust-lang.org/stable/rust-by-example/primitives.html),
[Kotlin](http://rosettacode.org/wiki/Variables#Kotlin),
[Python3](https://docs.python.org/3/library/typing.html), and many smaller
languages ([Ada](http://rosettacode.org/wiki/Variables#Ada),
[Pascal languages like Delphi](http://rosettacode.org/wiki/Variables#Delphi)
and [Modula-3](http://rosettacode.org/wiki/Variables#Modula-3),
[Eiffel](http://rosettacode.org/wiki/Variables#Eiffel),
[Nim](https://nim-lang.org/docs/tut1.html#the-var-statement),
[Pony](http://rosettacode.org/wiki/Variables#Pony),
[Zig](https://ziglang.org/documentation/0.7.1/#Variables)).
- Names will line up better with method names in a `struct` definition.

Disadvantages:

- Name separated from initializer; default doesn't match assignment
statements.
- Further from the simplistic appearance of common C and C++ variable
declarations.

Opinions vary:

- Existing languages typically make the "`: type`" part optional when an
"`= value`" clause is present.

### `:` versus `in`

The `:` operator for range-based for loops becomes harder to read, and more
likely to cause ambiguity, when `:` is also used for `var`. That is,
`for (var i: Int : list)` is just harder to understand than
`for (var i: Int in list)`. `in` is a favorable choice for its use in other
languages.