... e provavelmente é um daqueles artigos nos quais o OOP foi baseado.
Na verdade, não, mas isso contribuiu para a discussão, especialmente para os profissionais que, na época, eram treinados para decompor sistemas usando os primeiros critérios que ele descreve no artigo.
Primeiro, quero saber se minha avaliação está correta. O paradigma do PF e este artigo discordam filosoficamente?
Não. Além disso, a meu ver, sua descrição de como é um programa FP não é diferente de nenhum outro que utilize procedimentos ou funções:
Os dados são transmitidos de função para função, cada função sendo intimamente ciente dos dados e "alterando-os" ao longo do caminho.
... exceto na parte "intimidade", já que você pode (e geralmente possui) funções operando em dados abstratos, precisamente para evitar a intimidade. Assim, você tem algum controle sobre essa "intimidade" e pode regulá-la como quiser, configurando interfaces (ou seja, funções) para o que deseja ocultar.
Portanto, não vejo razão para não sermos capazes de seguir os critérios de ocultação de informações de Parnas usando programação funcional e terminar com a implementação de um índice KWIC com benefícios semelhantes apontados como sua segunda implementação.
Supondo que eles concordem, eu gostaria de saber o que é a implementação dos FPs de ocultação de dados. É óbvio ver isso no OOP. Você pode ter um campo particular que ninguém fora da classe possa acessar. Não há analogia óbvia disso para mim no FP.
No que diz respeito aos dados, é possível elaborar abstrações de dados e abstrações de tipo de dados usando o FP. Qualquer um desses oculta estruturas e manipulações concretas dessas estruturas de concreto usando funções como abstrações.
EDITAR
Há um número crescente de afirmações aqui afirmando que "ocultar dados" no contexto do FP não é tão útil (ou OOP-ish (?)). Então, deixe-me carimbar aqui um exemplo muito simples e claro do SICP:
Suponha que seu sistema precise trabalhar com números racionais. Uma maneira de representá-los é como um par ou uma lista de dois números inteiros: o numerador e o denominador. Portanto:
(define my-rat (cons 1 2)) ; here is my 1/2
Se você ignorar a abstração de dados, provavelmente obterá o numerador e o denominador usando car
e cdr
:
(... (car my-rat)) ; do something with the numerator
Seguindo essa abordagem, todas as partes do sistema que manipulam números racionais saberão que um número racional é um cons
- elas cons
numerarão para criar racionais e extraí-las usando operadores de lista.
Um problema que você pode enfrentar é quando precisa ter uma forma reduzida dos números racionais - serão necessárias alterações em todo o sistema. Além disso, se você decidir reduzir no momento da criação, poderá descobrir mais tarde que reduzir ao acessar um dos termos racionais é melhor, gerando outra alteração em escala total.
Outro problema é se, hipoteticamente, uma representação alternativa é preferida e você decide abandonar a cons
representação - mudança em escala completa novamente.
Qualquer esforço sensato para lidar com essas situações provavelmente começará a esconder a representação dos racionais por trás das interfaces. No final, você pode acabar com algo assim:
(make-rat <n> <d>)
retorna o número racional cujo numerador é o número inteiro <n>
e cujo denominador é o número inteiro <d>
.
(numer <x>)
retorna o numerador do número racional <x>
.
(denom <x>)
retorna o denominador do número racional <x>
.
e o sistema não saberá mais (e não deve mais) saber do que são feitos os racionais. Isto porque cons
, car
e cdr
não são intrínsecos à racionais, mas make-rat
, numer
e denom
são . Obviamente, isso poderia ser facilmente um sistema de FP. Portanto, "ocultação de dados" (neste caso, mais conhecido como abstração de dados ou o esforço de encapsular representações e estruturas concretas) surge como um conceito relevante e uma técnica amplamente utilizada e explorada, seja no contexto de OO, programação funcional ou tanto faz.
E o ponto é ... embora se possa tentar fazer distinções entre que "tipo de ocultação" ou encapsulamento eles estão fazendo (estejam escondendo uma decisão de design, estruturas de dados ou algoritmos - no caso de abstrações processuais), todos eles têm o mesmo tema: são motivados por um ou mais pontos que Parnas explicitou. Isso é:
- Mudança: se as alterações necessárias podem ser feitas localmente ou espalhadas pelo sistema.
- Desenvolvimento Independente: em que grau duas partes do sistema podem ser desenvolvidas em paralelo.
- Compreensibilidade: quanto do sistema deve ser conhecido para entender uma de suas partes.
O exemplo acima foi retirado do livro do SICP, portanto, para a discussão e apresentação completa desses conceitos no livro, eu recomendo verificar o capítulo 2 . Eu também recomendo familiarizar-se com tipos de dados abstratos no contexto do FP, o que traz outros problemas para a tabela.