Guardia (informatica) - Guard (computer science)

Nella programmazione di computer, una guardia è un'espressione booleana che deve restituire true se l'esecuzione del programma deve continuare nel ramo in questione.

Indipendentemente dal linguaggio di programmazione utilizzato, una clausola guard , un codice guard o un'istruzione guard è un controllo delle precondizioni di integrità utilizzato per evitare errori durante l'esecuzione. Un tipico esempio è verificare che un riferimento che sta per essere elaborato non sia null, il che evita errori del puntatore null. Altri usi includono l'uso di un campo booleano per l' idempotenza (quindi le chiamate successive sono nops), come nel modello Dispose . La guardia fornisce un'uscita anticipata da una subroutine ed è una deviazione comunemente usata dalla programmazione strutturata , rimuovendo un livello di annidamento e risultando in un codice più piatto: sostituzione if guard { ... }con if not guard: return; ....

Il termine è usato con un significato specifico in APL , Haskell , Clean , Erlang , occam , Promela , OCaml , Swift , Python dalla versione 3.10 e nei linguaggi di programmazione Scala . In Mathematica , le guardie sono chiamate vincoli . Le guardie sono il concetto fondamentale in Guarded Command Language , un linguaggio nei metodi formali . Le protezioni possono essere utilizzate per aumentare il pattern matching con la possibilità di saltare un pattern anche se la struttura corrisponde. Le espressioni booleane nelle istruzioni condizionali di solito si adattano anche a questa definizione di guardia sebbene siano chiamate condizioni .

Nel seguente esempio Haskell, le guardie si verificano tra ogni coppia di "|" e "=":

f x
 | x > 0 = 1
 | otherwise = 0

Questo è simile alla rispettiva notazione matematica:

In questo caso le guardie sono nelle clausole "se" e "altrimenti".

Se ci sono più guardie parallele, come nell'esempio sopra, normalmente vengono provate in ordine dall'alto verso il basso e viene scelto il ramo del primo a passare. Le guardie in un elenco di casi sono in genere parallele.

Tuttavia, nelle comprensioni di lista di Haskell le guardie sono in serie, e se una di esse fallisce, l'elemento della lista non viene prodotto. Sarebbe come combinare le guardie separate con AND logico , tranne per il fatto che possono esserci altre clausole di comprensione delle liste tra le guardie.

Evoluzione

Una semplice espressione condizionale, già presente in CPL nel 1963, ha una guardia sulla prima sottoespressione, e un'altra sottoespressione da utilizzare nel caso in cui la prima non possa essere utilizzata. Alcuni modi comuni per scrivere questo:

(x>0) -> 1/x; 0
x>0 ? 1/x : 0

Se la seconda sottoespressione può essere un'ulteriore semplice espressione condizionale, possiamo fornire più alternative da provare prima dell'ultimo fall-through :

(x>0) -> 1/x; (x<0) -> -1/x; 0

Nel 1966 ISWIM aveva una forma di espressione condizionale senza un caso di fall-through obbligatorio, separando così la guardia dal concetto di scelta dell'uno o dell'altro . Nel caso di ISWIM, se nessuna delle alternative poteva essere utilizzata, il valore doveva essere undefined , che è stato definito per non essere mai calcolato in un valore.

KRC , una "versione miniaturizzata" di SASL (1976), è stato uno dei primi linguaggi di programmazione ad utilizzare il termine "guardia". Le sue definizioni di funzione potevano avere diverse clausole e quella da applicare veniva scelta in base alle guardie che seguivano ciascuna clausola:

 fac n = 1,               n = 0
       = n * fac (n-1),   n > 0

L'uso delle clausole di protezione, e il termine "clausola di protezione", risale almeno alla pratica Smalltalk negli anni '90, come codificato da Kent Beck .

Nel 1996, Dyalog APL ha adottato uno stile puramente funzionale alternativo in cui la protezione è l'unica struttura di controllo. Questo esempio, in APL, calcola la parità del numero di input:

parity{
        2 : 'odd'
              'even'
        }

Protezione del modello

Oltre a una guardia attaccata a un pattern, pattern guard può riferirsi all'uso del pattern matching nel contesto di una guardia. In effetti, una corrispondenza del modello viene considerata come superata. Questo significato è stato introdotto in una proposta per Haskell di Simon Peyton Jones intitolata Una nuova visione delle guardie nell'aprile 1997 ed è stato utilizzato nell'attuazione della proposta. La funzione fornisce la possibilità di utilizzare i modelli nelle guardie di un modello.

Un esempio in Haskell esteso:

 clunky env var1 var2
 | Just val1 <- lookup env var1
 , Just val2 <- lookup env var2
 = val1 + val2
 -- ...other equations for clunky...

Questo dovrebbe leggere: "Goffo per un ambiente e due variabili, nel caso in cui le ricerche delle variabili dall'ambiente producano valori , è la somma dei valori. ..." Come nelle comprensioni di elenco , le guardie sono in serie e se nessuno di loro fallisce il ramo non viene preso.

Esempio

public string Foo(string username) {
    if (username == null) {
        throw new ArgumentNullException(nameof(username));
    }
    // Rest of the method code follows here...
}

Guarda anche

Riferimenti

link esterno