Quali sono alcuni buoni esempi di utilizzo pass by name? [chiuso]

7

Quando scrivo programmi che uso passare per valore o passare per riferimento sembrano sempre metodi logici. Quando ho imparato a conoscere diversi linguaggi di programmazione mi sono imbattuto per nome.

Pass by name è un metodo di passaggio dei parametri che attende di valutare il valore del parametro finché non viene utilizzato. Vedi Passa overflow dello stack per nome domanda per ulteriori informazioni sul metodo.

Quello che vorrei sapere è: quali sono alcuni buoni esempi e / o motivi per usare pass by name e dovrebbero essere reintrodotti in alcune lingue più moderne.

    
posta Paul 15.12.2010 - 08:55
fonte

4 risposte

2

Alcuni dei vantaggi sono descritti in una descrizione del passaggio per nome linkato nella risposta alla tua domanda collegata.

I vantaggi del pass-by-name sono (parafrasato dall'articolo):

  1. Ha un semplice modello semantico come sostituzione testuale.
  2. La modifica e la rivalutazione delle espressioni degli argomenti hanno applicazioni utili, come il dispositivo di Jensen. (a cura di: Descritto nella seconda sezione )
  3. Le espressioni degli argomenti non sono necessariamente valutate. Qui, y non viene valutato se x è falso:

    boolean procedure and (x, y);
      boolean x, y;
    begin
        if x then return y else return false
    end;
    

Lo userei?

Non vedo alcun motivo per, anche considerando i vantaggi proposti. I puntatori e la valutazione del cortocircuito impediscono la valutazione dell'espressione tanto quanto ne ho bisogno, e sono abbastanza soddisfatto dei modelli semantici che uso regolarmente.

    
risposta data 15.12.2010 - 10:06
fonte
5

Scala è un esempio di linguaggio moderno che supporta la valutazione call-by-name (così come call-by-value, che è l'impostazione predefinita). Come hai detto, il parametro viene valutato pigramente.

Questa funzione può essere utilizzata per creare la propria struttura di controllo. Il codice fornito da Axidos nella sua risposta è un semplice, ma un buon esempio.

Ci sono altri esempi nel libro Programmazione in Scala . Proverò a pubblicare questi esempi qui stasera.

    
risposta data 15.12.2010 - 10:47
fonte
2

Ecco quello che penso sia un esempio super semplice di passare qualcosa per nome:

// JavaScript
function apply(a, b, f) { return f(a,b); }

function add(a,b) { return a + b; }

var result = apply(2, 4, add); // result is now 6

// The same in C using function-pointers
int apply(int a, int b, int (*f)(int,int)) { return f(a,b); }

int add(int a, int b) { return a + b; }

int result = apply(2, 4, add); // result is once again 6

Notate come sto passando il nome della funzione add come parametro nella funzione apply , proprio come farei con qualsiasi altra variabile. La funzione f non viene valutata al momento della dichiarazione, semplicemente perché non può essere valutata; il suo corpo non esiste alla dichiarazione. Ma questo apre a così tante possibilità in termini di riduzione del codice di caldaia. Come dire, hai 2 funzioni / metodi che entrambi fanno esattamente la stessa cosa, a parte una sola linea molto specifica; invece di dover scrivere esattamente la stessa cosa due volte, puoi scriverlo una volta e poi passare la riga di codice che spicca, per nome.

Lascia che ti mostri un esempio più elaborato di uno dei miei progetti:

// C# snippet from a web-communication utility
private static void PostHelper(string inputUri, Action<WebClient, Uri> clientFunction) {
    var client = new WebClient();
    client.Headers[HttpRequestHeader.ContentType] = "application/json";
    var uri = new Uri(inputUri);
    clientFunction(client, uri);
}

public static void Post(string inputUri, string jsonInput) {
    PostHelper(inputUri, (client, uri) => client.UploadString(uri, "POST", jsonInput));
}

public static void PostAsync(string inputUri, string jsonInput) {
    PostHelper(inputUri, (client, uri) => client.UploadStringAsync(uri, "POST", jsonInput));
}

Se non avessi usato la capacità di C # di passare per nome, sotto forma di funzioni di ordine superiore, avrei dovuto scrivere il codice in PostHelper due volte, con la modifica minore che si dice UploadString , e l'altro dice UploadStringAsync , facendo come se l'avessi salvato codice ripetuto, e mi consente anche di espanderlo più tardi se voglio aggiungere più varianti del metodo. Poiché clientFunction è valutato pigramente, posso rendere il mio codice molto più scalabile.

    
risposta data 01.12.2013 - 21:18
fonte
-1

Il passaggio per nome ha uno scopo.

In effetti stiamo dicendo che passa per nome utilizza la sostituzione testuale o in altro modo la sostituzione delle macro.

Se utilizziamo il valore passa per valore o passiamo per riferimento stiamo semplicemente passando valori o indirizzi, ma non possiamo passare un'espressione come i*x[i]; (in passaggio per riferimento valutato in un percorso temporaneo il cui indirizzo è passato ), ma è possibile con pass by name.

Ad esempio, se vogliamo eseguire la somma dell'espressione i*x[i] dove i varia da 1 a 5 usando una funzione, possiamo scrivere una funzione che usa pass per riferimento come scritto di seguito (non importa il sintassi)

  *procedure sum (int low, int high, int i , real exp)
  { 
       begin

         real S;
         S := 0;
         for i := low step 1 until high do
           {  S := S + Exp;
             Sum := S}
       end;*
 }

quindi una chiamata come sum(1,5,i,x[i]) scoprirà la somma della serie i*x[i] , dove Exp viene letteralmente sostituita per i*x[i] .

    
risposta data 06.09.2012 - 08:55
fonte

Leggi altre domande sui tag