Naming Conventions
Convenções de naming cross-linguagem da Koder Stack: variables/funcs per idiom da linguagem, classes/types sempre PascalCase, constantes SCREAMING_SNAKE_CASE, files snake_case (códigos) ou kebab-case (.kmd), acronyms tratados como palavra (HttpClient não HTTPClient), booleans com prefixo is_/has_/can_/should_. Cross-language exceptions documentadas.
Quando esta spec se aplica
Triggers primários
- Criar/renomear identificador em código Koder
Todos os triggers
- Nomear nova variável, função, classe, tipo, constante, arquivo, módulo, package
- Decidir entre snake_case/camelCase/PascalCase em código novo
- Refatorar nome inconsistente
Corpo da especificação
Spec — Naming Conventions
Facet Code do Koder Design.
Pra naming de binários/CLI ver
binaries-and-cli/naming.kmd(k<slug>em CLI, paths/opt/koder/<slug>/, etc.).Pra naming de produtos/marcas ver
naming/brand-score.kmd.
Princípio cross-cutting
Cada linguagem tem o seu idiom nativo que a comunidade respeita — forçar uniformidade total atrapalha quem lê. A Koder respeita o idiom da linguagem para identificadores in-source, MAS uniformiza:
- Classes/Types: sempre PascalCase
- Constants: sempre SCREAMING_SNAKE_CASE
- Files: snake_case pra código, kebab-case pra docs
- Acronyms: tratados como palavra (
HttpClientnãoHTTPClient) - Booleans: prefixo semântico
Tabela cross-linguagem
| Categoria | Koda | Go | Dart | Python | Rust | JS/TS | SQL | Shell |
|---|---|---|---|---|---|---|---|---|
| Variável local | snake_case |
camelCase |
camelCase |
snake_case |
snake_case |
camelCase |
snake_case |
snake_case |
| Variável global/module | snake_case |
PascalCase (export) / camelCase (priv) |
camelCase |
snake_case |
snake_case |
camelCase |
snake_case |
snake_case |
| Function | snake_case |
PascalCase (export) / camelCase (priv) |
camelCase |
snake_case |
snake_case |
camelCase |
n/a | snake_case |
| Class/Type/Struct | PascalCase |
PascalCase |
PascalCase |
PascalCase |
PascalCase |
PascalCase |
n/a | n/a |
| Interface/Trait/Protocol | PascalCase |
PascalCase (sufixo er opcional: Reader) |
PascalCase |
PascalCase |
PascalCase |
PascalCase |
n/a | n/a |
| Constant | SCREAMING_SNAKE_CASE |
PascalCase (Go idiom override OK) |
kCamelCase (Dart idiom) ou SCREAMING_SNAKE |
SCREAMING_SNAKE_CASE |
SCREAMING_SNAKE_CASE |
SCREAMING_SNAKE_CASE |
UPPERCASE |
SCREAMING_SNAKE_CASE |
| Enum value | PascalCase |
PascalCase |
camelCase (Dart idiom) |
SCREAMING_SNAKE_CASE |
PascalCase |
PascalCase |
n/a | n/a |
| Module/Package | snake_case |
lowercase (sem _) |
snake_case |
snake_case |
snake_case |
kebab-case (npm) ou camelCase |
n/a | snake_case |
| File de código | snake_case.<ext> |
snake_case.go |
snake_case.dart |
snake_case.py |
snake_case.rs |
snake_case.ts ou kebab-case.ts |
snake_case.sql |
snake_case.sh |
| Test file | <name>_test.<ext> ou test_<name>.py (idiom da linguagem) |
|||||||
| Doc file | kebab-case.kmd ou kebab-case.md |
Override Go: Go usa case pra controle de visibilidade (
PascalCase= exported,camelCase= unexported). A Koder respeita isso — não tenta forçar snake_case que quebraria compilação.
R1 — Acronyms tratados como palavra
| ❌ Errado | ✅ Certo |
|---|---|
HTTPClient |
HttpClient |
URLParser |
UrlParser |
IDToken |
IdToken |
XMLDocument |
XmlDocument |
parseJSON |
parseJson |
userID |
userId |
koderID |
koderId |
Vale pra todas as linguagens. Acronym de 2 letras também
(Id, não ID).
Exceção rara: nomes oficiais de arquivos/protocolos onde "URL"
aparece em string literal ("URL" em config) — a string fica como
está; só o identificador segue R1.
R2 — Boolean naming
Booleans (variáveis, retornos, flags) devem ter prefixo semântico:
| Prefixo | Significado |
|---|---|
is_ |
Estado atual: is_active, is_dirty, is_authenticated |
has_ |
Posse/inclusão: has_children, has_permission |
can_ |
Capacidade: can_edit, can_delete |
should_ |
Decisão/política: should_retry, should_redirect |
was_ |
Estado passado: was_modified, was_seen |
will_ |
Futuro próximo: will_expire, will_redirect |
Negação não usa not_ ou no_ — usar a forma positiva e negar
no uso: is_active = false em vez de is_inactive = true.
R3 — Naming verbs vs nouns
| Tipo | Convenção |
|---|---|
| Function | Verb phrase: get_user, compute_total, send_email |
| Boolean function | is_*/has_*/can_*/should_* (mesmo critério de var) |
| Class/Type | Noun: User, OrderSummary, EmailValidator |
| Interface/Trait | Adjective ou -er: Comparable, Reader, Serializable |
| Constant | Noun: MAX_RETRIES, DEFAULT_TIMEOUT_SECONDS |
| Enum | Singular noun: Status (não Statuses); values são noun: Active, Pending |
R4 — Tamanho
- Local var em escopo curto (≤10 linhas): pode ser curto (
i,n,err) - Local var em escopo longo: nome completo (
item_count) - Module/global: sempre nome completo
- Function arg: nome completo, exceto receivers Go (
r *Repo), iteradores funcionais (x), ou matemática (a,b) - Não abreviar arbitrariamente:
usr❌,user✅;cfg❌,config✅ - Abreviações canônicas aceitas (lista fechada):
id,ip,url,db,api,cli,tui,ui,ux,ai,ml,os,vm,kv,js,ts,http,ssh,tls,dns,oidc,pat,sdk,lhs/rhs
R5 — Plurais
Coleções no plural; itens no singular:
users = [] # lista
for user in users # item
Mapas: users_by_id, count_by_status, etc. (sufixo _by_<key>).
R6 — Negação dupla proibida
not_disabled = true # ❌
enabled = true # ✅
R7 — Filenames
- Código:
snake_case.<ext>em todas as linguagens, exceto onde o ecosistema impõe outra convenção (npmkebab-caseaceito; Dart exige snake_case por package convention) - Docs (
.kmd/.md):kebab-case.kmd - Config (
.toml/.yaml):snake_caseoukebab-case(consistência por projeto)
R8 — Reserved prefixes/sufixes Koder
Identificadores começando com koder_*, kode_*, k_*, _rt_*
(runtime), ou terminados em _kmd são reservados a infra Koder.
Não usar pra user code dentro de produtos.
Audit (deterministic)
naming-audit.sh (a criar em ticket follow-up) verifica via tree-sitter:
- Class/Type/Struct → PascalCase
- Constants → SCREAMING_SNAKE_CASE
- Acronyms → tratados como palavra (regex)
- Booleans → prefixo semântico
- Filenames → snake_case ou kebab-case (per-tipo)
- No reserved prefix conflict
Severidade medium: warning não-bloqueante por enquanto (linguagem
em si pode forçar idiom). Migrar pra hard quando coverage estiver
alta o suficiente.
Cross-link
code/indentation.kmd— formatação irmãcode/languages/<lang>-style.kmd— overrides per-linguagembinaries-and-cli/naming.kmd— naming de surfaces externasnaming/brand-score.kmd— naming de produtos/marcaspolicies/design-governance.kmd
Referências
rfcs/design-RFC-001-koder-design-system.kmdspecs/code/indentation.kmdspecs/binaries-and-cli/naming.kmdspecs/naming/brand-score.kmdpolicies/design-governance.kmd