Bonjour les gens,
Je vois encore passer, en 2025, du code comme ça :
def is_prime(n):
if n <= 1:
is_prime = False
else:
is_prime = True
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
is_prime = False
return is_prime
Mais POURQUOI ? (ajouter un break résoudrait un problème de perfs, mais il paraît que chez les vrais puristes du SESE, break et continue sont interdits aussi, peu m’importe ici, ce n’est pas mon sujet).
Ma question est, pourquoi ne pas l’écrire de manière lisible :
def is_prime(n):
if n == 1:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
Étant fan du early return, lire une fonction entièrement codée dans un gros if ou dans un gros else juste parce qu’on s’interdit un return ça me chagrine.
Le return alternatif de FORTRAN IV (1961)
J’ai lu quelque part que cette coutume nous viendrait des développeurs FORTRAN, qui avaient, il y a fort fort longtemps, un return alternatif, une démo s’impose :
CALL CHECK(A, B, *10, *20, C)
...
10 ...
20 ...
SUBROUTINE CHECK(X, Y, *, *, C)
...
50 IF (X) 60, 70, 80
60 RETURN
70 RETURN 1
80 RETURN 2
END
- Le premier
RETURNest unreturnnormal, donc après la fin de l’exécution de la fonctionCHECKl’exécution de la fonction qui a appeléCHECKreprend comme on a l’habitude. - Le
RETURN 1renvoie au premier return alternatif qui vaut*10: donc c’est un saut au label 10. - Le
RETURN 2saute au label20(indiquée par le*20côté appelant).
J’imagine (probablement pas assez, ne l’ayant pas vécu) l’enfer, et la règle est apparue « Alternate RETURNs should not be used. ». Le return alternatif aura vécu de 1961 (Fortran IV) à 1990 (F90), l’année de naissance de Python.
Et ça serait peut-être cette règle qui se serait transformée en « un seul return par fonction » qui pollue encore notre code de nos jours.
Clairement « plusieurs return » (différents points de sortie dans la fonction appelée) et « return altenatifs » (plusieurs points d’atterrissage dans la fonction appelante) n’ont rien à voir : on ne peut pas « sauver » la règle Single-Exit en la réécrivant « un seul return par fonction ».
L’entrée alternative de FORTRAN
Dans Single-Entry Single-Exit (SESE) on lit single-entry, tiens c’est quoi ça ?
Ça date de la même époque, en FORTRAN il existait un mot clé ENTRY permettant d’ajouter des points d’entrée alternatifs à une fonction.
Le fait que Single-Entry signifie « n’utilisez pas de points d’entrée alternatifs » me conforte dans l’idée que Single-Exit signifie « n’utilisez pas de return alternatifs ».
Le dogme
Si c’est le cas, c’est donc littéralement un dogme, j’imagine la scène :
Dis, Maître, pourquoi SonarCube dit qu’il faut pas deux return dans ma fonction ?
La sagesse des anciens dit « Single-Entry, Single-Exit ». Nous on fait du code de qualité, on respecte la sagesse des anciens, on respecte MISRA et l’IEC 61508, sécurité, maintenabilité, lisibilité ! Si t’es contre t’es un jeune qui va droit dans le mur, je te le dis moi, y’en a qu’on essayé, ils ont eu des problèmes… Si tu ne veux pas finir comme les développeurs du THERAC 25, réécrit ta fonction à la norme et pose pas de questions.
Maître, c’est quoi alors Single-Entry ?
J’sais pas, retourne bosser, respecte la norme, et pose pas d’questions.
Alors que SESE ne peut pas s’appliquer aux langages qui n’ont pas d’entrée alternatives ou de return alternatifs, la règle ne peut s’appliquer à aucun langage contemporain (même fortran depuis F90 n’a plus ni l’un, ni l’autre).
Le dogme survit
Les tenant du « un seul return » se sont convaincus, et le font vivre, avec des arguments variés :
- MISRA a dit que
- L’IEC 61508 a dit que.
- Dijkstra a dit que, rep à ça !
- Ça permet de mettre un
assertau moment dureturn. - Ça permet de mettre un
breakpointau moment dureturn. - Ça permet de libérer des ressources au moment du
return. - Le code après un
returnpourrait ne pas être exécuté. - …
Ma conclusion
Libérez-vous des dogmes des années 70 !
Rédigez le code qui est le plus lisible à vos yeux en utilisant tous les outils à votre disposition pour ça. Si ça implique parfois de n’utiliser qu’un seul return, d’accord.
Mais si ça implique de tordre le code pour arriver à un seul return, pas d’accord.