Anruf nach Name vs Anruf durch Makroerweiterung

8

Was sind in nicht strengen Bewertungssprachen die Unterschiede und Vor- / Nachteile der Verwendung von Aufruf nach Name vs Aufruf per Makroerweiterung ?

Können Sie ein Beispiel geben, das beide Auswertungsstrategien erläutert?

Danke!

    
Andrés Andrade 12.06.2017, 02:30
quelle

1 Antwort

2

Anruf nach Name:

"Name nach Aufruf" ist eine Auswertungsstrategie, bei der die Argumente einer Funktion nicht vor dem Aufruf der Funktion ausgewertet werden, sondern direkt in den Funktionskörper eingefügt werden (mithilfe der ersatzvermeidenden Substitution) und dann ausgewertet werden können erscheinen in der Funktion. Wenn im Funktionskörper kein Argument verwendet wird, wird das Argument niemals ausgewertet. Wenn es mehrmals verwendet wird, wird es bei jedem Auftreten neu bewertet. (Siehe Jensens Gerät.)

Die Anruf-für-Name-Auswertung ist gelegentlich einer Call-by-Value-Evaluierung vorzuziehen. Wenn das Argument einer Funktion in der Funktion nicht verwendet wird, spart das Aufrufen nach Name Zeit, da das Argument nicht ausgewertet wird, während das Aufrufen nach Wert es unabhängig bewertet. Wenn das Argument eine nicht terminierende Berechnung ist, ist der Vorteil enorm. Wenn jedoch das Funktionsargument verwendet wird, ist der Aufruf nach Name oft langsamer und erfordert einen Mechanismus wie einen Thunk.

Eine frühe Verwendung war ALGOL 60. Die heutigen .NET-Sprachen können Aufrufe nach Namen mit Delegaten oder Expression-Parametern simulieren. Letzteres führt dazu, dass der Funktion ein abstrakter Syntaxbaum zugewiesen wird. Eiffel stellt Agenten bereit, die eine Operation darstellen, die bei Bedarf ausgewertet wird. Seed7 bietet einen Aufruf nach Namen mit Funktionsparametern.

Aufruf nach Makro:

Der Aufruf per Makroexpansion ähnelt dem Aufruf nach Name, verwendet jedoch eine Textersetzung anstelle einer ersatzvermeidenden Substitution. Bei unbewusster Verwendung kann Makrosubstitution zu variabler Erfassung führen und zu unerwünschtem Verhalten führen. Hygienische Makros vermeiden dieses Problem, indem sie nach Schattenparametern suchen und diese ersetzen, die keine Parameter sind.

HINWEIS: In nicht strengen Bewertungssprachen

Beispiel Aufruf nach Makro:

  

Aufruf per Makro-Erweiterung: viele Programmiersprachen, einschließlich C, lisp   und Schema, bieten Entwicklern einen Mechanismus zum Hinzufügen neuer Syntax   die Kernsprache Grammatik namens Makros. Makros werden zu Code erweitert   durch einen Makro-Präprozessor. Diese Makros können Argumente enthalten, die   werden in den endgültigen Code kopiert, den der Präprozessor erzeugt. Als   Beispiel, das folgende C-Programm implementiert die Swap-Funktion über ein Makro:

%Vor%

Dieser Makro implementiert eine gültige Swap-Routine. Das

  

vorverarbeitetes Programm wird wie der folgende Code aussehen. Weil der Körper   des Makros wird direkt in den Text des aufrufenden Programms kopiert,   es funktioniert im Kontext dieses Programms. Mit anderen Worten, das Makro   bezieht sich direkt auf die Variablennamen, die es empfängt, und nicht auf   ihre Werte.

%Vor%
  

Die Ausdrücke, die als Parameter an das Makro übergeben werden, werden alle ausgewertet   Zeit, die sie im Körper des Makros verwendet werden. Wenn das Argument niemals ist   benutzt, dann wird es einfach nicht ausgewertet. Als ein Beispiel, das Programm   Unten wird die Variable b zweimal erhöht:

     

#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) int main() { int a = 2, b = 3; int c = MAX(a, b++); printf("a = %d, b = %d, c = %d\n", a, b, c); } Makros leiden unter einem Problem, dem Variablen-Capture. Wenn ein   Makro definiert eine Variable v, die bereits in der Umgebung definiert ist   des Aufrufers, und v wird an den Makro als ein Parameter übergeben, der Körper   des Makros wird nicht in der Lage sein, ein Vorkommen von v von zu unterscheiden   das andere. Zum Beispiel hat das Programm unten ein Makro, das a definiert   variable Temperatur Der Aufruf innerhalb von main bewirkt, dass die Variable temp definiert ist   innerhalb dieser Funktion, um von der Definition innerhalb der   Makros Körper.

%Vor%

Sobald dieses Programm um

erweitert wurde
  

Der C-Präprozessor, wir erhalten den folgenden Code. Dieses Programm schlägt fehl   Tausche die Werte der Variablen temp und a:

aus
%Vor%

Es gibt eine Reihe von faulen Bewertungsstrategien

  

, die das Problem der Variablenerfassung vermeiden. Die zwei bekanntesten Techniken   sind Call-by-Name und Call-by-Need.

Beispiel Anruf nach Name:

  

Call by Name: In dieser Auswertungsstrategie ist nur der tatsächliche Parameter enthalten   ausgewertet, wenn innerhalb der Funktion verwendet; Diese Bewertung wird jedoch verwendet   der Kontext der Aufrufroutine. Im Beispiel unten,   aus Webers Buch genommen, haben wir eine Funktion g, die die ganze Zahl zurückgibt   6. Innerhalb der Funktion f speichert die erste Zuweisung, z. B. b = 5, 5 in der Variable i. Die zweite Zuweisung, b = a, liest den Wert von i,   derzeit 5 und fügt 1 hinzu. Dieser Wert wird dann bei i gespeichert.

%Vor%      

Sehr wenige Sprachen implementieren die Anruf-nach-Name-Auswertungsstrategie. Das   Bedeutendste unter diesen Sprachen ist Algol. Simula, eine direkte   Nachkomme von Algol, implementiert auch Ruf nach Namen, wie wir in sehen können   Dieses Beispiel. Der namentliche Aufruf bewirkt immer die Auswertung des   Parameter, auch wenn dieser Parameter mehrfach verwendet wird. Dies   Verhalten kann in referentiell transparenten Sprachen verschwenderisch sein,   weil Variablen in diesen Sprachen unveränderlich sind.

    
sugansoft 10.08.2017 04:55
quelle

Tags und Links