Dans Julia, pourquoi @printf est-il une macro plutôt qu’une fonction?

Dans Julia, la syntaxe pour imprimer une chaîne formatée est la suivante:

@printf("Hello %d\n", 5) 

Pourquoi @printf est- @printf une macro au lieu d’une fonction? Est-ce pour pouvoir accepter un nombre variable d’arguments?

Prendre un nombre variable d’arguments n’est pas un problème pour les fonctions normales de Julia [ 1 ]. @printf est une macro afin qu’elle puisse parsingr et interpréter la chaîne de format au moment de la compilation et générer un code personnalisé pour cette chaîne de format spécifique. Les gens peuvent ne pas se rendre compte que la fonction printf de C parsing et réinterprète la chaîne de format chaque fois que vous appelez printf . Le fait qu’il soit aussi rapide que cela représente un petit miracle de la programmation de pointeurs insensés. Sérieusement, il suffit de regarder l’implémentation printf de votre libc la plus proche. C’est complètement fou.

Julia utilise une approche différente: @printf est une macro qui traduit les chaînes de format en code efficace spécifique à cette spécification de format. Si vous y réfléchissez, une chaîne de format de style printf n’est en fait qu’un moyen d’exprimer une fonction qui prend un nombre et un type d’arguments fixes et les imprime d’une manière particulière. Notez que j’ai dit que la chaîne de format est une fonction, pas printf lui-même, qui est conceptuellement un générateur de fonctions, transformant les formats en formateurs. Le fait que tout cela soit inclus dans une fonction d’exécution dans C est un peu incompatible avec cela étant la seule option raisonnable dans C. En fait, à cause de cela, jusqu’à très récemment, il était assez facile de se photographier dans le pied en passant le mauvais numéro ou le type d’argument à C’s printf. Ce n’est que mieux maintenant, car les compilateurs ont été spécialement conçus pour comprendre la sémantique des formats printf.

En théorie, @printf de Julia peut être réalisé plus rapidement que C car il génère du code personnalisé, mais en pratique, j’ai eu un temps assez difficile pour faire correspondre C, sans parler de le battre. Mais je pense que cela est dû à la conception actuelle de notre système E / S et à la manière dont je l’utilise, et non à une limitation inhérente. Le matériel d’E / S doit cependant être révisé, et lorsque cela se @printf , nous pourrons peut-être battre C lors d’une impression formatée en exploitant le fait que @printf est une macro.

C’est pour la performance. La macro printf prend une chaîne de format constant (par exemple, "Hello %d\n" ) et génère du code optimisé pour cette chaîne.