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

RFC: Finalizing more naming conventions #430

Closed
Closed
Changes from all 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
83 changes: 83 additions & 0 deletions text/0000-finalizing-naming-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
- Start Date: 2014-11-02
- RFC PR: (leave this empty)
- Rust Issue: (leave this empty)

# Summary

This conventions RFC tweaks and finalizes a few long-running de facto
conventions, including capitalization/underscores, and the role of the `unwrap` method.

See [this RFC](https://github.com/rust-lang/rfcs/pull/328) for a competing proposal for `unwrap`.

# Motivation

This is part of the ongoing conventions formalization process. The
conventions described here have been loosely followed for a long time,
but this RFC seeks to nail down a few final details and make them
official.

# Detailed design

## General naming conventions

In general, Rust tends to use `CamelCase` for "type-level" constructs
(types and traits) and `snake_case` for "value-level" constructs. More
precisely, the proposed (and mostly followed) conventions are:

| Item | Convention |
| ---- | ---------- |
| Crates | `snake_case` (but prefer single word) |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the past we've discussed how "foo-bar" is somewhat more aesthetically pleasing than "foo_bar" when looking at package names. I do think that this convention will have large ramifications on the contents of crates.io and cargo in general, so just wanna make sure we're sure about this!

If we go with snake_case, then we probably want to remove the quotes around extern crate "foo" as bar as they kinda only exist today to allow dashes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could make them optional, that is, extern crate foo as bar and extern crate "foo" as bar. (If we remove support for strings, then we essentially require that crates have valid identifiers as names, and so should probably have the compiler enforce this?)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally prefer crate-name and then importing as a shorter name for crates that must be multiple words, though single words is strongly preferable. I think this works because they will usually be imported as a single word, i.e. extern crate "replace-map" as rmap; // from iron which is much nicer at the usage site than something like raw_trait_object::vtable(..).

| Modules | `snake_case` |
| Types | `CamelCase` |
| Traits | `CamelCase` |
| Enum variants | `CamelCase` |
| Functions | `snake_case` |
| Methods | `snake_case` |
| General constructors | `new` or `new_with_more_details` |
| Conversion constructors | `from_some_other_type` |
| Local variables | `snake_case` |
| Static variables | `SCREAMING_SNAKE_CASE` |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constants as well, right?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should consider CamelCase for constants, since SCREAMING_SNAKE_CASE is extremely abrasive to look at and it more clearly demonstrates the difference.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that there are precedents in both directions here, and I'm not sure it's clear that we should draw a distinction between these two kinds of variables.

Looking around, we've got:

I'll also point out that "SCREAMING_SNAKE_CASE" is abrasive probably because it has the word "screaming" in all caps. Something like MAX_WIDTH vs MaxWidth seems less abrasive to me

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to use enums to represent keys in a termbox-like console input library, but it turns out that Ctrl-I and Tab keys map to the same escape sequence so I'll have to use CTRL_I and TAB instead of CtrlI and Tab now if I want to use it in a match :(

| Type parameters | concise `CamelCase`, usually single uppercase letter: `T` |
| Lifetimes | short, lowercase: `'a` |

### Fine points

In `CamelCase`, acronyms count as one word: use `Uuid` rather than `UUID`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That looks not pretty... I prefer UUID. Why/when was this decided?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After going through the thread, I'm glad they went with Uuid. Thanks for the links.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's where all the pain were started...


In `snake_case` or `SCREAMING_SNAKE_CASE`, a "word" should never
consist of a single letter unless it is the last "word". So, we have
`btree_map` rather than `b_tree_map`, but `PI_2` rather than `PI2`.

## `unwrap`, `into_foo` and `into_inner`

There has been a [long](https://github.com/mozilla/rust/issues/13159)
[running](https://github.com/rust-lang/rust/pull/16436)
[debate](https://github.com/rust-lang/rust/pull/16436)
[about](https://github.com/rust-lang/rfcs/pull/328) the name of the
`unwrap` method found in `Option` and `Result`, but also a few other
standard library types. Part of the problem is that for some types
(e.g. `BufferedReader`), `unwrap` will never panic; but for `Option`
and `Result` calling `unwrap` is akin to asserting that the value is
`Some`/`Ok`.

There's basic agreement that we should have an unambiguous term for
the `Option`/`Result` version of `unwrap`. Proposals have included
`assert`, `ensure`, `expect`, `unwrap_or_panic` and others; see the
links above for extensive discussion. No clear consensus has emerged.

This RFC proposes a simple way out: continue to call the methods
`unwrap` for `Option` and `Result`, and rename *other* uses of
`unwrap` to follow conversion conventions. Whenever possible, these
panic-free unwrapping operations should be `into_foo` for some
concrete `foo`, but for generic types like `RefCell` the name
`into_inner` will suffice. By convention, these `into_` methods cannot
panic; and by (proposed) convention, `unwrap` should be reserved for
an `into_inner` conversion that *can*.

# Drawbacks

Not really applicable; we need to finalize these conventions.

# Unresolved questions

Are there remaining subtleties about the rules here that should be clarified?