Desde mi exposición (ciertamente limitada) a lenguajes de programación funcionales, como Clojure, parece que la encapsulación de datos tiene un papel menos importante. Por lo general, varios tipos nativos, como mapas o conjuntos, son la moneda preferida para representar datos sobre los objetos. Además, esos datos son generalmente inmutables.
Por ejemplo, aquí está una de las citas más famosas de Rich Hickey de la fama Clojure, en una entrevista sobre el asunto :
Fogus: Siguiendo esa idea, algunas personas se sorprenden por el hecho de que Clojure no participa en la encapsulación de ocultación de datos en sus tipos. ¿Por qué decidiste renunciar a ocultar datos?
Hickey: Seamos claros, Clojure enfatiza fuertemente la programación a las abstracciones. Sin embargo, en algún momento, alguien necesitará tener acceso a los datos. Y si tiene una noción de "privado", necesita las nociones correspondientes de privilegio y confianza. Y eso agrega un montón de complejidad y poco valor, crea rigidez en un sistema y a menudo obliga a las cosas a vivir en lugares que no deberían. Esto se suma a la otra pérdida que ocurre cuando la información simple se coloca en clases. En la medida en que los datos sean inmutables, hay poco daño que puede resultar de proporcionar acceso, aparte de que alguien podría llegar a depender de algo que podría cambiar. Bueno, está bien, la gente hace eso todo el tiempo en la vida real, y cuando las cosas cambian, se adaptan. Y si son racionales, saben cuándo toman una decisión basada en algo que puede cambiar y que en el futuro podrían necesitar adaptarse. Por lo tanto, es una decisión de gestión de riesgos, una que creo que los programadores deberían tener libertad para tomar. Si las personas no tienen la sensibilidad para desear programar en abstracciones y desconfiar de casarse con los detalles de implementación, entonces nunca serán buenos programadores.
Viniendo del mundo OO, esto parece complicar algunos de los principios consagrados que he aprendido a lo largo de los años. Estos incluyen información oculta, la ley de Demeter y el principio de acceso uniforme, por nombrar algunos. El hilo común es que la encapsulación nos permite definir una API para que otros sepan qué deben y qué no deben tocar. En esencia, crear un contrato que permita al responsable del mantenimiento de algunos códigos realizar libremente cambios y refactorizaciones sin preocuparse de cómo podría introducir errores en el código del consumidor (principio abierto / cerrado). También proporciona una interfaz limpia y curada para que otros programadores sepan qué herramientas pueden usar para obtener o aprovechar esos datos.
Cuando se permite acceder directamente a los datos, ese contrato de API se rompe y todos esos beneficios de encapsulación parecen desaparecer. Además, los datos estrictamente inmutables parecen hacer que pasar estructuras específicas de dominio (objetos, estructuras, registros) sea mucho menos útil en el sentido de representar un estado y el conjunto de acciones que se pueden realizar en ese estado.
¿Cómo abordan las bases de código funcionales estos problemas que parecen surgir cuando el tamaño de una base de código crece enormemente, de modo que las API deben definirse y muchos desarrolladores participan en el trabajo con partes específicas del sistema? ¿Hay ejemplos de esta situación disponibles que demuestren cómo se maneja esto en este tipo de bases de código?
Also, strictly immutable data seems to make passing around domain-specific structures (objects, structs, records) much less useful in the sense of representing a state and the set of actions that can be performed on that state.Realmente no. Lo único que cambia es que los cambios terminan en un nuevo objeto. Esta es una gran victoria cuando se trata de razonar sobre el código; pasar objetos mutables significa tener que hacer un seguimiento de quién podría mutarlos, un problema que aumenta con el tamaño del código.