Pensamiento funcional Parte 2

Amigos, seguimos entendiendo la programación funcional. En la segunda parte de esta serie de artículos, conocerá los principios básicos de este paradigma de desarrollo y comprenderá cómo este enfoque difiere de la programación orientada a objetos o imperativa.




Valores y funciones


Una vez más, considere esta función simple.


let add1 x = x + 1 

¿Qué significa x aquí?


  1. Tome algún valor del dominio (alcance).
  2. Use el nombre " x " para proporcionar este valor para que se pueda acceder más tarde.

El uso de un nombre para representar un valor se llama enlace. El nombre " x " está "vinculado" al valor de entrada.


Entonces, si calcula una función con un valor de entrada de, digamos, 5, sucederá lo siguiente: donde sea que " x " esté en la definición original, se establece el valor 5, similar a la función "buscar y reemplazar" en un editor de texto.


 let add1 x = x + 1 add1 5 //  «x» with «5» // add1 5 = 5 + 1 = 6 //  6 

Es importante entender que esto no es una tarea. " x " no es una "ranura" y no es una variable con un valor asignado que se puede cambiar más adelante. Esta es una asociación única del nombre " x " con un cierto valor. Este valor es uno de los enteros predefinidos; no se puede cambiar. Es decir una vez enlazado x no se puede cambiar . La etiqueta una vez asociada con el valor siempre está asociada con este valor.


Este principio es una parte crítica del pensamiento funcional: no hay "variables", solo valores .


Funciones como valores


Si lo piensa un poco más, puede ver que el nombre " add1 " en sí mismo es solo un enlace a "una función que aumenta la entrada en uno". La función en sí es independiente del nombre que se le asigna.


Al introducir let add1 x = x + 1 , le decimos al compilador de F # "cada vez que vea el nombre" add1 ", reemplácelo con una función que agregue 1 a la entrada". " add1 " se llama un valor de función .


Para ver que la función no depende de su nombre, es suficiente ejecutar el siguiente código:


 let add1 x = x + 1 let plus1 = add1 add1 5 plus1 5 

Como puede ver, " add " y " plus " son dos nombres vinculados a la misma función.


Siempre puede identificar una función de valor por su firma, que tiene el domain -> range forma estándar domain -> range . La firma generalizada de la función de valor:


 val functionName : domain -> range 

Valores simples


Imagine una operación que no toma nada y siempre devuelve 5.



Sería una operación "constante".


¿Cómo podría describirse esto en F #? Queremos decirle al compilador: "cada vez que vea el nombre c , reemplácelo con 5". Así:


 let c = 5 

Al calcular volverá:


 val c : int = 5 

Esta vez no hay una flecha que coincida, solo una int. De lo nuevo: un signo igual con el valor real deducido después. El compilador de F # sabe que este enlace tiene un valor conocido, que siempre se devolverá, es decir, el número 5.


En otras palabras, acabamos de definir una constante o, en términos de F #, un valor simple.
Siempre puede distinguir un valor simple de una función de valor, porque todos los valores simples tienen una firma similar:


 val aName: type = constant //  -   

Valores simples vs. valores de función | Significado simple vs. funciones de valor


Es importante comprender que en F #, a diferencia de otros lenguajes como C #, hay muy poca diferencia entre valores simples y funciones de valor. Ambos tipos son valores que se pueden asociar con nombres (usando la palabra clave let ), después de lo cual se pueden pasar a todas partes. De hecho, pronto veremos que la idea de que las funciones son valores que se pueden pasar como entrada a otras funciones es uno de los aspectos clave del pensamiento funcional.


Tenga en cuenta que existe una ligera diferencia entre un valor simple y una función de valor. Una función siempre tiene dominio y rango, y debe "aplicarse" al argumento para devolver el resultado. No es necesario calcular un valor simple después del enlace. Usando el ejemplo anterior, si queremos definir una "función constante" que devuelva 5, podríamos usar:


 let c = fun()->5 // or let c() = 5 

La firma de tales funciones se ve así:


 val c : unit -> int 

No asi:


 val c : int = 5 

Más adelante se proporcionará más información sobre la unit , la sintaxis de la función y las funciones anónimas.


"Valores" vs. "Objetos"


En lenguajes de programación funcionales, como F #, la mayoría de las cosas se llaman "valores". En lenguajes orientados a objetos, como C #, la mayoría de las cosas se llaman "objetos". ¿Cuál es la diferencia entre "significado" y "objeto"?


El valor, como vimos anteriormente, es un miembro del dominio. El dominio de enteros, el dominio de cadenas, el dominio de funciones que mapean enteros a cadenas, etc. En principio, los valores son inmutables (no mutables). Y los significados no tienen el comportamiento asociado a ellos.


Los objetos en la definición canónica son la encapsulación de la estructura de datos con el comportamiento asociado (métodos). En general, los objetos deben tener un estado (es decir, ser mutable), y todas las operaciones que cambian el estado interno deben ser proporcionadas por el propio objeto (a través de una notación de "punto").


En F #, incluso los valores primitivos tienen una cierta cantidad de comportamiento de "objeto". Por ejemplo, puede obtener la longitud de una cadena a través de un punto:


 «abc».Length 

Pero en general, evitaremos el término "objeto" para los valores estándar en F #, guardándolo para referirnos a clases completas u otros valores que proporcionan métodos.


Nombrando valores


Las convenciones de nomenclatura estándar utilizadas para los nombres de valores y funciones son básicamente caracteres alfanuméricos + guiones bajos. Pero hay un par de adiciones:


  1. Puede agregar un apóstrofe en cualquier parte del nombre, excluyendo el primer carácter.

 A'b'c begin' //   

  1. El último caso se usa a menudo como una etiqueta para versiones "diferentes" de un valor:

 let f = x let f' = derivative f let f'' = derivative f' 

o para variables del mismo nombre con palabras clave existentes


 let if' btf = if b then t else f 

También puede usar dobles comillas para cualquier cadena para que sea un identificador válido.


 ``this is a name`` ``123`` //  

Casos en los que es posible que necesite usar un truco de retroceso doble:


  • Cuando necesite usar un identificador que coincida con la palabra clave.

 let ``begin`` = «begin» 

  • Cuando necesite usar lenguajes naturales para reglas comerciales, pruebas unitarias o documentación ejecutable de estilo BBD como Cucumber.

 let ``is first time customer?`` = true let ``add gift to order`` = () if ``is first time customer?`` then ``add gift to order`` // - let [<Test>] ``When input is 2 then expect square is 4``= // code here // BDD clause let [<Given>] ``I have (.*) N products in my cart`` (n:int) = // code here 

A diferencia de C #, la convención de nomenclatura de F # requiere que las funciones y los valores comiencen con una letra minúscula, no mayúscula ( camelCase , no PascalCase ), a menos que estén diseñados para interactuar con otros lenguajes .NET. Sin embargo, los tipos y módulos usan letras mayúsculas (al principio).


Recursos Adicionales


Hay muchos tutoriales para F #, incluidos los materiales para aquellos que vienen con experiencia en C # o Java. Los siguientes enlaces pueden ser útiles a medida que profundiza en F #:



También se describen varias otras formas de comenzar a aprender F # .


Finalmente, la comunidad F # es muy amigable para principiantes. Hay un chat muy activo en Slack, respaldado por la F # Software Foundation, con salas para principiantes a las que puedes unirte libremente . ¡Recomendamos encarecidamente que haga esto!


¡No te olvides de visitar el sitio de la comunidad de habla rusa F # ! Si tiene alguna pregunta sobre el aprendizaje de un idioma, estaremos encantados de discutirlo en las salas de chat:



Sobre autores de traducción


Traducido por @kleidemos
La traducción y los cambios editoriales fueron realizados por los esfuerzos de la comunidad de desarrolladores de F # de habla rusa . También agradecemos a @schvepsss y @shwars por preparar este artículo para su publicación.

Source: https://habr.com/ru/post/es420039/


All Articles