Definição formal para o termo "linguagem OO pura"?

13

Não consigo pensar em um lugar melhor entre os irmãos SO para fazer essa pergunta. Originalmente, eu queria perguntar "O python é uma linguagem OO pura?" mas considerando problemas e algum tipo de desconforto que as pessoas experimentam ao tentar definir o termo, decidi começar por obter uma definição clara para o termo em si.

Seria bastante justo começar com a correspondência do Dr. Alan Kay, que cunhou o termo (observe a inspiração na analogia biológica para células ou outros objetos vivos).

Existem as seguintes maneiras de abordar a tarefa:

  1. Faça uma análise comparativa listando linguagens de programação que podem exibir (ou deixar de fazê-lo) certas propriedades únicas e suficientes para definir o termo (embora Smalltalk, Scala, Java e assim por diante - sejam exemplos possíveis, mas o IMO dessa maneira não parece realmente completo nem frutífero )
  2. Dê uma definição formal (ou próxima a ela, por exemplo, em estilo mais acadêmico ou matemático).
  3. Dê uma definição filosófica que se baseie totalmente no contexto semântico da linguagem concreta ou em uma experiência de programação a priori (deve haver alguma chance de explicação bem-sucedida da comunidade).

Minha versão atual: "Se uma certa linguagem de programação ( formal ) que pode ( gramaticalmente ) diferenciar operações e operandos, bem como inferir sobre o tipo de cada operando, se esse tipo é um objeto (no sentido de POO) ou não, então chamamos essa linguagem é uma linguagem OO, desde que exista pelo menos um tipo nessa linguagem que seja um objeto. Por fim, se todos os tipos de linguagem também forem objetos, definimos que essa linguagem é uma linguagem OO pura (forte) ".

Gostaria de receber qualquer possível melhoria dele. Como você pode ver, acabei de tornar a definição dependente do termo "objeto" (geralmente totalmente referenciado como classe de objetos).

[EDITAR]

Além disso, eu uso (felizmente bem entendido) a noção de um tipo como nas linguagens digitadas. A programação de tipos de dados ou programação orientada a tipos não é apenas uma interpretação sintática (do texto do programa, ou seja, como tratar certos valores de literais e variáveis ​​de dados - algo que evolui para a segurança de tipos), mas pode ser atribuída à gramática da linguagem e estudada de maneira formal (usando lógica matemática) como os chamados sistemas de tipos . Observe que exigir que um sistema de tipos específico tenha o chamado tipo universal é uma das maneiras de definir a pureza da linguagem OO (existem maneiras de expandir isso semanticamente).

NB

como responder :

  • ajuda se você especificar um livro ou uma referência que suporte / explique sua compreensão de terminologia e conceitos (geralmente uma boa definição cobre ou faz referência a todos os conceitos dependentes, exceto os elementares).
  • se possível, indique uma categoria recuada da sua resposta / definição, se não estiver claro o contrário (veja acima: 1 - por exemplo de linguagem, 2 - lógica matemática, 3 - descrição técnica e filosofia de programação)
  • a classificação é importante (e também porque o termo OO puro é incluído no termo OO) ao responder tentar desmistificar elementos do paradigma OO de outras metodologias conhecidas (e de nenhuma maneira confundir / sobrepor-los, por exemplo, elementos tipicamente da programação modular podem ser cobertos / incorporada à programação OO): tente distinguir OOP de (incluindo ou fazer parte de) programação funcional, programação lógica (especialmente altamente especializada), tipos de dados Abstarct (ADT), modular, metaprogramação (genéricos e tempo de macroexpansão do LISP), Contratos (por exemplo, Eiffel), orientado a aspectos (AO), ( são claras as diferenças entre a classificação declarativa e a funcionalidade, bem como as definições históricas da estrutura de Dijkstra)

na dificuldade de fornecer uma definição formal : surpreendentemente, é muito fácil fornecer uma descrição matemática do OOP na forma de um determinado sistema lógico (formal) (provavelmente baseado no tipo) e definir um conceito após o outro. Pode-se até tentar fazer algo mais prático aplicando esse formalismo a tipos de verificação de segurança ou aspectos de design de nova linguagem do que apenas entretenimento ou exercíciosabstratos(também procure formulação de OOP em Teoria Intuicionista de Tipos , tipos dependentes , independentemente, em formalismos FOL como cálculo lambda e apenas usando a teoria das categorias). Um ponto principal aqui é que sem surpresatais formulações IMO são fortemente tendenciosas (falhas) pelo entendimento provavelmente incompleto inicialmente de OOP (em engenharia da computação) e acabam sendo quase inacessíveis posteriormente (dificilmente contribuindo para trás no mundo da programação - talvez, exceto que certa porcentagem encontre aplicativos de volta ao mundo formal sendo integrado em idiomas populares ).

Então, sim, é difícil fornecer exatamente uma definição "boa", não apenas uma definição. Mas sou positivo em perguntar isso aqui por causa de sua experiência e envolvimento direto, pessoal.

Yauhen Yakimovich
fonte
2
Bem, você já respondeu a si mesmo pelo Python. "Não".
Psr
2
+1 para a boa pergunta, mas sua versão é um pouco falha pelo problema de que um tipo e um objeto são coisas diferentes.
Frank
5
@JoachimSauer: Ele disse em outro e-mail na lista de e-mails do Squeak que "a grande idéia é Messaging" e que lamenta já tê-lo chamado de "Orientado a Objetos" e, em vez disso, deveria ter chamado de "Orientado a Mensagens". Erlang, por exemplo, é uma linguagem totalmente orientada a objetos que atende a todos os critérios do Dr. Kay sem ter nenhum conceito em todos os "objetos", "métodos", "herança", "classes", "protótipos" ou algo assim .
Jörg W Mittag
1
Pode ser uma boa ilustração de que as sintaxes não são suficientes para definir uma linguagem OO. Se alguém puder mostrar que OOP (por exemplo, como uma ferramenta) é apenas semântico (independente de sintaxe), isso muda (inverte) minha pergunta completamente!
Yauhen Yakimovich 13/09/12
2
@YauhenYakimovich Este é um dos principais problemas da discussão sobre OOP, todos e seu cão têm sua própria idéia do que é. Em contraste, programação estruturada e programação funcional podem ser definidas de maneira muito simples. Isso me leva a questionar se o OO tem propriedades semelhantes à religião, em vez de à ciência.
Ricky Clarkson

Respostas:

19

OO, de acordo com Alan Kay, tem tudo a ver com a transmissão de mensagens, e é isso. Você verá que qualidades como polimorfismo e encapsulamento são realmente derivadas da passagem de mensagens.

Agora, essa postura é de fato muito extrema, porque basicamente significa que apenas o Smalltalk e os idiomas se qualificariam.

Eu acho que você pode definir OO como construindo seu sistema em entidades, que encapsulam completamente seu estado e são trocadas devido a suas qualidades polimórficas inerentes. Alguém poderia argumentar que uma linguagem puramente OO garante que essas duas qualidades principais sejam sempre atendidas. O que torna as linguagens OO "impuras" seriam mecanismos que permitam a criação de construções que não atendem a esses critérios, como as possibilidades de:

  • declarar campos públicos
  • declarar variáveis ​​que só podem conter instâncias de uma classe específica e suas subclasses (ou seja, variáveis ​​devem ser digitadas em interfaces, que é o que os objetos biológicos se comunicam na anologia de Kay), que são ainda mais restritas se a classe em questão for final, como que deixa ainda menos espaço para o polimorfismo
  • declarar primitivas

Então, novamente, a pureza da linguagem IMHO é mais uma fraqueza do que uma força. OO não é uma bala de prata. Nenhum paradigma é único.

back2dos
fonte
2
+1 para "OO não é uma bala de prata".
Andres F.12 /
1
@AndresF. Observe que o valor prático da POO, bem como outros conhecimentos teóricos relacionados à programação, não são realmente parte de uma pergunta. É bastante óbvio que alguém pode escrever código de uma maneira bem-sucedida sem qualquer conhecimento profundo de técnicas ou teorias de programação (e vice-versa). Nem as propriedades de aplicativos das linguagens OO são discutidas, etc.
Yauhen Yakimovich 12/12/12
@YauhenYakimovich Oh, eu sei. Eu não teria votado a resposta se tivesse sido fora de tópico. Ainda assim, gostei de uma afirmação com a qual concordo.
Andres F.
@AndresF. Claro :-) "OO não é uma bala de prata" provavelmente é verdade, assim como nos falta uma linguagem de programação perfeita. Mas o que exatamente faz da POO não uma bala de prata? Assim como um bom relatório de erros, acho que uma terminologia detalhada e precisa é a maneira de responder a isso. Eu investi tanto tempo trabalhando com ele que estou muito curioso para trazê-lo para o próximo nível. OOP é apenas um monte de ideias copiadas de um livro de programação para outro?
Yauhen Yakimovich 12/12/12
@ back2dos +1 por apontar explicitamente o papel da "passagem de mensagens" de acordo com Kay (Smalltalk, Objective-C). Aparentemente, ele nunca pretendeu ver o POO desenvolvido para as direções que tem hoje. Mas gostei muito que Kay tivesse essas idéias para criar objetos, NÃO dados (tipos). Ele realmente insistiu em atribuir-lhes qualidades biológicas, mas acabou em "mensagens".
Yauhen Yakimovich
6

Eu abordaria isso definindo-o como uma linguagem que usa construções OOP e nada mais (da mesma maneira que uma linguagem FP pura usa funções puras com dados imutáveis ​​e nada mais).

Em particular:

  • Toda entidade em que seu programa opera é um Objeto de primeira classe - ou seja, sem primitivas, sem ponteiros, sem matrizes etc.
  • A única coisa que você pode fazer com um objeto é chamar um método (potencialmente polimórfico) (== enviando uma mensagem). Não existem outras operações.
  • Todos os dados são encapsulados - ou seja, sem acesso ao campo público, você deve usar métodos em um objeto
  • Se você possui funções de primeira classe, elas também devem ser objetos - portanto, você precisa fazer algo comofunctionObject.call(param1,param2)
  • Sem variáveis ​​globais - se você quiser algo assim, precisará usar um objeto para representar o ambiente global atual, por exemplo, environment.getValue("myThing")ou colocar a variável em um objeto de classe

Observe que isso ainda deixa várias opções em aberto:

  • Modelos de objetos baseados em classe vs. modelos baseados em protótipo
  • Como a herança é implementada (se houver)
  • Se você tem despacho único ou múltiplo nos métodos
  • Se seus objetos são digitados estaticamente ou dinamicamente
  • A sintaxe exata usada para chamadas de método (por exemplo, você pode ter algum açúcar sintático para getters / setters etc.)
Mikera
fonte
1
essas são boas definições, mas não confunda a realidade do objeto com a mera sintaxe. Só porque funções e variáveis ​​globais têm uma sintaxe amigável, elas podem realmente ser objetos no coração.
Ddyer 12/09/12
@ ddyer - isso é correto se for realmente apenas sintaxe, mas acho que se a sintaxe também introduzir semântica diferente, poderá quebrar a "pureza". Por exemplo, variáveis ​​globais wrt, o uso de globalVariableNamepara acessar uma variável global é uma semântica diferente de uma chamada de método em um objeto, que seria a única maneira de acessar um valor não local em OOP puro.
Mikera 12/09/12
Eu acho que "Tudo" precisa ser qualificado. Se uma linguagem não possui capacidade de reflexão (por exemplo, não pode fazer referência a um método de um objeto por um nome abstrato ou armazená-lo em uma variável), os métodos também precisam ser objetos? As referências são objetos? Referências e objetos são coisas diferentes?
Joachim Sauer
@ Joachim - bom ponto. Eu o qualifiquei como "toda entidade em que seu programa opera" para distinguir objetos de meta-objetos na linguagem, como nomes de variáveis ​​e construções sintáticas. Obviamente, se seu programa realmente opera essas coisas via reflexão, eles precisam ser reificados como objetos reais, mas isso nem sempre será um requisito. De qualquer forma, se você conseguir uma melhor qualificação, sinta-se à vontade para editá-la!
Mikera 12/09/12
"Modelos de objetos baseados em classe vs. modelos baseados em protótipo": mas eu diria que em ambos os casos você tem algum tipo de classificação, ou seja, agrupa objetos com uma estrutura e comportamento comuns.
Giorgio
4

A discussão sobre as chamadas linguagens OO sempre foi um pouco do lado do cérebro. Ou seja:

"Alguém me disse que a linguagem X é OO; portanto, a linguagem X é igual a OO; então, toda linguagem que não possui os recursos da linguagem X não pode ser OO. E, como estou escrevendo meu código na linguagem X, tudo o que faço é OO. "

O termo design orientado a objetos se resume a três coisas:

  1. Design modular com objetos autônomos que não conhecem informações desnecessárias sobre o restante do programa, também conhecido como acoplamento flexível possível.
  2. Encapsulamento de dados dentro de objetos para impedir o acesso externo, intencional e acidental.
  3. Dependências claramente especificadas entre objetos. Para obter acoplamentos soltos, mas também para facilitar a manutenção e expansão do programa.

1) é puro design de programa, pode ser alcançado em qualquer linguagem de programação. No entanto, alguns idiomas têm recursos úteis, como classe / estrutura e palavras-chave privadas.

2) é principalmente o design do programa, embora não possa ser totalmente alcançado sem o suporte ao idioma, pois você precisa de mecanismos de linguagem como privado / estático para proteger contra uso acidental.

3) é principalmente design de programa. Normalmente, existem três dependências diferentes: "o objeto X contém o objeto Y", "o objeto X é um tipo de Y" e "o objeto X interage com o objeto Y". Existem muitos recursos de linguagem para ajudar com essas dependências: herança / polimorfismo, classes base abstratas e assim por diante.

Agora, se olharmos para o acima, podemos ver que você quase não precisa de nenhum recurso de idioma para escrever programas OO. Os recursos apenas tornam muito mais fácil.

Os objetivos acima não podem ser alcançados usando-se uma lógica reversa enlameada: apenas porque você usa a palavra-chave class, seu programa não recebe automaticamente um design modular. Só porque você usa herança, isso não significa automaticamente que suas dependências de objeto fazem sentido. Um idioma com recursos OO ainda permitiria coisas como class TheWholeBloodyProgram"Animal herda gato".

Infelizmente, o tópico sobre o bom design de programas orientados a objetos raramente é mencionado nesse tipo de discussão. Os programadores com lavagem cerebral só olham para a sintaxe e gritam coisas como, por exemplo, "C ++ tem tipos de dados primitivos para que seu programa C ++ não seja OO", então eles escrevem um programa horrível em sua própria linguagem favorita, sem usar nenhuma dica de design do programa, o que for.

Para responder à pergunta: muito poucos, se houver algum idioma, oferecem suporte ao design adequado do programa OO. Descobrir quais idiomas que possuem certos recursos relacionados ao OO são irrelevantes, desde que o programador não saiba o que significa design orientado a objetos. Um programador que afirma que certas linguagens são orientadas a objetos provavelmente não entendeu o conceito de OO como um todo. Pergunte ao possível programador de OO como ele cria programas de OO. Se a primeira coisa que eles fazem é começar a gritar palavras-chave no idioma, você pode assumir com segurança que elas não conhecem o design do OO.

Talvez exista alguma ferramenta sofisticada de alto nível UML-ish muito acima do código-fonte bruto, que força o programador a escrever apenas programas com um bom design orientado a objetos, mas duvido. As melhores ferramentas de design para a programação OO provavelmente ainda são o cérebro humano e o senso comum.


fonte
Você pode esclarecer como sua definição difere, por exemplo, programação modular com tipos de dados abstratos? Acho que você está no caminho certo, mas ainda não consigo ver o trem!
Jörg W Mittag
@ JörgWMittag Não é necessariamente diferente: os ADT tradicionais: podem ser escritos usando design orientado a objetos, com encapsulamento adequado, setters / getters, maneiras de herdá-lo etc. etc. Mas eles também podem ser escritos sem considerar o design OO. ->
2
@ JörgWMittag Se você tem um idioma como C, por exemplo, com suporte limitado ao OO, é complicado escrever ADT: s de maneira orientada a objetos. O erro mais comum é deixar a alocação do ADT para o chamador, ou seja, fornecer a ele uma estrutura pública com todos os internos expostos, quebrando o encapsulamento. A maneira correta de fazer isso em C é através dos chamados "tipos opacos" (tipos incompletos), embora poucos programadores em C saibam usá-los.
@Lundin: No artigo publicado por JörgWMittag como comentário a outra resposta, há uma comparação interessante (IMO) entre ADT e OO.
Giorgio
Lembro-me de alguns livros da UML (provavelmente) de um ponto adicional 0. Abstração (enfatizando a importância da formulação abstrata essencial para relacionamentos entre objetos como polimorfismo, herança, agregação etc.).
Yauhen Yakimovich 12/12/12
2

Não, não existe uma definição formal ou mesmo útil, e nunca haverá. Para algumas pessoas, OOP significa "Classe base universal" e "Deve usar a semântica de referência, melhor com um coletor de lixo" - e você pode até ter dúvidas sobre a sintaxe, uma das coisas menos relevantes já inventadas.

Por fim, primeiro, você deve responder à pergunta "O que é um objeto?". Os mais mesquinhos insistirão em herdar de alguma classe básica universal inútil e serão desnecessariamente alocados em um coletor de lixo para se qualificar. Mas eu prefiro uma definição muito mais útil. O objetivo do OOP é ter alguns dados e algumas funções que você pode chamar nesses dados. então

  • Um objeto contém algum estado e oferece algumas funções nesse estado.

Nesse caso, até se intqualifica. Afinal, quando você escreve um código de modelo em C ++ que pode aceitar primitivos ou objetos, torna-se difícil argumentar que os primitivos são diferentes de maneira substancial. Não há nada significativamente diferente em Vector v1, v2; v1 + v2;vez de int v1, v2; v1 + v2;(exceto a semântica de inicialização de baixa qualidade, é preciso admitir). Além disso, isso permite que lambdas e essas coisas sejam objetos, como eles mantêm o estado - suas capturas - e oferecem uma função nesse estado, para chamar o lambda.

Felizmente, também podemos classificar ponteiros para liberar funções como objetos, pois ambos mantêm o estado (um endereço) e uma função nesse estado (para chamá-lo). Portanto, uma função livre deve ser permitida - mesmo se você disser que todas as funções livres são, de fato, indicadores globais de funções.

DeadMG
fonte
2
Não vejo necessidade de tal distinção. Mas, em segundo lugar, eles têm a mesma identidade que qualquer outro objeto possui comparação de endereço / referência. O fato de você não poder distinguir dois objetos com o mesmo estado, exceto comparando endereços, está longe de ser novo e se aplica a todos os objetos.
DeadMG
5
-1. Começa com um discurso inútil e desnecessário, logo muda para o ataque ad hominem e a única coisa até remotamente factual (a definição de OOP ) está errada. Leia Sobre a compreensão da abstração de dados, revisitada por William R. Cook, para saber a diferença entre um tipo de dado abstrato e um objeto.
Jörg W Mittag
1
"Não vejo necessidade de tal distinção.": Mas essa distinção está entre as características comumente aceitas dos objetos. Obviamente, você pode desenvolver sua própria noção de um objeto que é diferente do que é comumente aceito. Você é totalmente livre para fazê-lo.
Giorgio
2
@ Jörg Eu imploro para diferir. Não concordo inteiramente com este post, mas chamar a ressalva no primeiro parágrafo de "inútil" ou de "discurso retórico" é falso. Não existe uma definição universalmente acordada para OOP. Esse é um fato simples e amplamente reconhecido. O restante da postagem é uma definição de OOP. Certamente não é o mais amplamente usado, nem o que eu daria, mas, como disse o DeadMG, é realmente bastante útil.
Konrad Rudolph
2
@KonradRudolph: esse parágrafo parecia muito diferente quando escrevi meu comentário, incluindo a comparação de programadores que se preocupam com sintaxe com racistas, mesmo mencionando um usuário específico deste site pelo nome.
Jörg W Mittag
0

Você pode pensar nisso por exemplo negativo. Java não é uma linguagem orientada a objetos pura, porque também existem tipos primitivos que não são objetos. Estes são números inteiros, duplos, matrizes e assim por diante. Em uma linguagem pura de objetos, a semântica dos objetos está disponível para tudo.

Há também a questão de quanto da linguagem está fechada para modificação, mesmo dentro da estrutura do objeto. Em java, você não pode definir novas subclasses para algumas classes, como String ou Class.

Quais idiomas são puros? O único candidato que vem à mente é conversa fiada.

ddyer
fonte
O Ruby não é pura linguagem OO também?
Zxcdw 12/09/12
2
@zxcdw (e ddyer): esse é exatamente o problema: ninguém tem uma definição formal de "OO puro", então ninguém pode dar uma resposta definitiva a essa pergunta.
Joachim Sauer