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

Naming conventions for Carbon-provided features #750

Closed
jonmeow opened this issue Aug 13, 2021 · 5 comments
Closed

Naming conventions for Carbon-provided features #750

jonmeow opened this issue Aug 13, 2021 · 5 comments
Labels
leads question A question for the leads team

Comments

@jonmeow
Copy link
Contributor

jonmeow commented Aug 13, 2021

What naming conventions should be used for Carbon-provided features?

Where I think we have consensus:

Where I think there's not an established choice:

  • Bool/bool, or True/true, explicitly deferred by pick names for fixed-size integer types #543
    • Note, this may not come from the prelude, which is expected to be written as Carbon code: it may be more intrinsic so that while and other keywords can easily handle it.
  • In class discussions, Self/self and Super/super
  • In general, how should features provided by the prelude be named?
    • What about functions on these types? For example, with String/string, would we write IsEmpty or is_empty?

I've come up with one easily summarized rule that's consistent with i32:

  • Anything language-provided without needing an import is always lower_snake_case.
    • bool, true, self, super, string.is_empty()
  • As above, but prelude class members follow standard naming conventions.
    • bool, true, self, super, string.IsEmpty()

I have a couple that are inconsistent with i32, although numeric types could be special-cased:

  • Prelude entries use standard naming conventions, everything else uses lower_snake_case
    • Bool/bool, True/true is implementation-dependent
    • self, super (because they can't be in prelude)
    • String.IsEmpty()
  • keywords use lower_snake_case, everything else uses standard naming conventions
    • Bool/bool, True/true is implementation-dependent
    • Self, Super (assuming they work as class-scoped aliases, unless we consider them keywords)
    • String.IsEmpty()

There's of course always the option of saying that non-keyword names are rare and can be decided on a case-by-case basis; we don't need a standard naming convention.

Thoughts?

I don't think this is blocking things, but it'd be nice to have it resolved as these are going to be put into a lot of early code/docs/examples, by their nature.

@chandlerc
Copy link
Contributor

What naming conventions should be used for Carbon-provided features?

My preferred option:

  • keywords use lower_snake_case, everything else uses standard naming conventions

    • Bool/bool, True/true is implementation-dependent
    • Self, Super (assuming they work as class-scoped aliases, unless we consider them keywords)
    • String.IsEmpty()

Just a collection of my thoughts on the various points you raised:

  • I think there is no lost consistency with i32 because those aren't keywords, they are type literals: i followed by a series of decimal digits. We use lowercase for the syntax part of literals elsewhere: 0x10, 123.456e789, 0x1.2p123. The digits are uppercase, and the syntax is lowercase. The i, u, and f components of the type literals follow this pattern.

  • I think we should pick bool and true, defining them as keywords.

    • I think you gave one good rationale: language constructs fundamentally rely on them like while.
    • Another rationale is that I think they should be handled as keywords -- no scope, no shadowing, no qualified naming.
    • They also are heavily used by users, so the name IMO does matter here.
    • true and false I think will be expected by C++ developers and re-training that seems expensive with little to no benefit.
    • Mismatch between the type and true I think will similarly cause confusion for C++ developers for no benefit.
  • I think we should use Self even where it really requires special handling and can't "just" be an alias.

    • The name should really behave like a normal name for the purpose of name lookup. For example, I can imagine using qualified name lookup to find Self. This makes it behave much less like a keyword IMO.
    • We could still choose to reject a name Self outside of a class as confusing, even if we don't consider it a keyword per se.
  • I think I like String and other names in the prelude having "normal" conventions.

    • They really shouldn't be keyword-like in behavior -- it should be ok to use qualified names with components overlapping. It should just be unqualified String that finds the type from the prelude.

@geoffromer
Copy link
Contributor

  • I think we should pick bool and true, defining them as keywords.

Wouldn't that make bool the only type in Carbon that doesn't have a name (in the "name lookup" sense of the word)? That seems like a weird irregularity that might have unwelcome consequences.

@chandlerc
Copy link
Contributor

  • I think we should pick bool and true, defining them as keywords.

Wouldn't that make bool the only type in Carbon that doesn't have a name (in the "name lookup" sense of the word)? That seems like a weird irregularity that might have unwelcome consequences.

I would make bool a keyword alias to Carbon.Bool or some such, similar to i32 but without any magic translation of the integer.

@chandlerc
Copy link
Contributor

Looks like we have consensus on my suggested pattern in #750 (comment).

Some terminology that came up in discussion:

  • Prelude: this should just be an implicit import of a library, not anything else. It should only introduce the package name of the library into the unqualified names.
  • Pre-declared identifiers: Other unqualified names predeclared into the unqualified namespace. These are expected to be aliases of normal package-qualified names from the prelude such as, purely as an example, alias String = Carbon.String.

And last but not least, to emphasize: pre-declared identifiers (and the package name of the prelude library) are available with unqualified lookup, but the same names can still be declared (shadowing), and then accessed with qualified namelookup to disambiguate:

package MyPackage

class String { ... }

// Can't use `String` but can use `MyPackage.String`:
var global_str: MyPackage.String = "Hello World!";

Whereas, whenever the name is lower_snake_case like bool or true, it is a keyword, and would need to use some kind of raw-identifier syntax to avoid collisions.

@jonmeow
Copy link
Contributor Author

jonmeow commented Jul 19, 2022

Addressed by #861

zygoloid added a commit to zygoloid/carbon-lang that referenced this issue Aug 3, 2022
.

The most significant change here is that explorer now uses the chosen spelling
rather than the old `Bool` spelling. Also update a few documentation examples
and some skeletal design docs to use the chosen spelling.
zygoloid added a commit that referenced this issue Aug 4, 2022
The most significant change here is that explorer now uses the chosen spelling
rather than the old `Bool` spelling. Also update a few documentation examples
and some skeletal design docs to use the chosen spelling.
@jonmeow jonmeow added the leads question A question for the leads team label Aug 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
leads question A question for the leads team
Projects
None yet
Development

No branches or pull requests

3 participants