¿La programación funcional es diferente o es realmente más difícil?

12

¿La programación funcional es diferente o es realmente más difícil ?

Diga a alguien que nunca haya aprendido a programar en absoluto, y se le enseña programación funcional. o alguien que nunca antes ha aprendido a programar, y se le enseña programación imperativa. ¿Qué le resultará más difícil? o lo mismo?

Mi pregunta: diga que el problema ahora es hacer una entrada,

de manera que qwe_asd_zxc_rty_fgh_vbn se convierta en qweAsdZxcRtyFghVbn

La vía procesal es:

  1. dividirlo a lo largo de _
  2. recorre la matriz saltando el primer elemento
  3. para cada entrada mayúscula la primera letra
  4. unir los resultados

La forma funcional es:

  1. si no puede encontrar _ return input
  2. corte el input a lo largo del primer _ (de manera que obtengamos qwe y asd_zxc_rty_gfh_cvb )
  3. mayúscula la primera letra de head y concat que con f(tail)

Está bien si tiene un fondo funcional Y tiene una experiencia considerable en programación de procedimientos, me gustaría preguntar: ¿le llevará más tiempo descubrir la manera de proceder o le llevará más tiempo? ¿Quieres descubrir la manera funcional?

Si tiene un procesal-background pero tiene muchos años de experiencia con la programación funcional, me gustaría hacer la misma pregunta: ¿le llevará más tiempo descubrir el procedimiento o lo hará? ¿Te lleva más tiempo descubrir la forma funcional?

    
pregunta Pacerier 10.06.2011 - 06:24

5 respuestas

12

Simplemente diferente. La programación funcional está mucho más relacionada con las matemáticas, con las que la mayoría de las personas están familiarizadas. Todo el asunto de las "variables inmutables" solo sorprende a los programadores imperativos donde la mentalidad de "mutable" está profundamente arraigada.

Para los recién llegados, a menudo es bastante intuitivo que no puedes simplemente cambiar el valor de algo.

Donde estudié CS, nos enseñaron un lenguaje funcional como nuestro primer curso. Y todos los que habían aprendido C ++ o Java previamente lucharon con eso. Aquellos que eran nuevos en programación lo recogieron con bastante facilidad.

    
respondido por el jalf 10.06.2011 - 10:20
20

Es simplemente diferente

Cuando programas, esencialmente traduces la forma en que razonas en código, la distancia entre tus pensamientos y la solución final podría decirse que es la "brecha cognitiva". Cuanto más grande sea la brecha, más difícil será para ti cerrarla.

Si proviene de un entorno de procedimientos, se habrá entrenado para pensar de manera procesal, por lo que la brecha será menor para el código funcional y viceversa.

La única forma de que un paradigma de programación sea intrínsecamente más fácil que cualquier otra cosa sería si se asignara a algo que ya sabía, como el lenguaje común, para que comience con un espacio más corto.

Funcional y de procedimiento es un concepto bastante fluido de todos modos y tienden a superponerse

    
respondido por el Homde 10.06.2011 - 08:11
4

Sí, la programación funcional tiende a ser difícil de comprender para muchas personas (tiendo a decir, especialmente aquellas que ya han sido expuestas a la programación de procedimientos primero).

También diría que tu ejemplo de programación funcional no es realmente un muy buen ejemplo de programación funcional. Está utilizando la recursividad y solo componer un resultado en lugar de modificar el estado, pero no mucho más que eso.

Para obtener un mejor ejemplo de programación funcional, considere un problema más general: en lugar de "buscar un guión bajo y convertir la siguiente letra a mayúsculas", considere esto como solo un caso especial de búsqueda de un patrón y ejecución de algunos código arbitrario cuando se encuentra.

Muchos lenguajes lo admiten, pero para hacerlo requieren que especifiquemos el patrón como una expresión regular. Las expresiones regulares, sin embargo, no son más ni menos que un lenguaje de programación de propósito especial, y una implementación de RE es un compilador y / o intérprete para ese lenguaje. El resultado de compilar el RE es básicamente una función que se ejecuta (en una máquina virtual RE especial) para hacer coincidir la expresión con alguna entrada.

En algo como Perl, usas un lenguaje especial para especificar el patrón, y un compilador especial para convertir esa cadena a algún tipo de función, y un intérprete especial para tomar esa función de tipo función y ejecutarla. En un lenguaje funcional, normalmente se usa el lenguaje mismo para especificar el patrón, y se usa el compilador propio del lenguaje para producir una función real . Podemos generar esa función sobre la marcha (como si pudiéramos compilar un RE cuando queramos), pero cuando lo hacemos, el resultado puede ejecutarse como cualquier otra función en el lenguaje en lugar de necesitar material RE especial para hacerlo.

El resultado es que podemos generalizar el problema anterior con relativa facilidad. Sin embargo, en lugar de codificar directamente la '_' y la "mayúscula" en la transformación, podemos tener algo como:

s&r(pattern, transform, string) {
    if (!pattern(string))
        return string
    else
        return transform(matched part of string) + s&r(rest of string);
}

Pero, a diferencia de algo en el que especificamos el patrón como un RE, podemos especificar el patrón directamente como una función real, y seguir utilizándolo, algo como:

my_pattern(string) return beginning(string) == '_';

Y luego pasamos esa función a s & r. En este momento, es una función bastante trivial, y la hemos codificado de forma totalmente estática. Un lenguaje funcional se vuelve interesante en gran medida cuando lo usamos como si pudiéramos RE, y generamos una función completamente nueva sobre la marcha basada en algo como la entrada del usuario, pero a diferencia de un RE esa función no necesita un intérprete especial de RE para ejecutarse, es solo una función normal como cualquier otra.

    
respondido por el Jerry Coffin 10.06.2011 - 07:16
4

Aquí está el código completo en Racket :

;; camelize : string -> string
(define (camelize str)
  (let ([parts (regexp-split #rx"_" str)])
    ;; result of regexp-split is never empty
    (apply string-append
           (first parts)
           (map string-titlecase (rest parts)))))

(camelize "qwe_asd_zxc_rty_fgh_vbn")
;; => "qweAsdZxcRtyFghVbn"

Como programador funcional con experiencia en procedimientos, no creo que me lleve más tiempo "resolver" una solución procesal, pero ciertamente me llevará más tiempo escribirla.

Por cierto, el resultado esperado del ejemplo en la publicación original es incorrecto: falta una "h" cerca del final.

    
respondido por el Ryan Culpepper 10.06.2011 - 09:17
3

Mi teoría favorita es que los modelos de programación son más fáciles de entender cuanto más cerca están del funcionamiento real de las computadoras. Los punteros son difíciles de entender hasta que te das cuenta de que son esencialmente direcciones de máquinas. La recursión es difícil de entender hasta que haya recorrido conscientemente un pequeño ejemplo, haya visto los marcos de la pila y se haya dado cuenta de dónde se almacenan los diferentes valores de la misma variable. Eso no significa que la programación de ensambladores sea más fácil que la programación de alto nivel, pero ver cómo se hace hace maravillas con el modelo mental que es clave para la competencia, ya sea en la programación o en la usabilidad general.

Ahora, el modelo de procedimiento está algo más cerca de la arquitectura habitual de la máquina: las asignaciones son escrituras en memoria (o registro). Las llamadas a los procedimientos son realmente solo saltos de fantasía, un if es en realidad un salto condicional, etc. Pero en Lisp, por ejemplo, no hay un equivalente de bajo nivel simple a un enlace léxico o una expresión lambda. Comprenderlo requiere que imagines una máquina funcional abstracta y completamente separada entre el nivel de lenguaje y la máquina física, porque, al parecer, la mayoría de las personas nunca llegan tan lejos.

(Estoy estoy familiarizado con la idea de que la arquitectura de von Neumann es, en última instancia, arbitraria, y no deberíamos perjudicar la mente de los principiantes con detalles tan irrelevantes de la arquitectura de la máquina, y en su lugar, presentarlos directamente a la semántica de los lenguajes de programación. De hecho, yo mismo enseñé algunos de esos cursos. Pero cada vez más creo que este es un objetivo noble pero equivocado; la gente aprende a programar mediante la comprensión desde la base, y el camino a la programación funcional es simplemente un poco más tiempo.)

    
respondido por el Kilian Foth 10.06.2011 - 09:10

Lea otras preguntas en las etiquetas