Qual è il design corretto per un ciclo for
?
Felix attualmente usa
if len a > 0 do
for var i in 0 upto len a - 1 do
println a.[i];
done
done
che include il limite superiore. Questo è necessario per supportare l'intera gamma di valori di un tipo intero tipico. Tuttavia il ciclo for mostrato non supporta array di lunghezza zero, quindi il test speciale, né la sottrazione di 1 funziona in modo convincente se la lunghezza dell'array è uguale al numero di numeri interi. (Dico in modo convincente perché potrebbe essere che 0 - 1 = maxval: questo è vero in C per unsigned int, ma sei sicuro che sia vero per unsigned char senza riflettere attentamente sulle promozioni integrali?)
L'effettiva implementazione del ciclo for dal mio compilatore gestisce correttamente 0 ma questo richiede due test per implementare il ciclo:
continue:
if not (i <= bound) goto break
body
if i == bound goto break
++i
goto continue
break:
Getta il controllo dello zero codificato a mano nell'esempio dell'array e sono necessari tre test.
Se il ciclo fosse esclusivo, gestirà lo zero correttamente, evitando il test speciale, ma non ci sarebbe modo di esprimere il limite superiore di un array con la dimensione massima.
Nota il modo C di fare questo:
for(i=0; predicate(i); increment(i))
ha lo stesso problema. Il predicato viene testato dopo l'incremento, ma l'incremento di terminazione non è universalmente valido!
Esiste un argomento generale secondo cui un semplice ciclo esclusivo è sufficiente: promuovere l'indice su un tipo grande per impedire l'overflow e presumere che nessuno eseguirà mai il ciclo fino al valore massimo di questo tipo .. ma non ne sono del tutto convinto : se hai promosso a C's size_t e fatto il loop dal secondo valore più grande al più grande otterresti un ciclo infinito!