zucchero sintattico relativo ai parametri di funzione

4

Esistono linguaggi di programmazione moderni in cui non è necessario specificare i tipi per ciascun parametro nella definizione di una funzione?

Es:

procedure P(a, b, c, d: integer)

vs

void P(int a, int b, int c, int d)

C'è una buona ragione per cui quest'ultima forma è così popolare? Perché non più lingue ti consentono di specificare il tipo di tutti i tuoi parametri contemporaneamente, come il primo modulo?

    
posta user46943 06.02.2012 - 21:38
fonte

3 risposte

3

Spiegazione relativa allo stile

Mentre il primo modulo è più corto, probabilmente verrebbe ammortizzato dai controllori di stile. È anche più semplice¹. Ad esempio:

IEnumerable<TResult> LoadEverything<T1, TResult>(
    IEnumerable<T1> baseSet, bool includeChecked, bool useDefaults = false,
    TResult defaultValue = null)
{
}

è difficile da capire, ma è ancora più semplice di:

IEnumerable<TResult> LoadEverything<T1, TResult>(
    IEnumerable<T1> baseSet, includeChecked, useDefaults = false: bool,
    TResult defaultValue = null)
{
    // Does bool apply to includeChecked and useDefaults? Or maybe to baseSet too?...
}

Quindi guadagni qualche secondo digitando meno con il tuo approccio in casi facili, ma sei sicuro che tale zucchero sintattico costerà molto in termini di tempo speso a leggere e capire il codice quando viene abusato.

Problemi di analisi

Anche l'analisi di tale codice sorgente è più difficile.

Problemi di refactoring

Inoltre, il cambio e il refactoring del codice potrebbero essere anche difficili. Prendendo l'esempio sopra, chiediamo all'IDE di cambiare l'ordine dei parametri, ripristinando baseSet e includeChecked . Se l'IDE è abbastanza intelligente, lo farà correttamente. Se non lo è, produrrà un codice che non può essere compilato. Lo stesso errore può essere fatto se si esegue il refactoring manualmente.

IEnumerable<TResult> LoadEverything<T1, TResult>(
    includeChecked, IEnumerable<T1> baseSet, useDefaults = false: bool,
    TResult defaultValue = null)
{
    // What's wrong? Why can't this piece of code compile?
}

Caso parametri senza carattere

Infine, se la tua lingua accetta parametri senza tipo, diventa impossibile da implementare. Il codice:

array<TResult> LoadEverything<T1, TResult>(
    baseSet, bool includeChecked, bool useDefaults = false,
    TResult defaultValue = null)
{
    var set = cast(baseSet to array<T1>);
    // [...]
}

funzionerà ancora, mentre:

array<TResult> LoadEverything<T1, TResult>(
    baseSet, includeChecked, useDefaults = false: bool,
    TResult defaultValue = null)
{
    var set = cast(baseSet to array<T1>);
    // [...]
}

non ha senso: se baseSet è un valore booleano, come può essere convertito in un array?

¹ A proposito, hai un caso simile quando dichiari variabili dello stesso tipo. Una forma più breve è: int a = 3, b = 5, c = 1; , ma nella maggior parte dei casi, vedresti tre righe, una dichiarazione per riga, ogni dichiarazione ha il suo tipo.

    
risposta data 06.02.2012 - 22:02
fonte
3

Il tuo primo esempio è il codice Pascal, quindi a meno che tu non consideri Delphi un linguaggio di programmazione moderno, dovrebbe rispondere alla prima parte della tua domanda.

Per quanto riguarda la seconda parte, penso che la seconda forma sia preferibile, perché

  1. viene immediatamente visualizzato il tipo di parametro proprio accanto ad esso, invece di dover eseguire la scansione dell'elenco dei parametri per la successiva occorrenza di un tipo,
  2. cambiare il tipo di parametro b nel secondo modulo significa sostituire una parola, mentre nel primo devi riscrivere la definizione aggiungendo i tipi sia per a che b .

Ricorda che mentre scrivi il codice una volta, viene letto e modificato molto più spesso. È quindi più importante che il codice sia facile da leggere e gestire piuttosto che scrivere.

    
risposta data 06.02.2012 - 22:01
fonte
2

Per rispondere alla tua domanda, sì, ci sono. Un esempio di un linguaggio relativamente moderno che utilizza una sintassi simile è Ada:

procedure A_Test (A, B: in Integer; C: out Integer) is
begin
    C := A + B;
end A_Test;

(questo esempio è tratto da qui ).

Questo stile è stato permesso in Algol, così molte lingue influenzate da Algol hanno raccolto questa sintassi:

proc max = (int i, k)int:
begin
    ....
end

Anche la prima versione di C ti permette di scrivere qualcosa del tipo:

int max(a, b)
int a, b
{
    return a>b ? a : b;
}

Penso che questa sintassi si sia gradualmente attenuata, perché la pratica di dichiarare più parametri o locals su una singola riga è stata disapprovata. Alla fine, anche i linguaggi che l'hanno consentito in passato (come C) hanno smesso di consentire questa sintassi nelle loro versioni meno arcaiche.

    
risposta data 06.02.2012 - 22:55
fonte

Leggi altre domande sui tag