¿Por qué se prefiere la programación imperativa sobre la programación funcional? [cerrado]

13

Antecedentes: soy partidario de la programación funcional que trabaja en una tienda VB.NET donde el modelo mental predominante es la programación imperativa. Siendo que la base de nuestro sistema es WinForms, puedo entender que no nos vamos a alejar por completo de la programación imperativa, pero aún así trato de usar FP (principalmente a través de Linq) siempre que sea posible porque creo en sus méritos.

Argumentos y contraargumentos contra FP

  1. Uno podría notar que Linq fluido es menos eficiente que su contraparte imperativa en que este estilo procesa una secuencia hacia otra secuencia y la repite. En general, tomará algunas pasadas más que el enfoque imperativo, que puede optimizarse mejor para evitar repeticiones en una secuencia. Por esta razón, el líder no podía entender por qué elegiría un enfoque funcional que sea claramente "menos eficiente".

    • Contraargumento : Argumenté que si bien a veces es menos eficiente en términos de ciclos de CPU, sentí que es más inteligible y fácil de seguir humanamente, ya que cada línea hace una sola cosa en su paso por la secuencia. Para mí esto se siente como tener una línea de montaje donde cada persona en su estación tiene un solo trabajo que hacer. Siento que el insignificante intercambio de eficiencia es recompensado por un código cuyas preocupaciones están claramente separadas.
  2. El siguiente argumento contra FP que escucho en mi tienda es que es más difícil de depurar, lo cual es cierto. No es fácil pasar por alto el código Linq. Y a veces tengo que desentrañar una cadena de métodos para seguir y analizar mejor los problemas que no puedo detectar de inmediato.

    • _Argumento del contador: en su mayor parte, aunque no tengo problemas con esto porque creo que el estilo funcional es más declarativo en cómo se lee y cuando se arroja un error dentro de una cadena funcional, generalmente puedo detectar el problema de inmediato.

Mi pregunta

He estado tratando de promover el estilo funcional en nuestra tienda y no siento que esté avanzando. He hecho ambos estilos de programación y solo recientemente incursioné en Haskell. A pesar de años de experiencia imperativa, ahora que estoy haciendo uso rutinario de FP en JavaScript, ha crecido en mí. Suena una nota de rectitud en mi núcleo cuando lo comparo con lo que podría haber hecho si me hubiera quedado con un estilo imperativo. He vuelto a entrenar mi cerebro hacia el pensamiento funcional, hacia la composición funcional.

Lo que no puedo entender es lo difícil que ha sido convencer a otros de los méritos de FP.

Por ejemplo, los desarrolladores en mi tienda usan Linq, pero creo que generalmente lo usan en el contexto de tratar con datos de dominio. Lo uso en un sentido más general y lo prefiero cada vez que estoy lidiando con secuencias / listas o estructuras de datos persistentes. No he podido convencer a mis compañeros de equipo para ampliar su uso de Linq.

Lo que estoy tratando de entender es lo que hace que a un desarrollador no le guste FP.

Me gustaría ver una respuesta de alguien que tenga mucha experiencia con FP pero que haya decidido a favor del estilo imperativo. ¿Qué impulsó la decisión de permanecer imperativo en lugar de usar funcional?


Aquí hay un ejemplo adicional que destaca las diferencias entre la programación imperativa y funcional.

Escribí el SelectedRowsmétodo de nuestra cuadrícula en Linq como tal:

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

Sin embargo, este estilo de código hace que algunos de nuestros desarrolladores se sientan incómodos, por lo que nuestro líder lo reescribió a los más familiares:

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
Mario T. Lanza
fuente
Me gusta la programación funcional, pero de un vistazo rápido al código preferiría el enfoque "imperativo" (lo llamo declarativo ). Es mucho más fácil para mí leer, dado que esta podría ser mi experiencia y ser un producto de mi entorno. Dicho esto, desde unos rápidos 5 segundos puedo ver los pasos de preparación y lo que se devuelve. Puedo ver que hay un bucle y sé que es muy probable que los ajustes a esos datos sucedan dentro de él. No tengo que rastrear definiciones de funciones; Está ahí, es simple. Pero FP es más limpio y una vez pasada la curva de aprendizaje, probablemente sería tan rápido de codificar.
vol7ron
El problema es la curva de aprendizaje, especialmente cuando se trabaja con personas que solo saben "lo suficiente" de muchos idiomas. Si se especializa en un idioma en particular, estoy seguro de que FP sería un mejor primer intento. Entonces, si hubiera ineficiencias (rendimiento de la prueba unitaria), uno podría ser más explícito en sus implementaciones.
vol7ron

Respuestas:

11

La programación funcional es demasiado complicada para programadores inexpertos . Una de las ilustraciones es esta , donde los estudiantes declararon que el desorden de 30 LOC era más fácil y más intuitivo de comprender en comparación con las cuatro líneas analógicas FP.

(Esta es la versión original del ejemplo de FP, ya que la respuesta en el enlace se ha editado más recientemente para que sea un poco más fácil de leer).

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)));

La programación funcional requiere una forma diferente de pensar sobre la forma en que codificamos y la forma en que se ejecuta este código. Rara vez se les dice a los estudiantes en la universidad, y una vez que se toman los malos hábitos, es difícil cambiarlos.

La programación funcional también tiene sus propias características específicas que pueden parecer riesgosas en manos de principiantes . La evaluación diferida es una de ellas, y pueden pasar meses antes de que uno empiece a comprender por qué la evaluación diferida es una característica excelente y no una molestia.

Es por eso que muchos principiantes comienzan a programar con lenguajes como PHP y no con lenguajes como Haskell.

Arseni Mourzenko
fuente
8
He tenido la experiencia opuesta en una universidad donde Scheme se usa para el curso de introducción. Cuando los estudiantes tenían que aprender Java o C #, la mayoría se quejaba de que Scheme era más legible
Daniel Gratzer, el
2
Eso prueba mi punto. Los estudiantes que aprendieron programación imperativa y OOP durante años lo encontrarían más legible. Las personas que comenzaron con FP lo encontrarán más legible en comparación con la programación imperativa. Sería interesante saber qué sucede con los estudiantes que conocen igualmente bien los paradigmas FP y no FP.
Arseni Mourzenko
1
El principal problema es que los lenguajes funcionales abstraen mucho. Cuando un Haskeller le dice que se quedó sin memoria porque acumuló thunks no evaluados, entonces definitivamente hay algo mal. Muchos algoritmos no son eficientes cuando están escritos en un estilo funcional. No puede implementar una rápida Quicksort impl. en la idiomática Haskell. Cada algoritmo en el lugar termina haciendo matrices de E / S para obtener un buen rendimiento. Los lenguajes funcionales son para los puristas del lenguaje, los lenguajes imperativos son para las personas que quieren hacer sus pensamientos a tiempo.
Kr0e
3
@ Kr0e: el argumento "abstrae demasiado" contra un lenguaje o paradigma siempre me parece extraño. Se utilizó el mismo argumento contra todos (o la mayoría) de los idiomas; Con suerte, la mayoría del software no está escrito en Assembler hoy.
Arseni Mourzenko
66
"Los lenguajes funcionales son para los puristas del lenguaje, los lenguajes imperativos son para las personas que quieren hacerse pensar a tiempo". Según mi experiencia, esto no es cierto. Puedo hacer las cosas más rápido usando lenguajes funcionales. El estilo imperativo es mucho más detallado y menos declarativo y cuando tengo que usar un lenguaje imperativo definitivamente necesito más iteraciones antes de hacer las cosas bien.
Giorgio