human
En général, il existe deux types de syntaxe pour définir des fonctions - quelque chose comme C, C++, C# ou Java (```int functionName(char arg)```) par rapport à la tradition ML (et autres) de définir le type de retour après la fonction (et d'utiliser quelque chose comme un mot-clé ```fun``` pour définir une fonction - comme ```fun functionName(char arg): int```).
L'un des avantages (pour le parseur, du moins) d'un mot-clé ```fun``` est qu'il permet au parseur d'être sans contexte (il n'a pas à deviner si ```int``` définit une variable ou une fonction).
Lorsque C a été inventé, les ordinateurs avaient très peu de mémoire et de vitesse (tellement peu que la raison pour laquelle C exige de définir toutes les variables au début de la fonction était parce qu'il devait être un parseur en une seule passe). Pourquoi n'ont-ils pas choisi la solution simple et utilisé un mot-clé de définition de fonction
gpt
Le document de Dennis Ritchie sur le développement du langage C donne une idée de la raison derrière cela : à savoir, la règle fondamentale en C selon laquelle la syntaxe de déclaration doit correspondre à la syntaxe d'expression"

Pour chaque objet de ce type composé, il existait déjà un moyen de mentionner l'objet sous-jacent : indexer le tableau, appeler la fonction, utiliser l'opérateur d'indirection sur le pointeur. Un raisonnement analogique a conduit à une syntaxe de déclaration pour les noms qui reflète celle de la syntaxe d'expression dans laquelle les noms apparaissent généralement. Ainsi,
```int i, *pi, **ppi;
```
déclare un entier, un pointeur vers un entier, un pointeur vers un pointeur vers un entier. La syntaxe de ces déclarations reflète l'observation selon laquelle ```i```, ```*pi``` et ```**ppi``` donnent toutes un type ```int``` lorsqu'elles sont utilisées dans une expression. De même,
```int f(), *f(), (*f)();
```
déclare une fonction renvoyant un entier, une fonction renvoyant un pointeur vers un entier, un pointeur vers une fonction renvoyant un entier ;
```int *api[10], (*pai)[10];
```
déclare un tableau de pointeurs vers des entiers et un pointeur vers un tableau d'entiers. Dans tous ces cas, la déclaration d'une variable ressemble à son utilisation dans une expression dont le type est celui nommé en tête de la déclaration.


Il semble que cette règle ait primé sur les considérations du parseur. Sa conséquence immédiate est que les déclarations de fonctions ne peuvent pas utiliser de mots-clés spécifiques ou imposer un ordre différent des composants de la déclaration.
Il convient de noter que l'analyse était quelque peu différente dans les premières versions de C, puisque les déclarations de fonctions ne spécifiaient pas leurs arguments et que les définitions de fonctions séparaient la liste des arguments des déclarations d'arguments (qui n'étaient pas nécessaires pour les arguments de type ```int```):
```sum();
```
déclare une fonction ```sum```, qui serait ensuite définie comme
```sum(a, b) {
    return a + b;
}
```
(pas de types nécessaires ici, la valeur par défaut est ```int```). Ainsi, le parseur ne traitait pas les types à l'intérieur des listes d'arguments.