Потреба в коментарях обернено пропорційна рівню абстракції коду.
Наприклад, мова для складання з більшості практичних цілей не зрозуміла без коментарів. Ось уривок з невеликої програми, яка обчислює та друкує терміни серії Фібоначчі :
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 ;
Навіть з коментарями це може бути досить складно.
Сучасний приклад: регулярні вирази - це дуже низькі абстракційні конструкції (малі літери, цифри 0, 1, 2, нові рядки тощо). Вони, ймовірно, потребують коментарів у вигляді зразків (Bob Martin, IIRC, це визнає). Ось регулярний вираз, який (я думаю) повинен відповідати URL-адресам HTTP (S) та 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\.
+\,\;\?\'\\\+&%\$#\=~_\-]+))*$
У міру просування мов вдосконалення ієрархії абстракцій програміст може використовувати евокативні абстракції (назва змінної, назви функцій, назви класів, назви модулів, інтерфейси, зворотні виклики тощо) для забезпечення вбудованої документації. Нехтувати, щоб скористатися цим, і використовувати коментарі, щоб надрукувати це - ліниво, недоброзичливо і неповажно до обслуговуючого персоналу.
Я маю в виду Numerical Recipes в C переведений в основному дослівно Numerical Recipes в C ++ , який я роблю висновок почав як Numerical Recipes (в FORTAN), з усіма змінними a
, aa
, b
, c
, cc
і т.д. підтримується з допомогою кожної версії. Алгоритми, можливо, були правильними, але вони не скористалися абстракціями, які надаються мовами. І вони мене відігнали. Зразок із статті доктора Доббса - Швидке перетворення Фур'є :
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;
}
}
Як особливий випадок абстракції, кожна мова має ідіоми / канонічні фрагменти коду для певних загальних завдань (видалення динамічного пов'язаного списку в С), і незалежно від того, як вони виглядають, вони не повинні бути задокументовані. Програмісти повинні вивчити ці ідіоми, оскільки вони неофіційно є частиною мови.
Тож забирайте: недіотичний код, побудований із будівельних блоків низького рівня, яких не уникнути, потребує коментарів. І це потрібно ВАААЙ менше, ніж трапляється.