Wikipedia dice que Ruby es un lenguaje funcional, pero no estoy convencido. ¿Por qué o por qué no?
Wikipedia dice que Ruby es un lenguaje funcional, pero no estoy convencido. ¿Por qué o por qué no?
Respuestas:
Definitivamente creo que puedes usar un estilo funcional en Ruby.
Uno de los aspectos más críticos para poder programar en un estilo funcional es si el lenguaje admite funciones de orden superior ... lo que hace Ruby.
Dicho esto, también es fácil programar en Ruby en un estilo no funcional. Otro aspecto clave del estilo funcional es no tener estado y tener funciones matemáticas reales que siempre devuelvan el mismo valor para un conjunto dado de entradas. Esto se puede hacer en Ruby, pero no se aplica en el lenguaje como algo más estrictamente funcional como Haskell.
Entonces, sí, admite el estilo funcional, pero también te permitirá programar en un estilo no funcional.
Is ruby a functional language?
y en una respuesta directa es un simple no. Ruby es un lenguaje orientado a objetos con algunas características funcionales.
No importa si un idioma es o no un idioma funcional. La programación funcional es una tesis, mejor explicada por Philip Wadler (La esencia de la programación funcional) y John Hughes (Por qué importa la programación funcional).
Una pregunta significativa es: "¿Cuán dispuesto es Ruby a lograr la tesis de la programación funcional?" La respuesta es "muy mal".
Recientemente di una charla sobre esto. Aquí están las diapositivas.
Ruby admite funciones de nivel superior (consulte Array # map, inject, & select), pero sigue siendo un lenguaje imperativo orientado a objetos.
Una de las características clave de un lenguaje funcional es que evita el estado mutable. Los lenguajes funcionales no tienen el concepto de variable como lo tendrías en Ruby, C, Java o cualquier otro lenguaje imperativo.
Otra característica clave de un lenguaje funcional es que se centra en definir un programa en términos de "qué", en lugar de "cómo". Al programar en un lenguaje OO, escribimos clases y métodos para ocultar la implementación (el "cómo") del "qué" (el nombre de la clase / método), pero al final estos métodos todavía se escriben usando una secuencia de declaraciones. En un lenguaje funcional, no especifica una secuencia de ejecución, incluso en el nivel más bajo.
Presento que el apoyo o la capacidad de programar en un idioma con un estilo funcional no lo hace un lenguaje funcional.
Incluso puedo escribir código Java en un estilo funcional si quiero lastimar a mis colegas y a mí mismo durante unos meses. .
Tener un lenguaje funcional no se trata solo de lo que puede hacer, como funciones de orden superior, funciones de primera clase y currying. También se trata de lo que no puedes hacer, como los efectos secundarios en funciones puras.
Esto es importante porque es una gran parte de la razón por la que los programas funcionales, o el código funcional en general, es más fácil de razonar. Y cuando el código es más fácil de razonar, los errores se vuelven menos profundos y flotan hacia la superficie conceptual donde se pueden corregir, lo que a su vez genera menos errores en el código.
Ruby está orientado a objetos en su esencia, por lo que aunque tiene un soporte razonablemente bueno para un estilo funcional, no es en sí mismo un lenguaje funcional.
De todos modos, esa es mi opinión no científica.
Editar: En retrospectiva y teniendo en cuenta los excelentes comentarios que he recibido hasta ahora a esta respuesta, creo que la comparación entre la orientación a objetos y la funcional es una de manzanas y naranjas.
El verdadero diferenciador es el de ser impacientes en la ejecución, o no. Los lenguajes funcionales tienen la expresión como su construcción lingüística principal y el orden de ejecución a menudo no está definido o se define como perezoso. La ejecución estricta es posible, pero solo se usa cuando es necesario. En un lenguaje imparativo, la ejecución estricta es la predeterminada y, si bien la ejecución diferida es posible, a menudo es torpe y puede tener resultados impredecibles en muchos casos extremos.
Ahora, esa es mi opinión no científica.
Ruby tendrá que cumplir con los siguientes requisitos para ser funcional "REALMENTE".
Valores inmutables: una vez que se establece una "variable", no se puede cambiar. En Ruby, esto significa que efectivamente debe tratar las variables como constantes. No es totalmente compatible con el idioma, tendrá que congelar cada variable manualmente.
Sin efectos secundarios: cuando se le pasa un valor dado, una función siempre debe devolver el mismo resultado. Esto va de la mano con tener valores inmutables; una función nunca puede tomar un valor y cambiarlo, ya que esto causaría un efecto secundario que es tangencial a devolver un resultado.
Funciones de orden superior: son funciones que permiten funciones como argumentos o utilizan funciones como valor de retorno. Esta es, posiblemente, una de las características más críticas de cualquier lenguaje funcional.
Currying: habilitado por funciones de orden superior, currying es transformar una función que toma múltiples argumentos en una función que toma un argumento. Esto va de la mano con la aplicación de función parcial, que está transformando una función de múltiples argumentos en una función que toma menos argumentos de los que tenía originalmente.
Recursión: bucle llamando a una función desde su interior. Cuando no tiene acceso a datos mutables, la recursividad se usa para construir y encadenar la construcción de datos. Esto se debe a que el bucle no es un concepto funcional, ya que requiere que se pasen variables para almacenar el estado del bucle en un momento dado.
Evaluación perezosa o evaluación retardada: retrasar el procesamiento de valores hasta el momento en que realmente se necesita. Si, por ejemplo, tiene algún código que generó una lista de números de Fibonacci con la evaluación diferida habilitada, esto en realidad no se procesará ni calculará hasta que otra función requiera uno de los valores del resultado, como por ejemplo, put.
Propuesta (Solo un pensamiento)
Sería genial tener algún tipo de definición para tener una mode
directiva para declarar archivos con paradigma funcional, ejemplo
modo 'funcional'
Ruby es un lenguaje de múltiples paradigmas que admite un estilo funcional de programación.
Ruby es un lenguaje orientado a objetos, que puede soportar otros paradigmas (funcional, imperativo, etc.). Sin embargo, dado que todo en Ruby es un objeto, es principalmente un lenguaje OO.
ejemplo:
"hola" .reverse () = "olleh", cada cadena es una instancia de objeto de cadena y así sucesivamente.
Depende de su definición de "lenguaje funcional". Personalmente, creo que el término en sí mismo es bastante problemático cuando se usa como un absoluto. Hay más aspectos de ser un "lenguaje funcional" que meras características del lenguaje y la mayoría depende de dónde se mire. Por ejemplo, la cultura que rodea al idioma es bastante importante a este respecto. ¿Fomenta un estilo funcional? ¿Qué pasa con las bibliotecas disponibles? ¿Te animan a utilizarlos de forma funcional?
La mayoría de la gente llamaría a Scheme un lenguaje funcional, por ejemplo. Pero, ¿qué pasa con Common Lisp? Aparte del problema del espacio de nombres único / múltiple y la eliminación garantizada de la llamada final (que también admiten algunas implementaciones de CL, según la configuración del compilador), no hay mucho que haga que Scheme sea un lenguaje más adecuado para la programación funcional que Common Lisp, y aún así, la mayoría de los Lispers no llamarían a CL un lenguaje funcional. ¿Por qué? Porque la cultura que lo rodea depende en gran medida de las características imperativas de CL (como la macro LOOP, por ejemplo, que la mayoría de los Schemers probablemente desaprobarían).
Por otro lado, un programador en C puede considerar CL como un lenguaje funcional. La mayoría del código escrito en cualquier dialecto Lisp es ciertamente mucho más funcional en estilo que su bloque habitual de código C, después de todo. Asimismo, Scheme es un lenguaje imperativo en comparación con Haskell. Por lo tanto, no creo que pueda haber una respuesta definitiva de sí o no. El hecho de llamar funcional o no a un lenguaje depende en gran medida de su punto de vista.
Ruby tampoco es un lenguaje de paradigmas múltiples, creo. El multi-paradigma tiende a ser utilizado por personas que desean etiquetar su idioma favorito como algo útil en muchas áreas diferentes.
Describiría que Ruby es un lenguaje de secuencias de comandos orientado a objetos. Sí, las funciones son objetos de primera clase (más o menos), pero eso realmente no lo convierte en un lenguaje funcional. En mi opinión, podría agregar.
La recursividad es común en la programación funcional. Casi todos los lenguajes admiten la recursividad, pero los algoritmos recursivos suelen ser ineficaces si no hay optimización de llamadas finales (TCO).
Los lenguajes de programación funcional son capaces de optimizar la recursividad de la cola y pueden ejecutar dicho código en un espacio constante. Algunas implementaciones de Ruby optimizan la recursividad de la cola, las otras no, pero en general las implementaciones de Ruby no son necesarias para hacer TCO. Consulte ¿Ruby realiza la optimización de llamadas finales?
Por lo tanto, si escribe un estilo funcional de Ruby y confía en el TCO de alguna implementación en particular, su código puede ser muy ineficaz en otro intérprete de Ruby. Creo que esta es la razón por la que Ruby no es un lenguaje funcional (tampoco lo es Python).
Estrictamente hablando, no tiene sentido describir un lenguaje como "funcional"; la mayoría de los lenguajes son capaces de programación funcional. Incluso C ++ lo es.
El estilo funcional es más o menos un subconjunto de características imperativas del lenguaje, compatible con azúcar sintáctico y algunas optimizaciones del compilador como la inmutabilidad y el aplanamiento de recursividad de cola,
Podría decirse que este último es un pequeño tecnicismo específico de la implementación y no tiene nada que ver con el lenguaje real. El compilador x64 C # 4.0 hace una optimización de recursividad de cola, mientras que el x86 no lo hace por alguna estúpida razón.
El azúcar sintáctico generalmente se puede trabajar en un grado u otro, especialmente si el lenguaje tiene un precompilador programable (es decir, #define de C).
Podría ser un poco más significativo preguntar "¿el lenguaje __ admite la programación imperativa?", Y la respuesta, por ejemplo con Lisp, es "no".
Por favor, eche un vistazo al principio del libro: "A-Great-Ruby-eBook" . Discute el tema muy específico que está preguntando. Puedes hacer diferentes tipos de programación en Ruby. Si desea programar como funcionalmente, puede hacerlo. Si desea programar como imperativamente, puede hacerlo. Es una pregunta de definición qué tan funcional es Ruby al final. Por favor, vea la respuesta del usuario camflan.