Sfondo: sono un sostenitore della programmazione funzionale che lavora in un negozio VB.NET in cui il modello mentale prevalente è una programmazione imperativa. Essendo il fondamento del nostro sistema WinForms, posso capire che non riusciremo ad allontanarci completamente dalla programmazione imperativa, ma comunque cerco di utilizzare FP (principalmente via Linq) laddove possibile, perché credo nei suoi meriti.
Argomenti e amp; contro-argomenti contro FP
-
Si potrebbe notare che Linq fluente è meno efficiente della sua controparte imperativa in quanto questo stile elabora una sequenza giù in un'altra sequenza e la ripete. Generalmente, ci vorranno alcuni passaggi in più rispetto all'approccio imperativo che può essere meglio ottimizzato per evitare passaggi ripetuti su una sequenza. Per questo motivo, il lead non ha capito perché sceglierei un approccio funzionale che fosse chiaramente "meno efficiente".
- Contro-argomento : ho affermato 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 una sola cosa al suo passaggio sul sequenza. Per me è come avere una catena di montaggio in cui ogni persona alla sua stazione ha un solo lavoro da svolgere. Sento che il trascurabile trade off dell'efficienza è ricompensato da un codice le cui preoccupazioni sono nettamente separate.
-
Il prossimo argomento contro FP che ho sentito nel mio negozio è che è più difficile eseguire il debug, il che è vero. Non è facile scavalcare il codice Linq. E a volte devo sbrogliare una catena di metodi per seguire e analizzare meglio i problemi che non riesco a individuare immediatamente.
- _Counter-argument: 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 riesco a individuare il problema immediatamente.
La mia domanda
Ho cercato di promuovere lo stile funzionale nel nostro negozio e non mi sento come se stessi facendo progressi. Ho fatto entrambi gli stili di programmazione e solo di recente mi sono occupato di Haskell. Nonostante anni di esperienza imperativa, ora che sto facendo un uso di routine di FP in JavaScript, è cresciuto su di me. Suona una nota di correttezza nel mio nucleo quando la paragono a quello che avrei potuto fare se mi fossi attenuta a uno stile imperativo. Ho riqualificato il mio cervello verso il pensiero funzionale, verso la composizione funzionale.
Ciò 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 dei dati di dominio. Lo uso in un senso più generale e lo preferisco ogni volta che mi occupo di 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 fa sì che uno sviluppatore non apprezzi FP.
Mi piacerebbe vedere una risposta da qualcuno che ha una buona esperienza con FP, ma ha deciso in favore dello stile imperativo. Che cosa ha spinto la decisione a rimanere con imperativo invece di usare funzionale?
Ecco un altro esempio che evidenzia le differenze tra imperativo e amp; programmazione funzionale.
Ho scritto il metodo SelectedRows
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 rende scomodi alcuni dei nostri sviluppatori e quindi il nostro ruolo lo ha riscritto a quelli 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