Metaprogrammering verwijst naar een verscheidenheid van manieren waarop een programma kennis van zichzelf heeft of zichzelf kan manipuleren.
In talen als C# is reflectie een vorm van metaprogrammering, aangezien het programma informatie over zichzelf kan onderzoeken. Bijvoorbeeld het retourneren van een lijst met alle eigenschappen van een object.
In talen als ActionScript kun je functies tijdens runtime evalueren om nieuwe programma’s te maken, zoals eval(“x” + i). DoSomething() zou een object genaamd x1 beïnvloeden als i 1 is en x2 als i 2 is.
Ten slotte is een andere veel voorkomende vorm van metaprogrammering wanneer het programma zichzelf kan veranderen op niet-triviale manieren. LISP is hier zeer bekend om en is iets waar Paul Graham ongeveer een decennium geleden voor pleitte. Ik zal een paar van zijn specifieke essays moeten opzoeken. Maar het idee is dat het programma een ander deel van het programma zou veranderen op basis van zijn toestand. Dit geeft een niveau van flexibiliteit om beslissingen te nemen op runtime die erg moeilijk is in de meeste populaire talen vandaag de dag.
Het is ook de moeite waard om op te merken dat in de goede oude tijd van programmeren in assemblage, programma’s die zichzelf wijzigden op runtime noodzakelijk en zeer gebruikelijk waren.
Van Paul Graham’s essay “What Made Lisp Different”:
Vele talen hebben iets dat een macro heet. Maar Lisp macro’s zijn uniek. En geloof het of niet, wat ze doen is gerelateerd aan de haakjes. De ontwerpers van Lisp hebben niet al die haakjes in de taal gestopt alleen maar om anders te zijn. Voor de Blub programmeur, ziet Lisp code er vreemd uit. Maar die haakjes zijn er met een reden. Zij zijn het uiterlijke bewijs van een fundamenteel verschil tussen Lisp en andere talen.
Lisp code is gemaakt van Lisp data objecten. En niet in de triviale zin dat de bronbestanden karakters bevatten, en dat strings een van de datatypes zijn die door de taal worden ondersteund. Lisp code, nadat het gelezen is door de parser, bestaat uit datastructuren die je kunt doorkruisen.
Als je begrijpt hoe compilers werken, is wat er echt aan de hand is niet zozeer dat Lisp een vreemde syntaxis heeft, maar dat Lisp geen syntaxis heeft. Je schrijft programma’s in de parse trees die worden gegenereerd in de compiler wanneer andere talen worden geparsed. Maar deze parse trees zijn volledig toegankelijk voor uw programma’s. U kunt programma’s schrijven die ze manipuleren. In Lisp, worden deze programma’s macro’s genoemd. Het zijn programma’s die programma’s schrijven.
Programma’s die programma’s schrijven? Wanneer zou je dat ooit willen doen? Niet erg vaak, als je denkt in Cobol. De hele tijd, als je in Lisp denkt. Het zou hier handig zijn als ik een voorbeeld kon geven van een krachtige macro, en zeggen: ziezo! Hoe zit dat? Maar als ik dat zou doen, zou het gewoon wartaal lijken voor iemand die Lisp niet kent; er is hier geen ruimte om alles uit te leggen wat je zou moeten weten om te begrijpen wat het betekende. In Ansi Common Lisp heb ik geprobeerd om de dingen zo snel mogelijk te laten gaan, en zelfs dan kwam ik pas op pagina 160 aan macro’s toe.
Maar ik denk dat ik een soort argument kan geven dat overtuigend kan zijn. De broncode van de Viaweb editor bestond waarschijnlijk voor zo’n 20-25% uit macro’s. Macro’s zijn moeilijker te schrijven dan gewone Lisp functies, en het wordt als een slechte stijl beschouwd om ze te gebruiken als ze niet nodig zijn. Dus elke macro in die code is er omdat het moet. Dat betekent dat tenminste 20-25% van de code in dit programma dingen doet die je niet gemakkelijk in een andere taal kunt doen. Hoe sceptisch de Blub programmeur ook mag zijn over mijn beweringen over de mysterieuze krachten van Lisp, dit zou hem toch nieuwsgierig moeten maken. We schreven deze code niet voor ons eigen amusement. We waren een kleine startup, zo hard als we konden programmeren om technische barrières tussen ons en onze concurrenten op te werpen.
Een achterdochtig iemand zou zich kunnen afvragen of er hier een correlatie was. Een groot deel van onze code deed dingen die in andere talen heel moeilijk te doen zijn. De resulterende software deed dingen die de software van onze concurrenten niet kon doen. Misschien was er een verband. Ik moedig je aan die draad te volgen. Er zit misschien meer achter die oude man op zijn krukken dan je op het eerste gezicht zou zeggen.