Metaprogrammering - Metaprogramming

Metaprogrammering er en programmeringsteknik, hvor computerprogrammer har mulighed for at behandle andre programmer som deres data. Det betyder, at et program kan designes til at læse, generere, analysere eller transformere andre programmer og endda ændre sig selv, mens det kører. I nogle tilfælde giver dette programmerere mulighed for at minimere antallet af kodelinjer for at udtrykke en løsning, hvilket igen reducerer udviklingstiden. Det giver også programmer større fleksibilitet til effektivt at håndtere nye situationer uden rekompilering.

Metaprogrammering kan bruges til at flytte beregninger fra løbetid til kompileringstid , til at generere kode ved hjælp af kompileringstidsberegninger og til at aktivere selvmodificerende kode . Programmeringssprogets evne til at være sit eget metasprog kaldes refleksion . Refleksion er en værdifuld sprogfunktion for at lette metaprogrammering.

Metaprogrammering var populær i 1970'erne og 1980'erne ved hjælp af listebehandlingssprog som LISP . LISP -hardwaremaskiner var populære i 1980'erne og aktiverede applikationer, der kunne behandle kode. De blev ofte brugt til kunstig intelligens applikationer.

Tilgange

Metaprogrammering gør det muligt for udviklere at skrive programmer og udvikle kode, der falder ind under det generiske programmeringsparadigme . At have selve programmeringssproget som en førsteklasses datatype (som i Lisp , Prolog , SNOBOL eller Rebol ) er også meget nyttigt; dette er kendt som homoiconicity . Generisk programmering påberåber sig en metaprogrammeringsfacilitet inden for et sprog ved at lade en skrive kode uden bekymring for at angive datatyper, da de kan leveres som parametre, når de bruges.

Metaprogrammering fungerer normalt på en af ​​tre måder.

  1. Den første fremgangsmåde er at udsætte internerne i køre-tidsmotoren for programmeringskoden gennem applikationsprogrammeringsinterfaces (API'er) som den for .NET IL- emitteren.
  2. Den anden tilgang er dynamisk udførelse af udtryk, der indeholder programmeringskommandoer, ofte sammensat af strenge, men kan også være fra andre metoder ved hjælp af argumenter eller kontekst, som Javascript. Således kan "programmer skrive programmer." Selvom begge metoder kan bruges på samme sprog, har de fleste sprog en tendens til at læne sig mod det ene eller det andet.
  3. Den tredje tilgang er at gå helt uden for sproget. Generelle programtransformationssystemer , såsom kompilatorer, der accepterer sprogbeskrivelser og udfører vilkårlige transformationer på disse sprog, er direkte implementeringer af generel metaprogrammering. Dette gør det muligt at anvende metaprogrammering på stort set ethvert målsprog uden hensyn til, om dette målsprog har sine egne metaprogrammeringsevner. Man kan se dette i arbejdet med Scheme, og hvordan det gør det muligt at tackle nogle begrænsninger i C ved at bruge konstruktioner, der var en del af selve ordningssproget til at udvide C.

Lisp er sandsynligvis det typiske sprog med metaprogrammeringsfaciliteter, både på grund af dets historiske forrang og på grund af enkelheden og kraften i dets metaprogrammering. I Lisp -metaprogrammering introducerer operatøren uden citat (typisk et komma) kode, der evalueres på programdefinitionstidspunktet snarere end ved løbetid; se Selvvurderende formularer og citat i Lisp . Metaprogrammeringssproget er således identisk med værtsprogrammeringssproget, og eksisterende Lisp -rutiner kan genbruges direkte til metaprogrammering, hvis det ønskes. Denne tilgang er blevet implementeret på andre sprog ved at inkorporere en tolk i programmet, som arbejder direkte med programmets data. Der er implementeringer af denne art for nogle almindelige sprog på højt niveau, f.eks. RemObjects ' Pascal Script for Object Pascal .

Anvendelser

Kodegenerering

Et simpelt eksempel på et metaprogram er denne POSIX Shell script , der er et eksempel på generative programmering :

#!/bin/sh
# metaprogram
echo '#!/bin/sh' > program
for i in $(seq 992)
do
    echo "echo $i" >> program
done
chmod +x program

Dette script (eller program) genererer et nyt 993-linjers program, der udskriver tallene 1–992. Dette er kun en illustration af, hvordan man bruger kode til at skrive mere kode; det er ikke den mest effektive måde at udskrive en liste med numre på. Ikke desto mindre kan en programmør skrive og udføre dette metaprogram på mindre end et minut, og vil have genereret over 1000 linjer kode på den tid.

En quine er en særlig form for metaprogram, der producerer sin egen kildekode som output. Quines er generelt kun af rekreativ eller teoretisk interesse.

Ikke al metaprogrammering involverer generativ programmering. Hvis programmer kan ændres ved runtime, eller hvis inkrementel kompilering er tilgængelig (f.eks. I C# , Forth , Frink , Groovy , JavaScript , Lisp , Elixir , Lua , Nim , Perl , PHP , Python , REBOL , Ruby , Rust , SAS , Smalltalk , og Tcl ), så kan teknikker bruges til at udføre metaprogrammering uden egentlig at generere kildekode.

En stil med generativ tilgang er at anvende domænespecifikke sprog (DSL'er). Et ganske almindeligt eksempel på brug af DSL'er involverer generativ metaprogrammering: lex og yacc , to værktøjer, der bruges til at generere leksikale analysatorer og parsere , lad brugeren beskrive sproget ved hjælp af regulære udtryk og kontekstfrie grammatikker og integrere de komplekse algoritmer, der kræves for effektivt at analysere Sprog.

Kodeinstrumentering

En brug af metaprogrammering er at instrumentere programmer for at udføre dynamisk programanalyse .

Adfærdsændringer

Metaprogrammering kan bruges til at væve adfærdsændringer i et program, som det gøres i aspektorienteret programmering . For eksempel kan metaprogrammering bruges til at injicere funktionsflag eller til at undersøge mulige patches til at rette fejl.

Udfordringer

Nogle hævder, at der er en skarp indlæringskurve til fuldstændig brug af metaprogrammeringsfunktioner. Da metaprogrammering giver mere fleksibilitet og konfigurerbarhed ved runtime, kan misbrug eller forkert brug af metaprogrammeringen resultere i uberettigede og uventede fejl, der kan være ekstremt vanskelige at fejlsøge for en gennemsnitlig udvikler. Det kan indføre risici i systemet og gøre det mere sårbart, hvis det ikke bruges med omhu. Nogle af de almindelige problemer, der kan opstå på grund af forkert brug af metaprogrammering, er, at kompilatoren ikke kan identificere manglende konfigurationsparametre, ugyldige eller forkerte data kan resultere i ukendt undtagelse eller andre resultater. På grund af dette mener nogle, at kun højtuddannede udviklere bør arbejde på at udvikle funktioner, der udøver metaprogrammering på et sprog eller en platform, og gennemsnitlige udviklere skal lære at bruge disse funktioner som en del af konventionen.

Anvendelser i programmeringssprog

Makro systemer

Makro -samlere

Den IBM / 360 og derivater havde magtfulde makro assembler faciliteter, der ofte blev brugt til at generere komplette samling sprog programmer eller dele af programmer (for forskellige operativsystemer for eksempel). Makroer, der blev leveret med CICS- transaktionsbehandlingssystem , havde assembler-makroer, der genererede COBOL-udsagn som et forbehandlingstrin.

Andre montører, f.eks. MASM , understøtter også makroer.

Metaclasses

Metaclasses leveres af følgende programmeringssprog:

Skabelonmetaprogrammering

Iscenesat metaprogrammering

Afhængige typer

Brug af afhængige typer gør det muligt at bevise, at genereret kode aldrig er ugyldig. Imidlertid er denne tilgang blødende og findes sjældent uden for forskningsprogrammeringssprog.

Implementeringer

Listen over bemærkelsesværdige metaprogrammeringssystemer fastholdes på Liste over programtransformationssystemer .

Se også

Referencer

eksterne links