Une IA meilleure que les développeurs ?
Quand je me pose la question de la qualité intrinsèque d'un morceau de code, les sujets du couplage, de la cohésion et de tout ce qu'il peut y avoir derrière les principes SOLID me viennent à l'esprit.
Les assistant de code ne vont pourtant pas dans cette direction à moins d'y être incités.
Mais on ne peut leur en vouloir : ils sont à l'image de ce qu'ils ont appris.
Après une refactorisation "SRP", l'IA m'avait laissé ce code là :
1const processStream = async function* (stream) {
2 let buffer = "";
3 let state: "outside" | "newline" = "outside";
4 for await (const datum of stream) {
5 const newToken = datum.content;
6 for (const char of newToken) {
7 buffer += char;
8 if (char === "`" && state !== "newline") {
9 if (state === "outside") {
10 state = "newline";
11 }
12 buffer = "";
13 } else if (state === "newline") {
14 buffer = "";
15 }
16 }
17 }
18};
19
20onStream={async (stream) => {
21 return await props.onReturn(processStream(stream));
22}}
On avait franchi un bon palier pour le découplage, mais on pouvait faire mieux.
L'amélioration OCP a été aussi laborieuse que le SRP avait été immédiat. J'ai dû tenter une bonne dizaine de prompt avant d'avoir un résultat qui ne soit pas over-engineered.
Et j'ai dû utiliser un prompt bien trop spécifique.
Propose une amélioration pour l'OCP de telle sorte que le traitement des données ou le composant qui l'intègre puissent évoluer indépendamment.
Reste simple (pas de classe, pas de découpage du traitement des données)
On veut juste pouvoir configurer le onStream du composant avec un autre traitement de données.
1const defaultProcessStream = async (stream) => {
2 let buffer = "";
3 let state: "outside" | "newline" = "outside";
4 for await (const datum of stream) {
5 const newToken = datum.content;
6 for (const char of newToken) {
7 buffer += char;
8 if (char === "`" && state !== "newline") {
9 if (state === "outside") {
10 state = "newline";
11 }
12 buffer = "";
13 } else if (state === "newline") {
14 buffer = "";
15 }
16 }
17 }
18};
19
20const MyComponent = ({ onStream = defaultProcessStream, onReturn }) => (
21 <Component
22 onStream={async (stream) => {
23 const processedStream = await onStream(stream);
24 return await onReturn(processedStream);
25 }}
26 />
27);
Je ne m'attendais pas à devoir préciser que les classes étaient inutiles. Il semble, que par défaut, les assistants de code ont appris que OCP implique interface et classe, ce qui est très limitatif.
Bien sûr, le code ci-dessus ouvrira l'éternel débat du trop d'abstraction et d'indirection. C'est un débat récurrent.
Pour moi, il n'y a pas débat car il va faciliter et sécuriser les évolutions du code telles qu'on les avait initialement demandées à l'IA.
En attendant, on constate que l'IA n'est pas meilleure que les développeurs. On pourrait dire que c'est un développeur très rapide mais très moyen. Elle a besoin d'être guidée pour élever son niveau de code.