Leggibilità della programmazione funzionale [chiusa]

12

Sono curioso di questo perché ricordo che prima di imparare qualsiasi linguaggio funzionale, li pensavo tutti orribilmente, terribilmente, terribilmente illeggibili. Ora che conosco Haskell e f #, trovo che ci vuole un po 'più tempo per leggere meno codice, ma quel piccolo codice fa molto più di una quantità equivalente in un linguaggio imperativo, quindi sembra un guadagno netto e io non sono estremamente praticato in modo funzionale.

Questa è la mia domanda, continuo a dire alla gente di OOP che lo stile funzionale è terribilmente illeggibile. Sono curioso di sapere se questo è il caso e mi sto illudendo, o se hanno avuto il tempo di imparare un linguaggio funzionale, l'intero stile non sarebbe più illeggibile di OOP?

Qualcuno ha visto delle prove o ha avuto degli aneddoti in cui hanno visto questo andare in un modo o nell'altro con una frequenza sufficiente per poter dire? Se la scrittura funzionalmente è davvero di minore leggibilità, allora non voglio continuare a usarlo, ma non so davvero se sia così o no.

    
posta Jimmy Hoffa 02.09.2012 - 07:45
fonte

5 risposte

14

La leggibilità del codice è molto soggettiva . Per questo motivo, persone diverse considererebbero lo stesso codice leggibile o illeggibile.

Un compito, x = x + 1 suona strano per un matematico, perché un compito sembra fuorviante simile a un confronto.

Un modello di progettazione OOP semplice non è completamente chiaro per qualcuno che non ha familiarità con questi modelli. Considera singleton . Qualcuno potrebbe chiedere a "Perché ho bisogno di un costruttore privato? Qual è il metodo misterioso getInstance() ? Perché non creiamo una variabile globale e assegniamo un oggetto lì?"

Lo stesso vale per un codice FP. A meno che tu non conosca i schemi logici dietro le quinte, sarà molto difficile persino capire qualcosa di molto semplice, ad es. come passare una funzione come argomento ad un'altra funzione.

Detto questo, si dovrebbe capire che FP non è un proiettile d'argento. Esistono molte applicazioni in cui FP potrebbe essere difficile da applicare e pertanto porteranno a un codice più leggibile .

    
risposta data 02.09.2012 - 13:11
fonte
11

Risposta breve:

Uno degli elementi che fanno affermare che il codice di programmazione funzionale è difficile da leggere è che dà la preferenza a una sintassi più compatta.

Risposta lunga:

La stessa programmazione funzionale non può essere leggibile o illeggibile, poiché è un paradigma, non uno stile di scrittura del codice. Ad esempio, in C #, la programmazione funzionale ha il seguente aspetto:

return this.Data.Products
    .Where(c => c.IsEnabled)
    .GroupBy(c => c.Category)
    .Select(c => new PricesPerCategory(category: c.Key, minimum: c.Min(d => d.Price), maximum: c.Max(d => d.Price)));

e sarebbe considerato leggibile da qualsiasi persona con sufficiente esperienza in Java, C # o lingue simili.

La sintassi della lingua, d'altra parte, è più compatta per molti linguaggi funzionali (inclusi Haskell e F #) rispetto ai popolari linguaggi OOP, dando una preferenza ai simboli piuttosto che alla parola in inglese semplice.

Questo vale anche per le lingue esterne a FP. Se si confrontano i linguaggi OOP più diffusi con quelli meno popolari che tendono ad usare più parole inglesi, gli ultimi sarebbero più facili da capire per le persone senza esperienza di programmazione.

Confronto:

public void IsWithinRanges<T>(T number, param Range<T>[] ranges) where T : INumeric
{
    foreach (var range in ranges)
    {
        if (number >= range.Left && number <= range.Right)
        {
            return true;
        }
    }

    return false;
}

a:

public function void IsWithinRanges
    with parameters T number, param array of (Range of T) ranges
    using generic type T
    given that T implements INumeric
{
    for each (var range in ranges)
    {
        if (number is from range.Left to range.Right)
        {
            return true;
        }
    }

    return false;
}

Allo stesso modo:

var a = ((b - c) in 1..n) ? d : 0;

potrebbe essere espresso in un linguaggio immaginario come:

define variable a being equal to d if (b minus c) is between 1 and n or 0 otherwise;

Quando la sintassi più breve è migliore?

Mentre una sintassi più dettagliata è più facile da capire per un principiante, la sintassi più compatta è più semplice per gli sviluppatori esperti. Codice più corto significa meno caratteri da digitare, il che significa più produttività.

Soprattutto, non ha senso forzare una persona a digitare una parola chiave per indicare qualcosa che può essere dedotto dalla sintassi.

Esempi:

  • In PHP devi digitare function prima di ogni funzione o metodo, senza alcun motivo specifico per farlo.

  • Ada mi ha sempre inorridito per aver costretto gli sviluppatori a digitare molte parole inglesi, soprattutto perché non esiste un IDE corretto con completamento automatico. Non ho usato Ada di recente e il loro tutorial ufficiale non funziona, quindi non posso dare un esempio; se qualcuno ha un esempio, sentiti libero di modificare la mia risposta.

  • La sintassi 1..n , utilizzata in molti FP (e Matlab), potrebbe essere sostituita da between 1, n o between 1 and n o between (1, n) . La parola chiave between rende molto più facile la comprensione per le persone che non hanno familiarità con la sintassi del linguaggio, ma comunque, due punti sono molto più veloci da scrivere.

risposta data 02.09.2012 - 13:45
fonte
6

Penso che una delle ragioni sia che la programmazione funzionale tende a funzionare con concetti molto più astratti. Ciò rende il codice più breve e più leggibile per le persone che conoscono e comprendono i concetti (perché esprimono appropriatamente l'essenza del problema), ma è illeggibile per le persone che non hanno familiarità con loro.

Ad esempio, per un programmatore funzionale è naturale scrivere un codice che può fallire in punti diversi all'interno di Maybe monad o Either monad. Oppure, per scrivere un computo stateful con l'aiuto di State monad. Ma per qualcuno che non capisce il concetto di monade, tutto questo sembra una specie di stregoneria nera.

Quindi penso che sarebbe ragionevole usare bit di programmazione funzionale anche in un gruppo di persone OOP, purché si usino concetti facili da capire o da imparare, come la mappatura su una collezione con una funzione o chiusure .

(E ovviamente dipende anche dal programmatore che ha scritto un pezzo di codice. Puoi scrivere codice orribilmente illeggibile in qualsiasi lingua, così come scrivere in uno stile carino e pulito.)

    
risposta data 02.09.2012 - 09:06
fonte
2

La leggibilità non ha nulla a che fare con i paradigmi, i modelli e così via. Più codice riflette la semantica del tuo dominio problematico, più sta operando una terminologia e gli idiomi di un dominio di questo tipo, più leggibile è.

Questo è il motivo per cui il codice OOP non è affatto leggibile: non che molti problemi del mondo reale siano espressi naturalmente in termini di tassonomie gerarchiche. Oggetti che trasmettono messaggi l'uno all'altro è un concetto strano, ed è molto lontano da tutto ciò che è "reale". Sorprendentemente, ci sono molti più concetti del mondo reale che possono essere mappati naturalmente agli idiomi funzionali. I problemi tendono a essere definiti in modo dichiarativo, quindi una soluzione dichiarativa è più naturale.

Sebbene ci siano molte altre semantiche che potrebbero essere più vicine al mondo reale di un puro OOP puramente funzionale, puro flusso di dati o puro qualunque cosa sarebbe mai. E a causa di questo fatto, un approccio orientato alla risoluzione dei problemi produce il codice più leggibile, superando tutti i paradigmi "puri" esistenti. Con i linguaggi specifici del dominio, ogni problema è espresso nella sua terminologia naturale. E i linguaggi funzionali sono leggermente migliori di quelli tradizionali dell'OOP nel facilitare l'implementazione delle DSL (sebbene siano disponibili approcci molto migliori).

    
risposta data 02.09.2012 - 14:03
fonte
1

La leggibilità del codice è soggettiva. Sono sicuro che alcune persone lo criticano per mancanza di comprensione. Ci sono degli idiomi naturalmente differenti nel modo in cui sono implementati i modelli comuni. Ad esempio, lo schema Visitor non ha senso in una lingua con la corrispondenza dei modelli .

L'inferenza del tipo può essere una funzione complicata. Di solito, è un grande acceleratore di sviluppo, tuttavia a volte può essere difficile capire quali tipi sono coinvolti a causa della mancanza di contesto che porta a errori confusi. Questo non è limitato ai linguaggi di programmazione funzionale: l'ho visto anche nei modelli C ++!

Le lingue moderne tendono ad essere multi-paradigma . Questo include sia C # che F #. È possibile scrivere uno stile funzionale in C # e uno stile imperativo in F #. Le stesse persone che criticano i linguaggi funzionali probabilmente scrivono codice funzionale nel loro linguaggio orientato agli oggetti.

Lo sviluppo commerciale nei linguaggi funzionali è ancora relativamente immaturo. Ho visto un numero di errori commessi che sarebbe considerato una cattiva forma in qualsiasi lingua. Ad esempio:

  1. Modifica dello stile man mano che si impara la lingua (e non si esegue il refactoring) che porta a un'incoerenza.
  2. Troppo in un file.
  3. Troppe dichiarazioni su una riga.
risposta data 02.09.2012 - 14:00
fonte

Leggi altre domande sui tag