Background: sono un sostenitore della programmazione funzionale che lavora in un negozio VB.NET dove il modello mentale prevalente è la programmazione imperativa. Essendo la base del nostro sistema sono WinForms, posso capire che non ci allontaneremo completamente dalla programmazione imperativa, ma cerco comunque di usare FP (principalmente via Linq) dove possibile perché credo nei suoi meriti.
Argomenti e controargomentazioni contro FP
Si potrebbe notare che Linq fluente è meno efficiente della sua controparte imperativa in quanto questo stile elabora una sequenza fino a un'altra sequenza e la ripete. In generale, richiederà alcuni passaggi in più rispetto all'approccio imperativo che può essere ottimizzato meglio per evitare passaggi ripetuti su una sequenza. Per questo motivo, il lead non riusciva a capire perché avrei scelto un approccio funzionale chiaramente "meno efficiente".
- Contro-argomento : ho sostenuto che mentre a volte è meno efficiente in termini di cicli della CPU, ho sentito che è più umanamente comprensibile e facile da seguire poiché ogni linea fa solo una cosa sul suo passaggio sulla sequenza. Per me è come avere una catena di montaggio in cui ogni persona nella sua stazione ha un solo lavoro da svolgere. Sento che il trascurabile compromesso dell'efficienza è compensato da un codice le cui preoccupazioni sono nettamente separate.
Il prossimo argomento contro FP che sento nel mio negozio è che è più difficile eseguire il debug - il che è vero. Non è facile scavalcare il codice Linq. E a volte devo svelare una catena di metodi per seguire meglio e analizzare i problemi che non riesco a individuare immediatamente.
- _Counter-argomento: per la maggior parte anche se non ho problemi con questo perché penso che lo stile funzionale sia più dichiarativo nel modo in cui legge e quando viene generato un errore all'interno di una catena funzionale, di solito posso individuare immediatamente il problema.
La mia domanda
Ho cercato di promuovere lo stile funzionale nel nostro negozio e non mi sento di fare progressi. Ho fatto entrambi gli stili di programmazione e solo recentemente mi sono dilettato in Haskell. Nonostante anni di esperienza imperativa, ora che uso abitualmente FP in JavaScript, è cresciuto su di me. Suona una nota di correttezza nel mio nucleo quando lo paragono a quello che avrei potuto fare se mi fossi bloccato in uno stile imperativo. Ho riqualificato il mio cervello verso il pensiero funzionale, verso la composizione funzionale.
Quello che non riesco a capire è quanto sia stato difficile convincere gli altri dei meriti di FP.
Ad esempio, gli sviluppatori nel mio negozio usano Linq, ma penso che generalmente lo utilizzino nel contesto della gestione dei dati di dominio. Lo uso in un senso più generale e lo preferisco ogni volta che ho a che fare con sequenze / elenchi o strutture di dati persistenti. Non sono stato in grado di convincere i miei compagni di squadra ad espandere il loro uso di Linq.
Quello che sto cercando di capire è ciò che impedisce a uno sviluppatore di non apprezzare FP.
Mi piacerebbe vedere una risposta da qualcuno che ha una buona esperienza con FP ma ha deciso a favore dello stile imperativo. Cosa ha spinto la decisione di rimanere con l'imperativo invece di usare funzionale?
Ecco un ulteriore esempio che evidenzia le differenze tra programmazione imperativa e funzionale.
Ho scritto il SelectedRows
metodo della nostra griglia in Linq come tale:
Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
Get
Return Me.ugrBase.Selected.Rows.
OfType(Of Infragistics.Win.UltraWinGrid.UltraGridRow)().
Select(Function(ugr) ugr.ListObject).
OfType(Of DataRowView)().
Select(Function(drv) drv.Row).
ToArray
End Get
Tuttavia, questo stile di codice mette a disagio alcuni dei nostri sviluppatori e quindi il nostro lead lo ha riscritto per i più familiari:
Public Property SelectedRows() As DataRow() Implements IDataSourceControl.SelectedRows
Get
Dim plstRows As New List(Of DataRow)
For Each bugrLoop As Infragistics.Win.UltraWinGrid.UltraGridRow In Me.ugrBase.Selected.Rows
If bugrLoop.ListObject IsNot Nothing Then
plstRows.Add(CType(bugrLoop.ListObject, DataRowView).Row)
End If
Next
Return plstRows.ToArray()
End Get