Metaprogramowanie odnosi się do różnych sposobów, w jakie program posiada wiedzę o sobie lub może sobą manipulować.
W językach takich jak C # refleksja jest formą metaprogramowania, ponieważ program może badać informacje o sobie. Na przykład zwrócenie listy wszystkich właściwości obiektu.
W językach takich jak ActionScript można oceniać funkcje w czasie wykonywania, aby tworzyć nowe programy, takie jak eval („x” + i). Funkcja DoSomething () wpłynie na obiekt o nazwie x1, gdy i wynosi 1, a x2, gdy i wynosi 2.
Wreszcie inną popularną formą metaprogramowania jest to, że program może zmienić się w nietrywialne mody. LISP jest z tego dobrze znany i jest czymś, co Paul Graham bronił około dekady temu. Będę musiał przejrzeć niektóre z jego konkretnych esejów. Ale chodzi o to, że program zmieniłby inną część programu na podstawie jej stanu. Zapewnia to poziom elastyczności przy podejmowaniu decyzji w czasie wykonywania, który jest bardzo trudny w większości popularnych języków.
Warto również zauważyć, że w dawnych dobrych czasach programowania w prostym asemblerze programy, które zmieniały się w czasie wykonywania, były konieczne i bardzo powszechne.
Z eseju Paula Grahama „What Made Lisp Different” :
Wiele języków ma coś, co nazywa się makro. Ale makra Lisp są wyjątkowe. Wierz lub nie, ale to, co robią, jest związane z nawiasami. Projektanci Lispa nie umieścili tych wszystkich nawiasów w języku tylko po to, by być innym. Dla programisty Bluba kod Lispa wygląda dziwnie. Ale te nawiasy są tam z jakiegoś powodu. Są zewnętrznym dowodem fundamentalnej różnicy między Lispem a innymi językami.
Kod Lisp składa się z obiektów danych Lisp. I nie w tym trywialnym sensie, że pliki źródłowe zawierają znaki, a łańcuchy są jednym z typów danych obsługiwanych przez język. Kod Lispa, po odczytaniu przez parser, składa się ze struktur danych, przez które możesz przechodzić.
Jeśli rozumiesz, jak działają kompilatory, tak naprawdę dzieje się nie tyle, że Lisp ma dziwną składnię, ale że Lisp nie ma składni. Piszesz programy w drzewach analizy, które są generowane w kompilatorze, gdy analizowane są inne języki. Ale te drzewa parsowania są w pełni dostępne dla twoich programów. Możesz pisać programy, które nimi manipulują. W Lispie te programy nazywane są makrami. Są to programy, które piszą programy.
Programy, które piszą programy? Czy kiedykolwiek chciałbyś to zrobić? Niezbyt często, jeśli myślisz w Cobolu. Cały czas, jeśli myślisz w Lisp. Byłoby dobrze, gdybym mógł podać przykład potężnego makra i powiedzieć, że tam! co ty na to? Ale gdybym to zrobił, wyglądałoby to jak bełkot dla kogoś, kto nie znał Lispa; nie ma tu miejsca na wyjaśnienie wszystkiego, co musisz wiedzieć, aby zrozumieć, co to oznacza. W Ansi Common Lisp starałem się przesuwać rzeczy tak szybko, jak tylko mogłem, a mimo to nie dotarłem do makr do strony 160.
Myślę jednak, że mogę przedstawić argument, który może być przekonujący. Kod źródłowy edytora Viaweb zawierał prawdopodobnie około 20-25% makr. Makra są trudniejsze do napisania niż zwykłe funkcje Lispa i uważa się, że złym stylem jest używanie ich, gdy nie są potrzebne. Więc każde makro w tym kodzie istnieje, ponieważ musi być. Oznacza to, że co najmniej 20-25% kodu w tym programie robi rzeczy, których nie można łatwo zrobić w żadnym innym języku. Jakkolwiek sceptyczny programista Bluba może odnosić się do moich roszczeń co do tajemniczych mocy Lispa, to powinno go zaciekawić. Nie pisaliśmy tego kodu dla własnej rozrywki. Byliśmy małym startupem, programowaliśmy tak ciężko, jak tylko mogliśmy, aby stawiać bariery techniczne między nami a naszymi konkurentami.
Podejrzana osoba mogłaby zacząć się zastanawiać, czy jest tu jakaś korelacja. Duża część naszego kodu wykonywała rzeczy, które są bardzo trudne do wykonania w innych językach. Powstałe oprogramowanie robiło rzeczy, których nie potrafiło oprogramowanie naszych konkurentów. Może był jakiś związek. Zachęcam do śledzenia tego wątku. W tym starcu kulejącym o kulach może być coś więcej niż na pierwszy rzut oka.