Sí, la programación funcional tiende a ser difícil de comprender para muchas personas (tiendo a decir, especialmente aquellos que ya han estado expuestos a la programación de procedimientos primero).
También diría que su ejemplo de programación funcional no es realmente un muy buen ejemplo de programación funcional. Está usando la recursión y solo componiendo 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úscula", considere esto como solo un caso especial de buscar un patrón y ejecutar algún código arbitrario cuando se encuentra
Muchos lenguajes lo admiten, pero para hacerlo requieren que especifiquemos el patrón como algo así como una expresión regular. Sin embargo, las expresiones regulares no son más o menos que un lenguaje de programación de propósito especial, y una implementación 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, usa un lenguaje especial para especificar el patrón, y un compilador especial para convertir esa cadena en algún tipo de función, y un intérprete especial para tomar esa función y ejecutarla. En un lenguaje funcional, normalmente usaría el lenguaje en sí para especificar el patrón, y usaría 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 cosas especiales de RE para hacerlo.
El resultado es que nosotros podemos generalizar el problema anterior con relativa facilidad. Sin embargo, en lugar de codificar el '_' y la "mayúscula" directamente 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 lo que especificamos el patrón como un RE, podemos especificar el patrón directamente como una función real, y aún usarlo, algo así como:
my_pattern(string) return beginning(string) == '_';
Y luego pasamos esa función al s & r. En este momento, es una función bastante trivial, y la hemos codificado completamente estáticamente. Un lenguaje funcional se vuelve en gran medida interesante cuando lo usamos como si pudiéramos REs, 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 RE especial para funcionar: es solo una función normal como cualquier otra.
map
para el paso 3 en lugar de un bucle mutante. El segundo enfoque es algo que solo consideraría si no hay una función dividida en la biblioteca estándar (en cuyo caso debe compararse con una solución imperativa que tampoco se usasplit
).x=x+1
puede hacer explotar un cerebro inesperado. La programación funcional es natural, no es más que funciones estrictamente matemáticas puras y convenientes.