Every so often, someone in the C++ world talks of "programming with generics" — despite that being an ADAism, and what they really mean is programming with templates. You'll be glad to hear that the C folk have been busy on the quiet, and that the C language now, as of ISO/IEC 9899:2011, has things that are actually called generics. With them, and where necessary (fortunately not the case in the example here) the statement-expression extension that is available in the clang and GCC compilers, one can transform any function in the C language to what I hereby name Descending Pratchett Form:
#include <stdio.h> #include <stdlib.h> #define go(ld) _Generic((ld) \ int: EXIT_FAILURE, \ long double: EXIT_SUCCESS, \ long double *************: (Gold = GOld = 1, &&&&&&&&&&&&ld), \ long double ***********: (GOLd = GOld + Gold, Gold = GOld, GOld = GOLd, &&&&&&&&&&ld), \ long double *********: (GOLd = GOld + Gold, Gold = GOld, GOld = GOLd, &&&&&&&&ld), \ long double *******: (GOLd = GOld + Gold, Gold = GOld, GOld = GOLd, &&&&&&ld), \ long double *****: (GOLd = GOld + Gold, Gold = GOld, GOld = GOLd, &&&&ld), \ long double ***: (GOLd = GOld + Gold, Gold = GOld, GOld = GOLd, &&ld), \ long double ************: (printf("%d ", Gold), &&&&&&&&&&&ld), \ long double **********: (printf("%d ", Gold), &&&&&&&&&ld), \ long double ********: (printf("%d ", Gold), &&&&&&&ld), \ long double ******: (printf("%d ", Gold), &&&&&ld), \ long double ****: (printf("%d ", Gold), &&&ld), \ long double **: (printf("%d ", Gold), &ld), \ long double *: (puts(""), ld), \ ) int main () { long double ld; int Gold, GOld, GOLd, GOLD; go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld)))))))))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld))))))))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld)))))))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld))))))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld)))))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld))))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld)))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld, go(ld))))))); go(ld, go(ld, go(ld, go(ld, go(ld, go(ld)))))); go(ld, go(ld, go(ld, go(ld, go(ld))))); go(ld, go(ld, go(ld, go(ld)))); go(ld, go(ld, go(ld))); go(ld, go(ld)); return go(ld); }