Browse Source

Updated README.md (#1075)

Revised landing page, including updated README.

Co-authored-by: josh11b <josh11b@users.noreply.github.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Co-authored-by: Jon Meow <jperkins@google.com>
Wolff Dobson 4 years ago
parent
commit
31fa2608d4

+ 107 - 136
README.md

@@ -6,152 +6,123 @@ Exceptions. See /LICENSE for license information.
 SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 -->
 
-<!-- toc -->
+## **The Carbon Language project is an experiment exploring a future direction for the C++ programming language.**
 
-## Table of contents
+<p align="center">
+  <a href="#carbon-goals">Carbon goals</a> |
+  <a href="#carbon-and-c">Carbon and C++</a> |
+  <a href="#take-a-look">Take a look</a> |
+  <a href="#join-us">Join us</a>
+</p>
 
--   [Overview](#overview)
--   [What about other languages?](#what-about-other-languages)
--   [Project status](#project-status)
--   [What will make Carbon a compelling future path for C++?](#what-will-make-carbon-a-compelling-future-path-for-c)
--   [Contributing](#contributing)
+<a href="docs/images/snippets.md#quicksort">
+<img src="docs/images/quicksort_snippet.svg" align="right" width="575"
+     alt="Quicksort code in Carbon. Follow the link to read more.">
+</a>
 
-<!-- tocstop -->
+<!-- Don't let the text wrap too narrowly to the left of the above image. -->
+<div><img src="docs/images/bumper.png">
 
-## Overview
+**Fast and works with C++**</div>
 
-The Carbon Language project is an **_experiment_** to explore a possible,
-distant future for the C++ programming language. It is designed around a
-specific set of goals, priorities, and use cases:
+-   Performance matching C++ using LLVM, with low-level access to bits and
+    addresses
+-   Interoperate with your existing C++ code, from inheritance to templates
+-   Fast and scalable builds that work with your existing C++ build systems
+
+**Modern and evolving**
+
+-   Solid language foundations that are easy to learn, especially if you have
+    used C++
+-   Easy, tool-based upgrades between Carbon versions
+-   Safer fundamentals, and an incremental path towards a memory-safe subset
+
+**Welcoming open-source community**
+
+-   Clear goals and priorities with robust governance
+-   Community that works to be welcoming, inclusive, and friendly
+-   Batteries-included approach: compiler, libraries, docs, tools, package
+    manager, and more
+
+## Carbon goals
+
+We believe Carbon must support:
 
 1. Performance-critical software
 2. Software and language evolution
 3. Code that is easy to read, understand, and write
-4. Practical safety guarantees and testing mechanisms
+4. Practical safety and testing mechanisms
 5. Fast and scalable development
 6. Modern OS platforms, hardware architectures, and environments
 7. Interoperability with and migration from existing C++ code
 
-The first six of these represent a set of priorities for C++ shared by a
-significant subset of the C++ community, industry, and ecosystem. However, C++
-is increasingly constrained by a diverse set of concerns and priorities
-(including some that are irrelevant to or in opposition to these goals, such as
-ABI stability), and carries a significant historical legacy that makes it
-challenging to evolve effectively. The result is that these users struggle to
-meet our goals using C++ today, and that is unlikely to change in the near
-future. Carbon is an attempt to explore what it would look like to rapidly and
-systematically re-engineer C++ into a near optimal future state along the top
-six priorities, which nonetheless is still reachable through interoperability,
-tooling, automation, and incremental large-scale migration efforts.
-
-For more information, see [our goals document](docs/project/goals.md).
-
-## What about other languages?
-
-Other programming languages don't _currently_ address these needs effectively.
-They present interoperability, migration, and performance challenges that make
-it expensive and potentially impossible to migrate a large C++ code base. An
-approach which requires rewriting an entire binary at once would be infeasible.
-A large-scale migration must be incremental, meaning that interoperability and
-tool-assisted code rewrites are critical.
-
-There are projects for several languages to reduce obstacles affecting migration
-from C++. Some contributors to Carbon are also contributing to those efforts in
-parallel in order to understand all of the options in this space. TODO: write up
-a detailed analysis of these languages specifically through the lens of the
-above goals.
-
-One especially interesting aspect not addressed by the active and widely used
-languages that might serve this purpose is that they have not been designed
-specifically to enable migration from and interoperability with _today's_ C++.
-They don't build on top of C++'s _existing_ ecosystem. There are only a few
-significant examples of programming languages that center around incremental
-migration of large existing codebases. They are specifically designed to not
-require complete rewrites, new programming models, or building an entire new
-stack/ecosystem. However, there is no comparable option for C++ today:
-
--   JavaScript → TypeScript
--   Java → Kotlin
--   C++ → **???**
-
-Carbon explores what it would look like to fill this gap and align it with the
-above priorities.
-
-## Project status
-
-**The project is just getting started.** Everything is at a very early stage. If
-you are hoping to see lots of concrete ideas and plans, you'll probably want to
-check back in 6 months to a year. At this stage, we're just beginning to lay the
-foundations.
-
-It is important to understand that **this is a science experiment**, not a
-production effort. There are several initial questions that we want to explore
-and answer with this experiment:
-
--   Can we deliver a design and implementation that is familiar and compelling
-    to C++ programmers and supports our goals?
--   How seamless and effective can we make interoperability?
--   How easy and scalable can we make migration?
--   Will a significant segment of the ecosystem and industry adopt Carbon given
-    these tradeoffs?
-
-We are committed to learning the answers to these questions, but that may well
-not result in a production language. There is a very real chance that this
-project will never leave the experimental phase. Anyone considering contributing
-or using Carbon should be extremely mindful of that fact: **core contributors
-may abandon the experiment**.
-
-While we may sometimes refer to Carbon as a language, it is crucial to
-understand that the goals of this science experiment are not about new
-languages, but about how to move today's C++ forward effectively. For example, a
-near optimal outcome would be to convince the C++ community to adopt this as its
-official path forward.
-
-## What will make Carbon a compelling future path for C++?
-
-We hope that eventually Carbon will provide **significant advantages compared to
-today's C++**. Areas where we think we can most dramatically improve C++ for
-both software systems and developers are:
-
--   A cohesive and principled language design, even when supporting advanced
-    features.
--   Making common coding patterns safe by default whenever practical, with
-    affordable security mitigations available for any unsafety.
-    -   We will provide static checks for as many safety issues as we can by
-        default.
-    -   We will provide a spectrum of build modes with different trade-offs
-        between dynamic safety and performance. For example:
-        -   The default build mode will include as many dynamic safety checks as
-            we can while keeping the software's performance reasonable for
-            normal development, testing, and debugging.
-        -   Release builds will favor performance, with opt-in dynamic safety
-            checks and security mitigations for applications with higher
-            security requirements.
-    -   Over time, we also expect to both track and drive research into
-        increasing the degree of safety available without compromising our other
-        goals.
--   Keeping our core language implementation simple, fast, and easily extended
-    in ways that will make all of our language tools better.
--   Providing an effective, open, and inclusive language evolution process
-    aligned with our goals and priorities.
-
-Carbon will also aim to allow a single layer of a legacy C++ library stack to be
-migrated to Carbon, without migrating the code above or below. This will make it
-easier for developers to start using Carbon. Key features underpin Carbon's
-compatibility and interoperability with C++:
-
--   The memory, execution, and threading model will be compatible with C++.
--   Access to existing C++ types, interfaces, and even templates will be
-    provided as part of the core language.
--   Carbon will be able to export types, interfaces, and templates for
-    consumption by C++.
-
-**However, Carbon's approach still requires a nearly complete re-engineering of
-the language as well as large-scale migration for users.** This is extremely
-expensive, and so the bar for Carbon to be a compelling direction for C++ is
-very high.
-
-## Contributing
-
-Please see our [contributing guidelines](CONTRIBUTING.md) for information about
-Carbon development.
+Many languages share these goals, and they can often be addressed independently
+in a language's design. For the Carbon project, they are prioritized in that
+order to help make clear what tradeoffs we intend to make.
+
+Read the [language overview](docs/design/) for more on the language design
+itself, and the [goals](docs/project/goals.md) for more on these values.
+
+## Carbon and C++
+
+If you're already a C++ developer, Carbon should have a short learning curve. It
+is built out of a consistent set of language constructs that should feel
+familiar. C++ code like this:
+
+<a href="docs/images/snippets.md#c">
+<img src="docs/images/cpp_snippet.svg" width="600"
+     alt="A snippet of C++ code. Follow the link to read it.">
+</a>
+
+can be mechanically transformed to Carbon, like so:
+
+<a href="docs/images/snippets.md#carbon">
+<img src="docs/images/carbon_snippet.svg" width="600"
+     alt="A snippet of converted Carbon code. Follow the link to read it.">
+</a>
+
+without loss of performance or readability. Yet, translating C++ to Carbon isn't
+necessary; you can call Carbon from C++ without overhead and the other way
+around. You can port your library to Carbon, or write new Carbon on top of your
+existing C++ investment. Carbon won't add a sea of dependencies or slow down
+your performance-critical code. For example:
+
+<a href="docs/images/snippets.md#mixed">
+<img src="docs/images/mixed_snippet.svg" width="600"
+     alt="A snippet of mixed Carbon and C++ code. Follow the link to read it.">
+</a>
+
+In terms of safety, any language that can seamlessly call C++ will not be
+perfectly safe in every dimension. However, Carbon's design encourages you to
+use safe constructs where possible.
+
+Ultimately, C++ carries a significant historical legacy, including around ABI
+stability, that constrains its evolution. Carbon is an attempt to set a new
+direction for C++ developers that allows for fast development, flexibility, and
+delight without sacrificing performance, interoperability, and familiarity.
+
+Read more about
+[C++ interop in Carbon](docs/design/interoperability/philosophy_and_goals.md).
+
+## Take a look
+
+Learn more about Carbon's design:
+
+-   [Project goals](docs/project/goals.md)
+-   [Language overview](docs/design/)
+-   [Executable semantics](executable_semantics/)
+
+## Join us
+
+Carbon is committed to a welcoming and inclusive environment where everyone can
+contribute.
+
+-   To watch for major release announcements, subscribe to
+    [our Carbon release post on GitHub](https://github.com/carbon-language/carbon-lang/discussions/1020)
+    and [star carbon-lang](https://github.com/carbon-language/carbon-lang).
+-   To join the design discussion, join our
+    [our Github forum](https://github.com/carbon-language/carbon-lang/discussions).
+-   See our [code of conduct](CODE_OF_CONDUCT.md) and
+    [contributing guidelines](CONTRIBUTING.md) for information about the Carbon
+    development community.
+-   We discuss Carbon on Discord; a public link will be forthcoming.

BIN
docs/images/bumper.png


+ 160 - 0
docs/images/carbon_snippet.svg

@@ -0,0 +1,160 @@
+<svg fill="white" viewBox="0 0 650 238" width="650" height="238" xmlns="http://www.w3.org/2000/svg">
+    <foreignObject width="100%" height="100%">
+<style>
+    .div-3 {
+        background-color: #EEEEEE;
+        padding: 5px;
+	padding-left: 30px;
+	margin: 0px;
+    }
+    pre {
+       display: block;
+       font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
+       white-space: pre;
+       width: 100%;
+       margin: 0px;
+    }
+    .pl-c /* comment, punctuation.definition.comment, string.comment */ {
+        color: #6a737d;
+    }
+
+    .pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header, meta.output */,
+    .pl-s .pl-v /* string variable */ {
+        color: #005cc5;
+    }
+
+    .pl-e /* entity */,
+    .pl-en /* entity.name */ {
+      color: #6f42c1;
+    }
+
+    .pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
+    .pl-s .pl-s1 /* string source */ {
+      color: #24292e;
+    }
+
+    .pl-ent /* entity.name.tag, markup.quote */ {
+      color: #22863a;
+    }
+
+    .pl-k /* keyword, storage, storage.type */ {
+      color: #d73a49;
+    }
+
+.pl-s /* string */,
+.pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */,
+.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
+.pl-sr /* string.regexp */,
+.pl-sr .pl-cce /* string.regexp constant.character.escape */,
+.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
+.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
+  color: #032f62;
+}
+
+.pl-v /* variable */,
+.pl-smw /* sublimelinter.mark.warning */ {
+  color: #e36209;
+}
+
+.pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ {
+  color: #b31d28;
+}
+
+.pl-ii /* invalid.illegal */ {
+  color: #fafbfc;
+  background-color: #b31d28;
+}
+
+.pl-c2 /* carriage-return */ {
+  color: #fafbfc;
+  background-color: #d73a49;
+}
+
+.pl-c2::before /* carriage-return */ {
+  content: "^M";
+}
+
+.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
+  font-weight: bold;
+  color: #22863a;
+}
+
+.pl-ml /* markup.list */ {
+  color: #735c0f;
+}
+
+.pl-mh /* markup.heading */,
+.pl-mh .pl-en /* markup.heading entity.name */,
+.pl-ms /* meta.separator */ {
+  font-weight: bold;
+  color: #005cc5;
+}
+
+.pl-mi /* markup.italic */ {
+  font-style: italic;
+  color: #24292e;
+}
+
+.pl-mb /* markup.bold */ {
+  font-weight: bold;
+  color: #24292e;
+}
+
+.pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ {
+  color: #b31d28;
+  background-color: #ffeef0;
+}
+
+.pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ {
+  color: #22863a;
+  background-color: #f0fff4;
+}
+
+.pl-mc /* markup.changed, punctuation.definition.changed */ {
+  color: #e36209;
+  background-color: #ffebda;
+}
+
+.pl-mi2 /* markup.ignored, markup.untracked */ {
+  color: #f6f8fa;
+  background-color: #005cc5;
+}
+
+.pl-mdr /* meta.diff.range */ {
+  font-weight: bold;
+  color: #6f42c1;
+}
+
+.pl-ba /* brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote */ {
+  color: #586069;
+}
+
+.pl-sg /* sublimelinter.gutter-mark */ {
+  color: #959da5;
+}
+
+.pl-corl /* constant.other.reference.link, string.other.link */ {
+  text-decoration: underline;
+  color: #032f62;
+}
+}
+</style>
+<div xmlns="http://www.w3.org/1999/xhtml" class="div-3">
+
+<pre>
+<span class="pl-k">import</span> Console;
+<span class="pl-c"><span class="pl-c">//</span> Carbon</span>
+<span class="pl-k">void</span> <span class="pl-en">PrintWithTotal</span>(v: Vector(u64)) {
+  <span class="pl-k">var</span> sum: <span class="pl-c1">u64</span> = <span class="pl-c1">0</span>;
+  <span class="pl-k">for</span> (e: <span class="pl-c1">u64</span> in v) {
+    sum += e;
+    Console.<span class="pl-c1">Print</span>(e, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>);
+  }
+  Console.<span class="pl-c1">Print</span>(<span class="pl-s"><span class="pl-pds">"</span>Total: <span class="pl-pds">"</span></span>, sum, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>);
+}
+
+</pre>
+
+        </div>
+    </foreignObject>
+</svg>

+ 162 - 0
docs/images/cpp_snippet.svg

@@ -0,0 +1,162 @@
+<svg fill="white" viewBox="0 0 650 254" width="650" height="254" xmlns="http://www.w3.org/2000/svg">
+    <foreignObject width="100%" height="100%">
+<style>
+    .div-3 {
+        background-color: #EEEEEE;
+        padding: 5px;
+	padding-left: 30px;
+	margin: 0px;
+    }
+    pre {
+       display: block;
+       font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
+       white-space: pre;
+       width: 100%;
+       margin: 0px;
+    }
+    .pl-c /* comment, punctuation.definition.comment, string.comment */ {
+        color: #6a737d;
+    }
+
+    .pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header, meta.output */,
+    .pl-s .pl-v /* string variable */ {
+        color: #005cc5;
+    }
+
+    .pl-e /* entity */,
+    .pl-en /* entity.name */ {
+      color: #6f42c1;
+    }
+
+    .pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
+    .pl-s .pl-s1 /* string source */ {
+      color: #24292e;
+    }
+
+    .pl-ent /* entity.name.tag, markup.quote */ {
+      color: #22863a;
+    }
+
+    .pl-k /* keyword, storage, storage.type */ {
+      color: #d73a49;
+    }
+
+.pl-s /* string */,
+.pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */,
+.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
+.pl-sr /* string.regexp */,
+.pl-sr .pl-cce /* string.regexp constant.character.escape */,
+.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
+.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
+  color: #032f62;
+}
+
+.pl-v /* variable */,
+.pl-smw /* sublimelinter.mark.warning */ {
+  color: #e36209;
+}
+
+.pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ {
+  color: #b31d28;
+}
+
+.pl-ii /* invalid.illegal */ {
+  color: #fafbfc;
+  background-color: #b31d28;
+}
+
+.pl-c2 /* carriage-return */ {
+  color: #fafbfc;
+  background-color: #d73a49;
+}
+
+.pl-c2::before /* carriage-return */ {
+  content: "^M";
+}
+
+.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
+  font-weight: bold;
+  color: #22863a;
+}
+
+.pl-ml /* markup.list */ {
+  color: #735c0f;
+}
+
+.pl-mh /* markup.heading */,
+.pl-mh .pl-en /* markup.heading entity.name */,
+.pl-ms /* meta.separator */ {
+  font-weight: bold;
+  color: #005cc5;
+}
+
+.pl-mi /* markup.italic */ {
+  font-style: italic;
+  color: #24292e;
+}
+
+.pl-mb /* markup.bold */ {
+  font-weight: bold;
+  color: #24292e;
+}
+
+.pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ {
+  color: #b31d28;
+  background-color: #ffeef0;
+}
+
+.pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ {
+  color: #22863a;
+  background-color: #f0fff4;
+}
+
+.pl-mc /* markup.changed, punctuation.definition.changed */ {
+  color: #e36209;
+  background-color: #ffebda;
+}
+
+.pl-mi2 /* markup.ignored, markup.untracked */ {
+  color: #f6f8fa;
+  background-color: #005cc5;
+}
+
+.pl-mdr /* meta.diff.range */ {
+  font-weight: bold;
+  color: #6f42c1;
+}
+
+.pl-ba /* brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote */ {
+  color: #586069;
+}
+
+.pl-sg /* sublimelinter.gutter-mark */ {
+  color: #959da5;
+}
+
+.pl-corl /* constant.other.reference.link, string.other.link */ {
+  text-decoration: underline;
+  color: #032f62;
+}
+}
+</style>
+<div xmlns="http://www.w3.org/1999/xhtml" class="div-3">
+
+<pre>
+#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>vector<span class="pl-pds">&gt;</span></span>
+#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds">&lt;</span>iostream<span class="pl-pds">&gt;</span></span>
+<span class="pl-c"><span class="pl-c">//</span> C++</span>
+<span class="pl-k">void</span> <span class="pl-en">PrintWithTotal</span>(<span class="pl-k">const</span> std::vector&lt;<span class="pl-c1">uint64_t</span>&gt;&amp; v) {
+  <span class="pl-c1">uint64_t</span> sum = <span class="pl-c1">0</span>;
+  <span class="pl-k">for</span> (<span class="pl-c1">uint64_t</span> e in v) {
+    sum += e;
+    cout &lt;&lt; e &lt;&lt; <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>;
+  }
+  cout &lt;&lt; <span class="pl-s"><span class="pl-pds">"</span>Total: <span class="pl-pds">"</span></span> &lt;&lt;  sum &lt;&lt; <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>;
+}
+
+
+</pre>
+
+        </div>
+    </foreignObject>
+</svg>

+ 161 - 0
docs/images/mixed_snippet.svg

@@ -0,0 +1,161 @@
+<svg fill="white" viewBox="0 0 650 254" width="650" height="254" xmlns="http://www.w3.org/2000/svg">
+    <foreignObject width="100%" height="100%">
+<style>
+    .div-3 {
+        background-color: #EEEEEE;
+        padding: 5px;
+	padding-left: 30px;
+	margin: 0px;
+    }
+    pre {
+       display: block;
+       font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
+       white-space: pre;
+       width: 100%;
+       margin: 0px;
+    }
+    .pl-c /* comment, punctuation.definition.comment, string.comment */ {
+        color: #6a737d;
+    }
+
+    .pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header, meta.output */,
+    .pl-s .pl-v /* string variable */ {
+        color: #005cc5;
+    }
+
+    .pl-e /* entity */,
+    .pl-en /* entity.name */ {
+      color: #6f42c1;
+    }
+
+    .pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
+    .pl-s .pl-s1 /* string source */ {
+      color: #24292e;
+    }
+
+    .pl-ent /* entity.name.tag, markup.quote */ {
+      color: #22863a;
+    }
+
+    .pl-k /* keyword, storage, storage.type */ {
+      color: #d73a49;
+    }
+
+.pl-s /* string */,
+.pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */,
+.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
+.pl-sr /* string.regexp */,
+.pl-sr .pl-cce /* string.regexp constant.character.escape */,
+.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
+.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
+  color: #032f62;
+}
+
+.pl-v /* variable */,
+.pl-smw /* sublimelinter.mark.warning */ {
+  color: #e36209;
+}
+
+.pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ {
+  color: #b31d28;
+}
+
+.pl-ii /* invalid.illegal */ {
+  color: #fafbfc;
+  background-color: #b31d28;
+}
+
+.pl-c2 /* carriage-return */ {
+  color: #fafbfc;
+  background-color: #d73a49;
+}
+
+.pl-c2::before /* carriage-return */ {
+  content: "^M";
+}
+
+.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
+  font-weight: bold;
+  color: #22863a;
+}
+
+.pl-ml /* markup.list */ {
+  color: #735c0f;
+}
+
+.pl-mh /* markup.heading */,
+.pl-mh .pl-en /* markup.heading entity.name */,
+.pl-ms /* meta.separator */ {
+  font-weight: bold;
+  color: #005cc5;
+}
+
+.pl-mi /* markup.italic */ {
+  font-style: italic;
+  color: #24292e;
+}
+
+.pl-mb /* markup.bold */ {
+  font-weight: bold;
+  color: #24292e;
+}
+
+.pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ {
+  color: #b31d28;
+  background-color: #ffeef0;
+}
+
+.pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ {
+  color: #22863a;
+  background-color: #f0fff4;
+}
+
+.pl-mc /* markup.changed, punctuation.definition.changed */ {
+  color: #e36209;
+  background-color: #ffebda;
+}
+
+.pl-mi2 /* markup.ignored, markup.untracked */ {
+  color: #f6f8fa;
+  background-color: #005cc5;
+}
+
+.pl-mdr /* meta.diff.range */ {
+  font-weight: bold;
+  color: #6f42c1;
+}
+
+.pl-ba /* brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote */ {
+  color: #586069;
+}
+
+.pl-sg /* sublimelinter.gutter-mark */ {
+  color: #959da5;
+}
+
+.pl-corl /* constant.other.reference.link, string.other.link */ {
+  text-decoration: underline;
+  color: #032f62;
+}
+}
+</style>
+<div xmlns="http://www.w3.org/1999/xhtml" class="div-3">
+
+<pre>
+<span class="pl-k">import</span> Console;
+<span class="pl-k">import</span> Cpp &lt;vector&gt;;
+<span class="pl-c"><span class="pl-c">//</span> Carbon and C++ interop</span>
+<span class="pl-k">void</span> <span class="pl-en">PrintWithTotal</span>(v: Cpp.std.vector(Cpp.<span class="pl-c1">uint64_t</span>)) {
+  <span class="pl-k">var</span> sum: <span class="pl-c1">u64</span> = <span class="pl-c1">0</span>;
+  <span class="pl-k">for</span> (e: Cpp.<span class="pl-c1">uint64_t</span> in v) {
+    sum += e;
+    Console.<span class="pl-c1">Print</span>(e, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>)
+  }
+  Console.<span class="pl-c1">Print</span>(<span class="pl-s"><span class="pl-pds">"</span>Total: <span class="pl-pds">"</span></span>, sum, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>);
+}
+
+</pre>
+
+        </div>
+    </foreignObject>
+</svg>

+ 168 - 0
docs/images/quicksort_snippet.svg

@@ -0,0 +1,168 @@
+<svg fill="white" viewBox="0 0 575 424" width="575" height="424" xmlns="http://www.w3.org/2000/svg">
+    <foreignObject width="100%" height="100%">
+<style>
+    .div-3 {
+        background-color: #EEEEEE;
+        padding: 5px;
+	padding-left: 30px;
+	margin: 0px;
+    }
+    pre {
+       display: block;
+       font-family: ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;
+       white-space: pre;
+       width: 100%;
+       margin: 0px;
+    }
+    .pl-c /* comment, punctuation.definition.comment, string.comment */ {
+        color: #6a737d;
+    }
+
+    .pl-c1 /* constant, entity.name.constant, variable.other.constant, variable.language, support, meta.property-name, support.constant, support.variable, meta.module-reference, markup.raw, meta.diff.header, meta.output */,
+    .pl-s .pl-v /* string variable */ {
+        color: #005cc5;
+    }
+
+    .pl-e /* entity */,
+    .pl-en /* entity.name */ {
+      color: #6f42c1;
+    }
+
+    .pl-smi /* variable.parameter.function, storage.modifier.package, storage.modifier.import, storage.type.java, variable.other */,
+    .pl-s .pl-s1 /* string source */ {
+      color: #24292e;
+    }
+
+    .pl-ent /* entity.name.tag, markup.quote */ {
+      color: #22863a;
+    }
+
+    .pl-k /* keyword, storage, storage.type */ {
+      color: #d73a49;
+    }
+
+.pl-s /* string */,
+.pl-pds /* punctuation.definition.string, source.regexp, string.regexp.character-class */,
+.pl-s .pl-pse .pl-s1 /* string punctuation.section.embedded source */,
+.pl-sr /* string.regexp */,
+.pl-sr .pl-cce /* string.regexp constant.character.escape */,
+.pl-sr .pl-sre /* string.regexp source.ruby.embedded */,
+.pl-sr .pl-sra /* string.regexp string.regexp.arbitrary-repitition */ {
+  color: #032f62;
+}
+
+.pl-v /* variable */,
+.pl-smw /* sublimelinter.mark.warning */ {
+  color: #e36209;
+}
+
+.pl-bu /* invalid.broken, invalid.deprecated, invalid.unimplemented, message.error, brackethighlighter.unmatched, sublimelinter.mark.error */ {
+  color: #b31d28;
+}
+
+.pl-ii /* invalid.illegal */ {
+  color: #fafbfc;
+  background-color: #b31d28;
+}
+
+.pl-c2 /* carriage-return */ {
+  color: #fafbfc;
+  background-color: #d73a49;
+}
+
+.pl-c2::before /* carriage-return */ {
+  content: "^M";
+}
+
+.pl-sr .pl-cce /* string.regexp constant.character.escape */ {
+  font-weight: bold;
+  color: #22863a;
+}
+
+.pl-ml /* markup.list */ {
+  color: #735c0f;
+}
+
+.pl-mh /* markup.heading */,
+.pl-mh .pl-en /* markup.heading entity.name */,
+.pl-ms /* meta.separator */ {
+  font-weight: bold;
+  color: #005cc5;
+}
+
+.pl-mi /* markup.italic */ {
+  font-style: italic;
+  color: #24292e;
+}
+
+.pl-mb /* markup.bold */ {
+  font-weight: bold;
+  color: #24292e;
+}
+
+.pl-md /* markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted */ {
+  color: #b31d28;
+  background-color: #ffeef0;
+}
+
+.pl-mi1 /* markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted */ {
+  color: #22863a;
+  background-color: #f0fff4;
+}
+
+.pl-mc /* markup.changed, punctuation.definition.changed */ {
+  color: #e36209;
+  background-color: #ffebda;
+}
+
+.pl-mi2 /* markup.ignored, markup.untracked */ {
+  color: #f6f8fa;
+  background-color: #005cc5;
+}
+
+.pl-mdr /* meta.diff.range */ {
+  font-weight: bold;
+  color: #6f42c1;
+}
+
+.pl-ba /* brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote */ {
+  color: #586069;
+}
+
+.pl-sg /* sublimelinter.gutter-mark */ {
+  color: #959da5;
+}
+
+.pl-corl /* constant.other.reference.link, string.other.link */ {
+  text-decoration: underline;
+  color: #032f62;
+}
+}
+</style>
+<div xmlns="http://www.w3.org/1999/xhtml" class="div-3">
+
+  <pre>
+fn <span class="pl-c1">Partition</span>[T:! Comparable &amp; Movable](s: Span(T))
+     -&gt; <span class="pl-c1">i32</span> {
+  <span class="pl-k">var</span> i: <span class="pl-c1">i32</span> = -<span class="pl-c1">1</span>;
+
+  <span class="pl-k">for</span> (j: <span class="pl-c1">i32</span> in s.<span class="pl-c1">Indices</span>()) {
+    <span class="pl-k">if</span> (s[j] &lt;= s.<span class="pl-c1">Last</span>()) {
+      ++i;
+      <span class="pl-c1">Swap</span>(&amp;s[i], &amp;s[j]);
+    }
+  }
+  <span class="pl-k">return</span> i;
+}
+
+fn <span class="pl-c1">QuickSort</span>[T:! Comparable &amp; Movable](s: Span(T)) {
+  <span class="pl-k">if</span> (s.<span class="pl-c1">Length</span>() &lt;= <span class="pl-c1">1</span>) { <span class="pl-k">return</span>; }
+  <span class="pl-k">let</span> p: <span class="pl-c1">i32</span> = <span class="pl-c1">Partition</span>(s);
+  <span class="pl-c1">QuickSort</span>(s.<span class="pl-c1">Sub</span>(<span class="pl-c1">0</span>, p - <span class="pl-c1">1</span>));
+  <span class="pl-c1">QuickSort</span>(s.<span class="pl-c1">Sub</span>(p + <span class="pl-c1">1</span>));
+}
+
+  </pre>
+        </div>
+    </foreignObject>
+</svg>

+ 82 - 0
docs/images/snippets.md

@@ -0,0 +1,82 @@
+# Front page snippets for Carbon
+
+<!--
+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
+-->
+
+## Quicksort
+
+A sample of quicksort in Carbon.
+
+```cpp
+fn Partition[T:! Comparable & Movable](s: Span(T))
+     -> i32 {
+  var i: i32 = -1;
+
+  for (j: i32 in s.Indices()) {
+    if (s[j] <= s.Last()) {
+      ++i;
+      Swap(&s[i], &s[j]);
+    }
+  }
+  return i;
+}
+
+fn QuickSort[T:! Comparable & Movable](s: Span(T)) {
+  if (s.Length() <= 1) { return; }
+  let p: i32 = Partition(s);
+  QuickSort(s.Sub(0, p - 1));
+  QuickSort(s.Sub(p + 1));
+}
+```
+
+## Carbon and C++
+
+### C++
+
+```cpp
+#include <vector>
+#include <iostream>
+// C++
+void PrintWithTotal(const std::vector<uint64_t>& v) {
+  uint64_t sum = 0;
+  for (uint64_t e in v) {
+    sum += e;
+    cout << e << "\n";
+  }
+  cout << "Total: " <<  sum << "\n";
+}
+```
+
+### Carbon
+
+```cpp
+import Console;
+// Carbon
+void PrintWithTotal(v: Vector(u64)) {
+  var sum: u64 = 0;
+  for (e: u64 in v) {
+    sum += e;
+    Console.Print(e, "\n");
+  }
+  Console.Print("Total: ", sum, "\n")
+}
+```
+
+### Mixed
+
+```cpp
+import Console;
+import Cpp <vector>;
+// Carbon and C++ interop
+void PrintWithTotal(v: Cpp.std.vector(Cpp.uint64_t)) {
+  var sum: u64 = 0;
+  for (e: Cpp.uint64_t in v) {
+    sum += e;
+    Console.Print(e, "\n");
+  }
+  Console.Print("Total: ", sum, "\n");
+}
+```