Czym dokładnie jest metaprogramowanie?

Czytałem artykuł na temat programowania ployglota na platformie Java. Niektóre komentarze w artykule odnoszą się do metaprogramowania jako możliwości generowania kodu (być może w locie).

Jest metaprogramowaniem zdolności do generowania kodu w locie lub jest to zdolność do wprowadzania metod i atrybutów do istniejących obiektów w czasie wykonywania (jak to, na co zezwalają niektóre dynamiczne języki, takie jak Python, Ruby i Groovy).

Author: nbro, 2009-02-05

7 answers

Metaprogramowanie odnosi się do różnych sposobów, w jakie program posiada wiedzę o sobie lub może manipulować sobą.

W językach takich jak C#, reflection 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).DoSomething() oddziaływałby na obiekt o nazwie x1, gdy i jest 1 i x2 kiedy mam 2 lata.

Wreszcie, inną popularną formą metaprogramowania jest sytuacja, w której program może zmienić się w nietrywialne mody. LISP jest z tego dobrze znany i jest czymś, o czym opowiedział Paul Graham około dekady temu. Muszę poszukać jego konkretnych esejów. Ale chodzi o to, że program zmieniłby inną część programu w oparciu o jego stan. Pozwala to na poziom elastyczności w podejmowaniu decyzji w czasie wykonywania, który jest bardzo trudny w większości popularnych języków dzisiaj.

Warto również zauważyć, że w dawnych dobrych czasach programowania w prostych assembly, programy, które zmieniały się w czasie wykonywania, były niezbędne i bardzo powszechne.

Z eseju Paula Grahama "co zmieniło Lisp":

Wiele języków ma coś, co nazywa się makro. Ale makra Lispu są unikalne. Oraz Wierzcie lub nie, to co robią to związane z nawiasami. Na projektanci Lispu nie umieścili tych wszystkich nawias w język po prostu być inaczej. Do programisty Blub, Kod Lispu wygląda dziwnie. Ale te nawiasy są nie bez powodu. Są zewnętrznym dowodem na podstawowa różnica między Lispem i innych języków.

Kod Lispu jest zbudowany z danych Lispu obiektów. I nie w trywialnym sensie że pliki źródłowe zawierają znaków, a łańcuchy są jednym z typy danych obsługiwane przez język. Kod Lispu, po przeczytaniu go przez parser, składa się z danych konstrukcje które możesz przemierzyć.

Jeśli rozumiesz jak działają Kompilatory, to, co się naprawdę dzieje, nie jest tak bardzo ten Lisp ma dziwną składnię jak to Lisp nie ma składni. Piszesz programy w drzewach parsowania, które są generowane w kompilatorze, gdy inne języki są przetwarzane. Ale te parse drzewa są w pełni dostępne dla programy. Można pisać programy, które manipulować nimi. W Lispie te programy nazywane są makrami. Są to programy, które piszą programy.

Programy, które piszą programy? Kiedy chciałabyś to kiedyś zrobić? Nie bardzo często, jeśli myślisz w COBOLu. Wszystkie czas, jeśli myślisz w Lispie. Informatyka byłoby tu wygodnie, gdybym mógł podaj przykład potężnego makra, i powiedz to! co ty na to? Ale jeśli Tak, to by wyglądało jak bełkot dla kogoś, kto nie wiedział Lisp; nie ma tu miejsca na wyjaśnienia wszystko, co musisz wiedzieć, aby zrozum, co to znaczy. W Ansi Często Lisp I tried to move things tak szybko, jak tylko mogłem, a nawet tak Do makr dotarłem dopiero na stronie 160.

Ale myślę, że mogę dać coś w rodzaju argument, który może być przekonujący. Na kod źródłowy edytora Viaweb był prawdopodobnie około 20-25% makr. Makra są trudniejsze do napisania niż zwykły Lisp funkcje, i jest uważany za zły styl używania ich, gdy nie są konieczne. Więc każde makro w tym kodzie jest, bo musi być. Co? oznacza to, że że co najmniej 20-25% kod w tym programie robi rzeczy, których nie da się łatwo zrobić w żadnym inny język. Jednak sceptyczny Programista Blub może być o moim roszczenia do tajemniczych mocy Lisp, to powinno go zaciekawić. Nie pisaliśmy tego kodu dla naszego własna rozrywka. Byliśmy małym startupem, programowanie tak trudne, jak to tylko możliwe w nakaz stawiania barier technicznych między nami a naszymi konkurentami.

Podejrzana osoba może zacząć wonder gdyby istniała jakaś korelacja proszę. Duża część naszego kodu była robienie rzeczy, które są bardzo trudne do zrobienia w innych językach. W wyniku oprogramowanie robiło rzeczy naszych konkurentów" oprogramowanie nie da rady. Może było jakiś związek. Zachęcam ty podążaj za tym wątkiem. Mogą be more to that old man hobbling along na kulach niż na pierwszy rzut oka.

 68
Author: DavGarcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-12 12:31:56

Cóż, metaprogramowanie to tylko programowanie, ale to w zasadzie"pisanie kodu, który pisze kod".

Zdolność, o której wspominasz, gdy program może obserwować i modyfikować swoją strukturę i zachowanie, nazywa się odbiciem i jest to rodzaj metaprogramowania.

Dynamicznie typowane języki, mają potężne funkcje odbicia runtime, możliwe dzięki interpretacji natury tych języków...

Statyczne języki typowane mają również potężne metaprogramowanie techniki, na przykład metaprogramowanie szablonu C++ ...

 24
Author: CMS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 05:33:25

Świetne pytanie. Przykro mi, że żadna z odpowiedzi aktualnie nie odpowiada poprawnie na twoje pytanie. Może mogę pomóc...

Definicja metaprogramowania jest bardzo prosta: oznacza programy, które manipulują programami.

Twoja zaakceptowana odpowiedź mówi, że programy, które manipulują sobą. Są to rzeczywiście metaprogramy, ale są one podzbiorem wszystkich metaprogramów.

Wszystkie:

  • parsery
  • języki specyficzne dla domeny (DSLs)
  • Embedded domain specific languages (EDSLs)
  • Kompilatory
  • Tłumacze
  • przepisywanie terminów
  • twierdzenie udowodnione

Są metaprogramami. Tak więc kompilator GCC jest metaprogramem, interpreter CPython jest metaprogramem, system algebry komputerowej Mathematica jest metaprogramem, twierdzenie Coq prover jest metaprogramem i tak dalej.

Inne odpowiedzi twierdziły, że metaprogramy są programy, które generują inne programy. Są to rzeczywiście metaprogramy, ale znowu są one podzbiorem wszystkich metaprogramów. Przykładem takiego metaprogramu jest biblioteka Fastest Fourier Transform in the West (FFTW). Kod źródłowy jest napisany głównie w OCaml i generuje bity kodu C (zwane kodeletami), które są łączone w celu utworzenia wysokiej wydajności szybkiej transformacji Fouriera procedur zoptymalizowanych dla konkretnych maszyn. Biblioteka ta jest faktycznie wykorzystywana do dostarczania Procedury FFT w Matlab. Ludzie pisali programy do generowania metod numerycznych od dziesięcioleci, od wczesnych dni FORTRAN {29]}.

Pierwszy język programowania, który zintegrował obsługę metaprogramowania, był językiem Lisp (LISt Processor) pod koniec lat 50. XX wieku. LISP 1.5 zawierał szereg funkcji, które ułatwiały metaprogramowanie. Po pierwsze, podstawowym typem danych Lispu są listy zagnieżdżone, tj. drzewa takie jak (a (b c) d), co oznacza, że każdy kod Lispu może być wyrażony natywnie jako dane struktura. Jest to znane jako homoikoniczność. Po drugie, kod Lispu może być łatwo konwertowany na dane za pomocą cudzysłowu. Na przykład (+ 1 2 3) dodaje 1+2+3 i (QUOTE (+ 1 2 3)) tworzy wyrażenie, które dodaje 1+2+3 po ocenie. Po trzecie, LISP dostarczył meta-circular evaluator, który pozwala na użycie interpretera hosta lub kompilatora do oceny kodu Lispa w czasie wykonywania, w tym generowanego w czasie wykonywania kodu Lispa. Potomkami Lispa są Scheme i Clojure . We wszystkich tych językach metaprogramowanie jest najczęściej spotykany w postaci programów, które same się modyfikują, zazwyczaj za pomocą makr. W 1970 roku Robin Milner opracował Metajęzyk {29]} (ML), który ewoluował w rodzinę języków programowania ML, która obejmuje Standard ML i OCaml i silnie wpłynął Haskell {29]} i F#{29]}. Języki te ułatwiają wyrażanie innych języków. W tych językach metaprogramy są najczęściej spotykane w postaci lexerów, parserów, interpreterów i kompilatorów. W 1994 roku Erwin Unruh odkrył, że system szablonów C++ jest kompletny i może być używany do wykonywania dowolnych programów w czasie kompilacji. Metaprogramowanie szablonów C++ przyniosło metaprogramowanie niemytym masom, które (ab)używały go do wielu różnych rzeczy, w tym do generowania metod numerycznych w bibliotece Blitz++ {29]}.
 23
Author: Jon Harrop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-14 07:59:25

To tylko moja osobista opinia, która jest prawdopodobnie najbardziej liberalną definicją metaprogramowania.

Myślę, że zawiera:

  1. Generowanie kodu kompilacji lub generowanie kodu uruchomieniowego (lub obu)
  2. Aspect-Oriented Thinking lub Aspect Oriented Programming]}
  3. DRY Thinking

Myślę, że można się tam dostać za pomocą dowolnego z nich i w kombinacji:

  1. odbicie
  2. DSLs (Domain Specific Languages)
  3. atrybuty (. NET) lub adnotacje (Java)
  4. Generics (. NET/Java)
  5. Templates (C++)
  6. method_missing (Ruby)
  7. closures / first class functions / delegates
  8. AOP-programowanie zorientowane na aspekt
 8
Author: BuddyJoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-23 02:37:41

Metaprogramowanie to pisanie programu, który wysyła inny program. Jest to coś, w czym języki takie jak Lisp są naprawdę dobre. O wiele łatwiej jest to zrobić w języku, który obsługuje prawdziwe makra (nie makra C++, ale takie, które mogą manipulować kodem, który generują), takie jak Ruby, Lisp, Scheme, itp. niż w języku takim jak Java.

Jedną z implementacji jest stworzenie "języka specyficznego dla domeny", który jest sposobem na ulepszenie języka programowania do wykonania określonego zadania. Może być niezwykle potężny, jeśli zrobione poprawnie. Ruby on Rails jest dobrym przykładem tego typu programowania.

Jeśli jesteś zainteresowany poznaniem tej metody, zapoznaj się z strukturą i interpretacją programów komputerowych, która jest jedną z najważniejszych książek na ten temat.

 5
Author: Steve Rowe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 05:27:47
Metaprogramowanie jest zapisem programów komputerowych, które zapisują lub manipulują innymi programami (lub sobą) jako swoimi danymi, lub które wykonują część pracy w czasie wykonywania, która w przeciwnym razie byłaby wykonywana w czasie kompilacji. W wielu przypadkach pozwala to programistom zrobić więcej w tym samym czasie, w którym mogliby napisać cały kod ręcznie, lub daje programom większą elastyczność, aby efektywnie radzić sobie z nowymi sytuacjami bez rekompilacji. (Źródło .)

Zasadniczo jest to pisanie kodu, który generuje więcej kodu, który jest uruchamiany w celu osiągnięcia jakiegoś celu. Zazwyczaj odbywa się to w tym samym języku (używając javascript do utworzenia ciągu javascript, a następnie eval it) lub w innym języku (używając.NET do utworzenia pliku wsadowego systemu windows).

 4
Author: EndangeredMassa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 05:21:30

Wikipedia ma ładny artykuł na ten temat. Nie trzeba dokonywać modyfikacji runtime, aby coś zakwalifikować jako metaprogramowanie. Na przykład, wiele osób używa szablonów C++ do metaprogramowania podczas kompilacji.

 3
Author: Mr Fooz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 05:21:30