¿La programación funcional da como resultado programas más seguros?

Sí puede. Antes de responder con más detalle, es importante discutir que hay grados de “programación funcional”. ¿Clojure es un lenguaje funcional? R? ¿Pitón? Lisp común? No todo el mundo está de acuerdo en que “la línea” entre lo funcional y lo habitual es disfuncional (significado disfuncional , “imperativo cuando no debería ser o de una forma peligrosamente descontrolada”, porque la programación imperativa es absolutamente adecuada para algunos problemas y generalmente es inofensiva). pequeños pedazos de código) vive la programación.

La mayoría de los idiomas son “funcionales”. Ese es el primer nivel. Eso incluye Python, con funciones de orden superior y funciones de mapa y filtro. Eso es útil, pero realmente no cambia la forma en que la mayoría de las personas codifican. El segundo nivel sería “funcionalmente alentado”, que es lo que son la mayoría de los lenguajes: Clojure, ML y Haskell están en esta categoría, aunque Haskell podría ser “funcionalmente altamente alentado” porque el sistema de tipos espera que las funciones normales no tengan estado, y se considera un error escribir una función con estado con la firma de tipo de una sin estado. (Puede usar unsafePerformIO para evadir la mónada IO y otorgar firmas de tipo sin estado a las funciones externas con estado, pero se considera un código incorrecto si la función tiene estado semántico). Entonces, uno podría ser “funcional-requerido”, lo que generalmente significa que los efectos con estado se segregan a una pequeña parte crítica del programa que se anota claramente como el único responsable de la ejecución , mientras que la mayor parte del código realiza cálculos sin estado. Haskell usando -XSafe estaría en esta categoría. En general, la programación funcional requerida es más restrictiva de lo que la mayoría de los programadores tolerarían. Entonces, “programación funcional” generalmente significa el segundo de estos tres niveles: programación funcional alentada .

Dicho todo esto, respondamos la pregunta. Primero, la habilitación de características funcionales (como en Python o Ruby) puede hacer que el código sea mucho más conciso. Con menos líneas de código y menos complejidad accidental, los programadores pueden prestar más atención a la esencia de lo que se está haciendo y detectar errores más fácilmente. Entonces, sí, incluso un poco de programación funcional (Python no es tan funcional) puede facilitar la escritura del código correcto (y seguro). Por supuesto, eso no garantiza nada y, cuando se trata de seguridad, generalmente no hay garantías porque, por así decirlo, ni las computadoras ni los humanos pueden reconocer de manera confiable a los “malos”.

Con la fuerte tipificación estática de Haskell, puede ir un poco más allá, ya que en realidad puede establecer requisitos estrictos en el sistema de tipos. (Esto se puede lograr con las comprobaciones de tiempo de ejecución en lenguajes dinámicos, pero eso requiere que los humanos sigan constantemente una política de lo que se verifica y lo que no.) Por ejemplo, en lugar de exponer una API SQL que acepta cadenas sin formato (no hacer eso!) puede escribir una función con la firma de tipo Consulta -> SanitizedString y solo aceptar SanitizedStrings para el motor SQL. Esto le permite controlar qué tipos de consultas están permitidas a través del tipo de consulta.

No obtienes “seguridad” gratis porque no siempre es un concepto bien definido, y porque los humanos son sorprendentemente ingeniosos cuando hay algo que ganar al romper un programa, pero la programación funcional y especialmente la programación funcional de tipo estático hacen que Es más fácil escribir código seguro.

El término “seguro” está un poco sobrecargado en este contexto. Supongo que está hablando de la fiabilidad del programa que escribo. La programación funcional es programación con funciones puras . Pero en los modelos de la vida real, todas las cosas interesantes suceden con efectos secundarios. Por lo tanto, en FP, es importante abordar este problema también. Los efectos secundarios no son referencialmente transparentes, los efectos secundarios no se componen y, por lo tanto, no son puros . La disciplina más importante que debemos respetar en la programación funcional es aislar los efectos secundarios del código puro.

Si hacemos eso, entonces podemos razonar sobre las funciones puras que escribimos, al igual que podemos hacer en matemáticas. Podemos hacer pruebas para demostrar que la función pura cumple los contratos que modelamos. Esto se llama razonamiento de los programas y solo se puede hacer si su programa promete pureza. De hecho, hay sistemas como Agda y COQ donde puede comenzar con una prueba y luego convertirla en un programa.

Consideremos un ejemplo de tal prueba que puedes hacer con una función pura que escribes en Haskell. Usaremos la prueba por inducción al igual que podemos hacer en matemáticas. Este ejemplo es del libro de Simon Thompson Haskell – El arte de la programación funcional ( http://www.amazon.com/Haskell-Fu …).

Escribo una función doubleAll que duplicará todos los elementos de una lista.

  doubleAll [] = []
 doubleAll (z: zs) = 2 * z: doubleAll zs 

Para probar que la función realmente hace lo que pretendemos hacer, podemos comenzar verificando algunas propiedades que la función debe respetar. Una de esas propiedades es cómo doubleAll interactúa con sum (una función para sumar todos los elementos de una lista). En otras palabras, la siguiente propiedad debe mantenerse:

sum (doubleAll xs) = 2 * sum xs

Aquí está el caso base para la inducción:

  suma (doubleAll [])
   = suma []
   = 0 

Y el RHS ..

  2 * suma []
   = 2 * 0
   = 0 

Y ahora el paso de inducción:

Hipótesis de inducción:

sum (doubleAll xs) = 2 * sum xs

Entonces podemos mostrar

  sum (doubleAll (x: xs))
   = suma (2 * x: doubleAll xs) (vea la definición de doubleAll arriba)
   = 2 * x + suma (doubleAll xs) (definición de suma)

y luego el lado derecho

  2 * suma (x: xs)
   = 2 * (x + suma xs) (definición de suma)
   = 2 * x + 2 * suma xs (por arith) 

Ahora necesitamos mostrar que las 2 expresiones anteriores son iguales, lo cual son en virtud de nuestra hipótesis de inducción ya que

  2 * x + suma (doubleAll xs)
   = 2 * x + 2 * sum xs (aplica hyp al segundo término) 

Por lo tanto, con funciones puras podemos probar la exactitud de nuestros programas. Esto se llama razonamiento equitativo y es una buena herramienta para agregar confiabilidad a nuestros programas.

Sí, porque le brinda mejores herramientas para escribir programas correctos con menos defectos. Y a través de la transparencia referencial, son más simples de verificar formal e informalmente.

La verificación de tipo estático también es indispensable aquí. Puede codificar muchas propiedades necesarias en tipos y hacer que el compilador las pruebe. Por ejemplo, si una función se define como aceptar un valor de autorización, el compilador ha demostrado que ha obtenido dicho valor dentro del marco de tipos del programa, no un valor falsificado, al evaluar la función. Esto no es cierto para los sistemas de tipo dinámico, que carecen de tal prueba deben hacer tal verificación en tiempo de ejecución y, por lo tanto, aceptarán un valor falsificado.

Para ver una ilustración de cómo la seguridad de tipos se extiende hasta el código de máquina, consulte el documento Del sistema F al lenguaje de ensamblaje mecanografiado, https://www.cs.princeton.edu/~dp

No necesariamente

¿Tal vez? Esas dos dimensiones son sesgadas. Podría crear fácilmente una aplicación insegura que sea funcional.

More Interesting

¿Para qué se usa UML?

¿Cómo puede ser excepcionalmente bueno para encontrar código para un problema (aplicación / software) que ya ha sido codificado?

Quiero ser programador web. Todavía no sé nada: pizarra limpia. Soy de una carrera relacionada con la salud. ¿Como empiezo?

¿Cuál es la mejor plataforma para desarrollar software para el tráfico de difusión y el software de programación completo con métrica detallada?

¿Cuál es la diferencia entre especificación e implementación en informática? ¿Cómo pueden estos dos ser claramente diferenciados en una tesis?

¿Elegiría Node.js / Express.js o Play framework (Java) para un nuevo proyecto de aplicación web? ¿Por qué?

Dada su mano de obra altamente calificada, ¿por qué la TI india (software, semiconductores, etc.) continúa ganando menos que sus pares occidentales?

Cómo vender mi solución de software a mi empleador y evitar conflictos de intereses

Si los requisitos del cliente cambian continuamente como probador, ¿cómo va a gestionar la situación?

¿Es cierto que las grandes empresas tecnológicas se aprovechan de los recién graduados universitarios?

¿Cuáles son buenas referencias para las tasas globales de desarrolladores de software?

¿Qué patrones de diseño se usan popularmente en el desarrollo de software?

¿Los ingenieros de software todavía usan formularios de Windows para hacer programas en C #?

¿Qué problemas de ingeniería de software de la vida real sobresale Haskell?

¿Cuál es el paquete de compensación para un nuevo ingeniero de software graduado que comienza en Microsoft en 2014?