Un linguaggio basato sul numero limitato di argomenti passati alle funzioni

16

L'idea è ispirata dal fatto che operatori come +, -,%, ecc. possono essere visti come funzioni con uno o due argomenti passati e senza effetti collaterali. Supponendo che io, o qualcun altro, scrivo una lingua che interrompe il superamento di più di due argomenti, e funziona anche solo tramite il valore di ritorno:

a) tale linguaggio potrebbe portare a una comprensione più semplice del codice?

b) il flusso del codice sarebbe più chiaro? (forzato in più passaggi, con potenzialmente meno interazioni "nascoste"

c) le restrizioni renderebbero il linguaggio eccessivamente ingombrante per programmi più complessi.

d) (bonus) qualsiasi altro commento su pro / contro

Nota:

Dovrebbero ancora essere prese due decisioni - la prima è se consentire l'input dell'utente al di fuori di main () o il suo equivalente, e anche quale sarà la regola riguardo a cosa succede quando si passano array / strutture. Ad esempio, se qualcuno desidera che una singola funzione aggiunga più valori, potrebbe aggirare la limitazione raggruppandola in una matrice. Questo potrebbe essere fermato non permettendo ad un array o struct di interagire con se stesso, il che permetterebbe comunque, ad esempio, di dividere ogni numero di una quantità diversa, a seconda della sua posizione.

    
posta Orangesandlemons 22.06.2016 - 10:59
fonte

6 risposte

40

Robert C. Martin nel suo libro "Clean Code" raccomanda strongmente l'uso di funzioni con 0, 1 o 2 parametri al massimo, quindi almeno c'è un autore di libri esperti che pensa che il codice diventa più pulito usando questo stile (tuttavia , non è sicuramente l'autorità definitiva qui, e le sue opinioni sono discutibili).

Dove Bob Martin è IMHO corretto è: le funzioni con 3 o più parametri sono spesso indicatori di un odore di codice. In molti casi, i parametri possono essere raggruppati per formare un tipo di dati combinato, in altri casi può essere un indicatore per la funzione che sta facendo semplicemente troppo.

Tuttavia, non penso che sarebbe una buona idea inventare una nuova lingua per questo:

  • se vuoi davvero applicare una regola del genere in tutto il tuo codice, hai solo bisogno di uno strumento di analisi del codice per una lingua esistente, non c'è bisogno di inventare una lingua completamente nuova per questo (ad esempio, per C # qualcosa del tipo ' fxcop 'potrebbe probabilmente essere utilizzato).

  • a volte, la combinazione di parametri con un nuovo tipo non sembra valsa la pena, o sarebbe una pura combinazione artificiale. Vedi, ad esempio, questo metodo File.Open dal framework .Net. Ci vogliono quattro parametri, e sono abbastanza sicuro che i progettisti di questa API l'abbiano fatto intenzionalmente, perché hanno pensato che sarebbe stato il modo più pratico per fornire i diversi parametri alla funzione.

  • a volte ci sono scenari del mondo reale in cui più di 2 parametri rendono le cose più semplici per motivi tecnici (ad esempio, quando hai bisogno di un mapping 1: 1 su un'API esistente in cui sei legato all'uso di semplici tipi di dati, e non può combinare parametri diversi in un oggetto personalizzato)

risposta data 22.06.2016 - 12:05
fonte
47

Esistono molte lingue che funzionano già in questo modo, ad es. Haskell. In Haskell, ogni funzione richiede esattamente un argomento e restituisce esattamente un valore.

È sempre possibile sostituire una funzione che accetta n argomenti con una funzione che accetta argomenti n-1 e restituisce una funzione che assume l'argomento finale. Applicando questo ricorsivamente, è sempre possibile sostituire una funzione che accetta un numero arbitrario di argomenti con una funzione che richiede esattamente un argomento. E questa trasformazione può essere eseguita meccanicamente, mediante un algoritmo.

Questo è chiamato Frege-Schönfinkeling, Schönfinkeling, Schönfinkel-Currying, o Currying, dopo Haskell Curry che lo ha studiato ampiamente negli anni '50, Moses Schönfinkel, che lo descrisse nel 1924, e Gottlob Frege, che lo prefigurò nel 1893.

In altre parole, limitare il numero di argomenti ha esattamente un impatto zero.

    
risposta data 22.06.2016 - 12:48
fonte
8

Ho passato un po 'di tempo in queste ultime settimane a cercare di imparare il linguaggio del computer J. In J, praticamente tutto è un operatore, quindi ottieni solo "monade" (funzioni che hanno solo un argomento) e "diadi" (funziona esattamente con due argomenti). Se hai bisogno di più argomenti, devi fornirli in un array o fornirli in "scatole".

J può essere molto conciso, ma come il suo predecessore APL, può anche essere molto criptico - ma questo è principalmente il risultato dell'obiettivo del creatore di emulare il succinto matematico. È possibile rendere più leggibile un programma J utilizzando i nomi anziché i caratteri per creare operatori.

    
risposta data 22.06.2016 - 17:14
fonte
5

Un linguaggio basato sul modo in cui limita lo sviluppatore dipende dal presupposto che lo sviluppatore della lingua capisca meglio le esigenze di ogni programmatore di quanto il programmatore comprenda tali esigenze. Ci sono casi in cui questo è effettivamente valido. Ad esempio, i vincoli sulla programmazione multithreaded che richiedono la sincronizzazione utilizzando mutex e semafori sono considerati da molti come "buoni" perché la maggior parte dei programmatori è completamente inconsapevole delle complessità specifiche della macchina sottostanti che tali vincoli nascondono da esse. Allo stesso modo, pochi desiderano cogliere appieno le sfumature degli algoritmi di garbage collection multithreaded; un linguaggio che semplicemente non ti permette di rompere l'algoritmo GC è preferito rispetto a uno che costringe un programmatore a essere consapevole di troppe sfumature.

Dovresti formulare un argomento valido per spiegare perché, in quanto sviluppatore di una lingua, capisci che l'argomento passa molto meglio dei programmatori che usano la tua lingua e che è importante impedire loro di fare cose che consideri dannose. Penso che sarebbe un argomento difficile da fare.

Devi anche sapere che i programmatori faranno intorno ai tuoi vincoli. Se hanno bisogno di 3 o più argomenti, useranno tecniche come il curry per trasformarle in chiamate con pochi argomenti. Tuttavia, spesso questo è al costo di leggibilità, piuttosto che a migliorarlo.

La maggior parte delle lingue che conosco con questo tipo di regole sono esolang, linguaggi progettati per dimostrare che si può effettivamente operare con un insieme limitato di funzionalità. In particolare, gli esolang in cui ogni carattere è un opcode hanno la tendenza a limitare il numero di argomenti, semplicemente perché hanno bisogno di mantenere l'elenco degli opcode brevi.

    
risposta data 23.06.2016 - 02:29
fonte
1

Avrai bisogno di due cose:

  • Chiusura
  • Tipo di dati compositi

Aggiungerò un esempio matematico per spiegare la risposta scritta da Jörg W Mittag .

Considera la funzione gaussiana .

Una funzione gaussiana ha due parametri per la sua forma, vale a dire la media (posizione centrale della curva) e la varianza (correlata alla larghezza dell'impulso della curva). Oltre ai due parametri, è necessario fornire anche il valore della variabile libera x per valutarlo.

Nel primo passaggio, progetteremo una funzione gaussiana che prende tutti e tre i parametri, vale a dire la media, la varianza e la variabile libera.

Nel secondo passaggio, creiamo un tipo di dati composito che combina media e varianza in un'unica cosa.

Nel terzo passaggio, creiamo una parametrizzazione della funzione gaussiana creando una chiusura della funzione gaussiana legata al tipo di dati compositi che abbiamo creato nel secondo passaggio.

Infine, valutiamo la chiusura creata nel terzo passaggio passando il valore della variabile libera x ad esso.

La struttura è quindi:

  • Valuta (calcolo)
    • ParameterizedGaussian (closure: la formula, più alcune variabili vincolate)
      • GaussianParameters (tipo di dati compositi)
        • Media (valore)
        • Varianza (valore)
    • X (il valore della variabile gratuita)
risposta data 22.06.2016 - 15:38
fonte
1
  1. In quasi tutti i linguaggi di programmazione, puoi passare un qualche tipo di elenco, array, tupla, record o oggetto come unico argomento. Il suo unico scopo è quello di contenere altri oggetti invece di passarli a una funzione individualmente. Alcuni IDE Java hanno anche una funzione " Estrai oggetto parametro " per fare proprio questo . Internamente, Java implementa un numero variabile di argomenti creando e passando una matrice.

  2. Se vuoi davvero fare ciò di cui stai parlando nella forma più pura, devi guardare il calcolo lambda. È esattamente quello che descrivi. Puoi effettuare ricerche sul Web, ma la descrizione che avevo senso per me era in Tipi e linguaggi di programmazione .

  3. Guarda Haskell e ML linguaggi di programmazione (ML è più semplice). Sono entrambi basati sul calcolo lambda e concettualmente hanno un solo parametro per funzione (se si strizza un po ').

  4. L'elemento 2 di Josh Bloch è: "Considera un costruttore in presenza di molti parametri del costruttore." Puoi vedere come verbose diventa , ma è un piacere lavorare con un'API scritta in questo modo.

  5. Alcune lingue hanno chiamato parametri che sono un altro approccio per rendere le firme dei metodi enormi molto più facili da navigare. Kotlin ha nominato argomenti per esempio.

risposta data 27.06.2016 - 23:32
fonte