Răsfoiți Sursa

One way principle (#829)

Add a principle that Carbon should only provide one way of doing things

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Jon Meow 4 ani în urmă
părinte
comite
c3f4f28ec5
3 a modificat fișierele cu 235 adăugiri și 0 ștergeri
  1. 155 0
      docs/project/principles/one_way.md
  2. 1 0
      proposals/README.md
  3. 79 0
      proposals/p0829.md

+ 155 - 0
docs/project/principles/one_way.md

@@ -0,0 +1,155 @@
+# Principle: Prefer providing only one way to do a given thing
+
+<!--
+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
+-->
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Background](#background)
+-   [Principle](#principle)
+-   [Applications of this principle](#applications-of-this-principle)
+-   [Caveats](#caveats)
+    -   [Specialized syntax](#specialized-syntax)
+    -   [Non-obvious alternatives](#non-obvious-alternatives)
+    -   [In evolution](#in-evolution)
+-   [Alternatives considered](#alternatives-considered)
+
+<!-- tocstop -->
+
+## Background
+
+It's common in programming languages to provide multiple, similar ways of doing
+the same thing. Sometimes this reflects the legacy of a language, and
+difficulties in evolving in ways that would require changes to
+developer-authored code, thereby retaining backwards compatibility. Other times
+it reflects a desire to provide both verbose and concise versions of the same
+syntax. We are concerned with both forms.
+
+We also are cautious about creating alternatives that may give rise to a
+[paradox of choice](https://en.wikipedia.org/wiki/The_Paradox_of_Choice),
+wherein options are similar enough that developers actively spend time analyzing
+tarde-offs, and the time spent that way outweighs the potential benefits of a
+correct choice.
+
+Where multiple, similar implementation options exist, it can sometimes give rise
+to style guidelines to indicate a preferential choice; sometimes because one
+option is objectively better, but sometimes because making a choice is better
+than not making one. Even with a style guide, developers may diverge in style by
+accident or intent, choosing different coding patterns simply because either
+option works. It can also become an issue as developers move between an
+organization that they need to learn a new style guide, and relearn habits.
+
+A couple examples of this in other languages are:
+
+-   In Perl,
+    ["There is more than one way to do it."](https://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it)
+-   In Python,
+    ["There should be one -- and preferably only one -- obvious way to do it."](https://www.python.org/dev/peps/pep-0020/)
+
+## Principle
+
+In Carbon, we will prefer providing only one way to do a given thing. That is,
+given a syntax scenario where multiple design options are available, we will
+tend to provide _one_ option rather than than providing several and letting
+users choose. This echoes Python's principle.
+
+Minimizing choices serves several goals:
+
+-   [Language tools](/docs/project/goals.md#language-tools-and-ecosystem) should
+    be easier to write and maintain with the lower language complexity implied
+    by less duplication of functionality.
+-   [Software and language evolution](/docs/project/goals.md#software-and-language-evolution)
+    processes should find it easier to both consider existing syntax and avoid
+    creation of new syntax conflicts.
+-   [Understandability of code](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write)
+    should be promoted if developers have less syntax they need to understand.
+    This can be expected to improve code quality and productivity so long as the
+    resulting code structures aren't overly complicated.
+
+By minimizing the overlap of language features, we hope to make work easier for
+both Carbon's maintainers and developers.
+
+## Applications of this principle
+
+We can observe the application of this principle by comparing several language
+features to C++. There, improving understandability is frequently the primary
+motivation:
+
+-   Where C++ allows logical operators to be written with either symbols (for
+    example, `&&`) or text (for example, `and`), Carbon will only support one
+    form (in this case, [text](/proposals/p0680.md)).
+-   Where C++ allows hexadecimal numeric literals to be either lowercase
+    (`0xaa`) or uppercase (`0xAA`), and with `x` optionally uppercase as well,
+    Carbon will only allow the [`0xAA` casing](/proposals/p0143.md).
+-   Where C++ provides both `struct` and `class` with the only difference is
+    access control defaults, Carbon will only provide one (`class`, albeit with
+    default public visibility diverging from C++).
+
+However, sometimes language tools are the primary motivation. For example, where
+C++ allows braces to be omitted for single-statement control flow blocks, Carbon
+will [require braces](/proposals/p0623.md). This offers a syntax simplification
+that should allow for better error detection.
+
+## Caveats
+
+### Specialized syntax
+
+Sometimes overlap will occur because a specialized syntax offers particular
+benefits, typically as a matter of convenience for either a common use-case or a
+particularly complex and important use-case. Some examples of why and where this
+occurs are:
+
+-   For [performance](/docs/projects/goals.md#performance-critical-software), it
+    may at times be necessary to provide a specialized syntax that better
+    supports optimization than a generic syntax.
+-   For
+    [understandability of code](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write),
+    there may be times that a particular use-case is common enough that
+    simplifying its syntax provides substantial benefit.
+    -   For example, `for (var x: auto in list)` could typically be written with
+        as a `while` loop, but range-based for loops are considered to improve
+        understandability. However, C++'s `for (;;)` syntax is sufficiently
+        close to `while` that we expect to use `while` to address the
+        corresponding use-cases.
+-   For
+    [migration and interoperability](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code),
+    it may be pragmatic to provide both an ideal way of doing things for new
+    Carbon code, and a separate approach that is more C++-compatible for
+    migration.
+    -   For example, consider generics and templates: generics are considered to
+        be the preferred form for new code, but templates are considered a
+        necessity for migration of C++ code. This is not an evolution situation
+        because we do not anticipate ever removing templates.
+
+### Non-obvious alternatives
+
+Echoing Python, there may be non-obvious alternative ways of doing a given
+thing, such as using `while (condition) { DoSomething(); break; }` in place of
+`if (condition) { DoSomething(); }`. As a more complex example, lambdas could be
+implemented using other code constructs; this would require significantly more
+code and hinder understandability.
+
+This kind of overlap may exist, but will hopefully be considered sufficiently
+non-idiomatic that examples won't be common in code. If a choice would not
+likely be based mainly on coding styles, it's likely sufficiently distinct that
+this principle won't apply.
+
+### In evolution
+
+For [evolution](/docs/project/goals.md#software-and-language-evolution), it will
+often be necessary to temporarily provide an "old" and "new" way of doing things
+simultaneously.
+
+For example, if renaming a language feature, it may be appropriate to provide
+the same functionality under two identifiers. However, one should be marked as
+deprecated and eventually removed. We should be cautious of adding new,
+overlapping features without a plan to remove the corresponding legacy version.
+
+## Alternatives considered
+
+-   [Provide multiple ways of doing a given thing](/proposals/p0829.md#provide-multiple-ways-of-doing-a-given-thing)

+ 1 - 0
proposals/README.md

@@ -71,5 +71,6 @@ request:
 -   [0731 - Generics details 2: adapters, associated types, parameterized interfaces](p0731.md)
 -   [0752 - `api` file default-`public`](p0752.md)
 -   [0777 - Inheritance](p0777.md)
+-   [0829 - One way principle](p0829.md)
 
 <!-- endproposals -->

+ 79 - 0
proposals/p0829.md

@@ -0,0 +1,79 @@
+# One way principle
+
+<!--
+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://github.com/carbon-language/carbon-lang/pull/829)
+
+<!-- toc -->
+
+## Table of contents
+
+-   [Problem](#problem)
+-   [Proposal](#proposal)
+-   [Alternatives considered](#alternatives-considered)
+    -   [Provide multiple ways of doing a given thing](#provide-multiple-ways-of-doing-a-given-thing)
+
+<!-- tocstop -->
+
+## Problem
+
+We have repeatedly run into cases where we could offer equivalent functionality
+multiple ways.
+
+## Proposal
+
+Add a principle noting the preference is to only provide one way of doing
+things.
+
+## Alternatives considered
+
+### Provide multiple ways of doing a given thing
+
+Carbon could focus on providing a lower bar for overlapping functionality,
+encouraging overlapping syntax. This could be considered as similar to Perl's
+["There is more than one way to do it."](https://en.wikipedia.org/wiki/There%27s_more_than_one_way_to_do_it).
+Overlapping syntax should still receive some scrutiny, but use-cases with small
+marginal benefits might be considered sufficient to create divergent syntax.
+
+For example:
+
+-   For matching C++ legacy:
+    -   We might include `for (;;)`.
+    -   We might re-add support for optional braces on `if` and similar.
+    -   We might support `class` and `struct` with their C++-equivalent default
+        visibility rules.
+    -   We might support both `and` and `&&`, `0xa` and `0XA`, etc.
+-   We might make `;` optional, as there's precedent in modern languages to do
+    so.
+-   Both templates and generics might be embraced with feature parity such that
+    both should be good solutions for generic programming problems, as much as
+    possible.
+
+It's worth noting Perl also has a related motto of "There is more than one way
+to do it, but sometimes consistency is not a bad thing either." It's best to
+avoid interpreting this alternative to the extreme: for example, this is not
+encouraging providing all of `extensible`, `extendable`, and `extendible` as
+equivalent keywords, as that is divergence with very minimal benefit
+(particularly `extendable` versus `extendible`).
+
+Advantages:
+
+-   More likely that developers will find syntax that they like.
+-   Can make it easier to migrate code because we can actively support a
+    C++-like dialect in addition to a more Carbon-centric dialect.
+
+Disadvantages:
+
+-   Developers would either accept personal styles, or create more style guides.
+    -   Either can be considered a language dialect, whether at the personal or
+        organizational level.
+-   Increases the difficulty of building syntax parsing and typo correction in
+    the language, as there are more options that need to be corrected between,
+    multiple of which may be valid in a given context.
+
+We are declining this alternative because we value the language simplicity
+provided by minimizing overlap of features.