A necessidade de comentários é inversamente proporcional ao nível de abstração do código.
Por exemplo, a linguagem Assembly é, para fins mais práticos, ininteligível sem comentários. Aqui está um trecho de um pequeno programa que calcula e imprime termos da série Fibonacci :
main:
; initializes the two numbers and the counter. Note that this assumes
; that the counter and num1 and num2 areas are contiguous!
;
mov ax,'00' ; initialize to all ASCII zeroes
mov di,counter ; including the counter
mov cx,digits+cntDigits/2 ; two bytes at a time
cld ; initialize from low to high memory
rep stosw ; write the data
inc ax ; make sure ASCII zero is in al
mov [num1 + digits - 1],al ; last digit is one
mov [num2 + digits - 1],al ;
mov [counter + cntDigits - 1],al
jmp .bottom ; done with initialization, so begin
.top
; add num1 to num2
mov di,num1+digits-1
mov si,num2+digits-1
mov cx,digits ;
call AddNumbers ; num2 += num1
mov bp,num2 ;
call PrintLine ;
dec dword [term] ; decrement loop counter
jz .done ;
; add num2 to num1
mov di,num2+digits-1
mov si,num1+digits-1
mov cx,digits ;
call AddNumbers ; num1 += num2
.bottom
mov bp,num1 ;
call PrintLine ;
dec dword [term] ; decrement loop counter
jnz .top ;
.done
call CRLF ; finish off with CRLF
mov ax,4c00h ; terminate
int 21h ;
Mesmo com comentários, pode ser bastante complicado grocá-lo.
Exemplo moderno: Regexes geralmente são construções de abstração muito baixas (letras minúsculas, número 0, 1, 2, novas linhas etc.). Eles provavelmente precisam de comentários na forma de amostras (Bob Martin, IIRC, reconhece isso). Aqui está uma regex que (eu acho) deve corresponder aos URLs HTTP (S) e FTP:
^(((ht|f)tp(s?))\://)?(www.|[a-zA-Z].)[a-zA-Z0-9\-\.]+\.(com|edu|gov|m
+il|net|org|biz|info|name|museum|us|ca|uk)(\:[0-9]+)*(/($|[a-zA-Z0-9\.
+\,\;\?\'\\\+&%\$#\=~_\-]+))*$
À medida que os idiomas avançam na hierarquia de abstração, o programador pode usar abstrações evocativas (nome da variável, nomes de funções, nomes de classes, nomes de módulos, interfaces, retornos de chamada etc.) para fornecer documentação interna. Negligenciar tirar proveito disso e usar comentários para ocultar o papel é preguiçoso, um desserviço e desrespeito ao mantenedor.
Estou pensando em receitas numéricas em C traduzido principalmente na íntegra a receitas numéricas em C ++ , que eu inferir começou como receitas numéricas (em FORTAN), com todas as variáveis a
, aa
, b
, c
, cc
, etc mantida através de cada versão. Os algoritmos podem estar corretos, mas não tiraram vantagem das abstrações fornecidas pelas linguagens. E eles me fodem. Amostra de um artigo do Dr. Dobbs - Fast Fourier Transform :
void four1(double* data, unsigned long nn)
{
unsigned long n, mmax, m, j, istep, i;
double wtemp, wr, wpr, wpi, wi, theta;
double tempr, tempi;
// reverse-binary reindexing
n = nn<<1;
j=1;
for (i=1; i<n; i+=2) {
if (j>i) {
swap(data[j-1], data[i-1]);
swap(data[j], data[i]);
}
m = nn;
while (m>=2 && j>m) {
j -= m;
m >>= 1;
}
j += m;
};
// here begins the Danielson-Lanczos section
mmax=2;
while (n>mmax) {
istep = mmax<<1;
theta = -(2*M_PI/mmax);
wtemp = sin(0.5*theta);
wpr = -2.0*wtemp*wtemp;
wpi = sin(theta);
wr = 1.0;
wi = 0.0;
for (m=1; m < mmax; m += 2) {
for (i=m; i <= n; i += istep) {
j=i+mmax;
tempr = wr*data[j-1] - wi*data[j];
tempi = wr * data[j] + wi*data[j-1];
data[j-1] = data[i-1] - tempr;
data[j] = data[i] - tempi;
data[i-1] += tempr;
data[i] += tempi;
}
wtemp=wr;
wr += wr*wpr - wi*wpi;
wi += wi*wpr + wtemp*wpi;
}
mmax=istep;
}
}
Como um caso especial de abstração, todo idioma possui idiomas / trechos de código canônico para determinadas tarefas comuns (excluindo uma lista vinculada dinâmica em C) e, independentemente de sua aparência, eles não devem ser documentados. Os programadores devem aprender esses idiomas, pois eles não fazem parte oficialmente do idioma.
Portanto, o que deve ser levado em consideração: o código não-idiomático criado a partir de blocos de baixo nível que não podem ser evitados precisa de comentários. E isso é necessário muito menos do que acontece.