Koda Code Style
code specs/code/languages/koda-style.kmd
Style guide específico de Koder Koda (`engines/lang/koda`): token grammar (base pra syntax highlighting), order de imports/declarações, doc comment style (#: triple-line), anti-patterns recorrentes (array aliasing writeback #750, implicit globals). Cross-link com policies da Koda (full-oop, full-self-hosted) e color-schemes (render-side dos tokens).
Quando esta spec se aplica
Triggers primários
- Editar arquivo .kd
Todos os triggers
- Escrever código Koda novo (.kd)
- Configurar syntax highlighting de Koda em editor (kterm, vscode-koder)
- Code review de PR Koda
- Resolver bug recorrente que casa com anti-pattern listado
Corpo da especificação
Spec — Koda Code Style
Facet Code do Koder Design, sub-facet Languages → Koda. Estende
code/indentation.kmdecode/naming.kmdcom regras específicas de Koda.Para policies executáveis da própria linguagem (build chain self-hosted, full-OOP semantics), ver
engines/lang/koda/policies/.
Indentação e naming
- Indentação: 2 espaços (per
code/indentation.kmdR1) - Variables/funcs:
snake_case(percode/naming.kmd) - Classes/Types:
PascalCase - Constants:
SCREAMING_SNAKE_CASE - Files:
snake_case.kd
Token grammar (base pra syntax highlighting)
Categorias de token reconhecidas pelo highlighter; cada uma mapeia
1:1 pros tokens semânticos de themes/color-schemes.kmd.
| Token Koda | Mapping em color-schemes |
|---|---|
keyword (if, else, class, def, return, while, for, do, end, module) |
syntax_keyword |
keyword_op (and, or, not, in, is) |
syntax_keyword_op |
string literal ("...", '...') |
syntax_string |
string interpolation (#{...}) |
syntax_string_special |
number (int, float, hex 0x, octal 0o, binary 0b) |
syntax_number |
boolean (true, false) |
syntax_boolean |
nil literal (nil) |
syntax_boolean |
comment line (# até EOL) |
syntax_comment |
doc comment (#: em linhas consecutivas — ver Doc style) |
syntax_doc_comment |
function definition (após def) |
syntax_function |
function call (identifier seguido de () |
syntax_function_call |
method call (após ., seguido de () |
syntax_method |
class definition (após class) |
syntax_class |
| type reference (uso de PascalCase identifier) | syntax_type |
intrinsic (self, super, yield) |
syntax_intrinsic |
| constant (SCREAMING_SNAKE_CASE identifier) | syntax_constant |
| variable (snake_case identifier) | syntax_variable |
| parameter (em def signature) | syntax_parameter |
punctuation ({}, [], (), ,, ;, :) |
syntax_punctuation |
operator (+, -, *, ==, <, >>) |
syntax_operator |
| error (lint inline marker) | syntax_error |
Os hex destes tokens vivem em
themes/color-schemes/<preset>.toml, populados porthemes/color-schemes.kmd§ Vocabulário. Highlight é coerente em UI (editor render), syntax (vscode), e terminal (kterm).
Order de declarações em arquivo
#: doc comment do módulo (opcional, no topo)
#: descreve o que o módulo faz
# 1. imports
require "lib/foo"
require "lib/bar"
# 2. constants do módulo
MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30
# 3. classes (na ordem em que se compõem; base classes primeiro)
class Base
...
end
class Derived < Base
...
end
# 4. funções top-level (auxiliares vêm depois das que as usam? não —
# declarar primeiro pra leitura linear)
def public_entry_point(args)
helper_a(args)
end
def helper_a(args)
...
end
Order dentro de uma classe
class User
# 1. constants
MAX_NAME_LENGTH = 100
# 2. construtor
def initialize(name)
@name = name
end
# 3. accessors / properties
def name
@name
end
# 4. métodos públicos (ordem lógica de fluxo)
def authenticate(password)
...
end
# 5. métodos privados (sufixo _ ou em bloco private)
private
def _hash_password(password)
...
end
end
Doc comments — #: triple-line style
Doc comments usam #: (não #) e ocupam três linhas mínimas
quando documentando função/classe/método públicos:
#: Compute the SHA-256 hash of a string.
#:
#: Returns a 64-char lowercase hex string. Raises EncodingError if
#: the input contains invalid UTF-8.
def sha256(s)
...
end
Linha 1: resumo de uma linha
Linha 2: vazia (#:)
Linha 3+: detalhes (parâmetros, retorno, raises, exemplo)
Doc comment de classe:
#: User account in the Koder identity service.
#:
#: A user belongs to exactly one tenant (workspace_id required).
#: Authentication is delegated to OIDC. See specs/identity/login-resolution.kmd.
class User
...
end
Anti-patterns recorrentes
AP1 — Array aliasing writeback (#750 family)
# ❌ ERRADO — bucket aliasa container[k]; push após cap-grow orfana o novo chunk
bucket = container[k]
bucket.push(item)
# ✅ CERTO — explicit writeback após push
bucket = container[k]
bucket.push(item)
container[k] = bucket
Ver feedback_koda_array_aliasing_writeback em memory + tickets
#755 / #757 family.
AP2 — Implicit globals
# ❌ ERRADO — variável criada sem declaração explícita pode virar global
def init
config = load_config() # local? global? Koda atualmente cria local
end
# ✅ Quando intencionalmente global, prefixar @@global ou usar módulo
def init
Config.set(load_config())
end
AP3 — String concat em loop
# ❌ Performance ruim em loop grande
result = ""
for chunk in chunks do
result = result + chunk
end
# ✅ Usar buffer/join
result = chunks.join("")
AP4 — Mutating coleção durante iteração
# ❌ Comportamento indefinido
items.each do |item|
items.delete(item) if predicate(item)
end
# ✅ Filtrar primeiro
to_delete = items.filter { |i| predicate(i) }
to_delete.each { |i| items.delete(i) }
AP5 — Editar runtime no arquivo de research
# ❌ ERRADO — edits em runtime-design-R.asm não shipam
# Ver policies/runtime-source-of-truth.kmd
# Edit canonical: engines/lang/koda/self-hosted/lib/compiler_backend.kd
# ::emit_runtime_part2
Imports/requires
- Um
requirepor linha - Agrupar por origem: stdlib primeiro, depois Koder libs, depois app local — separados por linha em branco
- Ordem alfabética dentro do grupo
require "stdlib/io"
require "stdlib/json"
require "koder/identity"
require "koder/jet"
require "./helpers"
require "./models/user"
Audit deterministico
koda-style-audit.sh (a criar em follow-up) verifica:
- Indent 2 espaços, no tabs (delegate a editorconfig-checker)
- Class/method order
- Doc comments seguem triple-line style em públicos
- AP1 detection:
bucket = X[k]; bucket.pushsemX[k] = bucket - AP3 detection:
+=string em loop body - AP4 detection:
.deletedentro de.eachblock
Cross-link
code/indentation.kmd,code/naming.kmd— base cross-languagethemes/color-schemes.kmd— render-side dos token mappingsengines/lang/koda/policies/full-oop.kmd— value type semanticsengines/lang/koda/policies/full-self-hosted.kmd— build chainpolicies/runtime-source-of-truth.kmd— onde editar runtimepolicies/regression-tests.kmd— anti-patterns viram regression tests
Referências
rfcs/design-RFC-001-koder-design-system.kmdspecs/code/indentation.kmdspecs/code/naming.kmdspecs/themes/color-schemes.kmdengines/lang/koda/policies/full-oop.kmdengines/lang/koda/policies/full-self-hosted.kmd