O que são objetos de "primeira classe"?

191

Quando os objetos ou algo mais são considerados "de primeira classe" em uma determinada linguagem de programação e por quê? Em que eles diferem dos idiomas em que não estão?

EDITAR. Quando alguém diz "tudo é um objeto" (como em Python), ele realmente quer dizer que "tudo é de primeira classe"?

Federico A. Ramponi
fonte
1
Seria possível migrar esta pergunta para programmers.SE? Ou seria um desajuste também? Eu acho que essa pergunta é boa. Apenas não é capaz de dizer qual fórum seria o melhor.
Shashank Sawant
16
Votado para reabrir ... infelizmente isso realmente parece que foi fechado por pessoas que não têm programa, é claramente sobre o tema: /
djechlin

Respostas:

176

Em resumo, significa que não há restrições ao uso do objeto. É o mesmo que qualquer outro objeto.

Um objeto de primeira classe é uma entidade que pode ser criada dinamicamente, destruída, transmitida para uma função, retornada como um valor e ter todos os direitos que outras variáveis ​​da linguagem de programação possuem.

Dependendo do idioma, isso pode implicar:

  • sendo expressável como um valor literal anônimo
  • sendo armazenável em variáveis
  • sendo armazenável em estruturas de dados
  • ter uma identidade intrínseca (independente de qualquer nome)
  • sendo comparável em termos de igualdade com outras entidades
  • sendo passável como parâmetro para um procedimento / função
  • retornável como resultado de um procedimento / função
  • sendo construtível em tempo de execução
  • sendo imprimível
  • sendo legível
  • sendo transmissível entre processos distribuídos
  • sendo armazenável fora dos processos em execução

Fonte .

No C ++, as próprias funções não são objetos de primeira classe, no entanto:

  • Você pode substituir o operador '()' tornando possível ter uma função de objeto, que é de primeira classe.
  • Ponteiros de função são de primeira classe.
  • boost bind, lambda e function oferecem funções de primeira classe

No C ++, classes não são objetos de primeira classe, mas instâncias dessas classes. No Python, as classes e os objetos são objetos de primeira classe. (Veja esta resposta para mais detalhes sobre classes como objetos).

Aqui está um exemplo de funções de primeira classe Javascript:

// f: function that takes a number and returns a number
// deltaX: small positive number
// returns a function that is an approximate derivative of f
function makeDerivative( f, deltaX )
{
    var deriv = function(x)
    { 
       return ( f(x + deltaX) - f(x) )/ deltaX;
    }
    return deriv;
}
var cos = makeDerivative( Math.sin, 0.000001);
// cos(0)     ~> 1
// cos(pi/2)  ~> 0

Fonte .

As entidades que não são objetos de primeira classe são chamadas de objetos de segunda classe. Funções em C ++ são de segunda classe porque não podem ser criadas dinamicamente.

Em relação à edição:

EDITAR. Quando alguém diz "tudo é um objeto" (como em Python), ele realmente quer dizer que "tudo é de primeira classe"?

O termo objeto pode ser usado livremente e não implica ser de primeira classe. E provavelmente faria mais sentido chamar todo o conceito de 'entidades de primeira classe'. Mas em Python, eles pretendem tornar tudo de primeira classe. Acredito que a intenção da pessoa que fez sua declaração significou primeira classe.

Brian R. Bondy
fonte
2
Você pode dar alguns exemplos de objetos que não são de 'primeira classe'?
Sudip Bhandari
1
@SudipBhandari Eu me perguntei a mesma coisa, finalmente encontrei o útil artigo da Wikipedia sobre este tópico: cidadão / objeto de primeira classe . Achei a definição de Robin Popplestone especialmente útil. (Btw, postando um artigo WP pode parecer super-óbvio, mas eu não sabia que este era um conceito linguagem de programação fundamental)
mblakesley
19

"Quando alguém diz" tudo é um objeto "(como em Python), ele realmente quer dizer que" tudo é de primeira classe "?"

Sim.

Tudo em Python é um objeto adequado. Até coisas que são "tipos primitivos" em outros idiomas.

Você descobre que um objeto como 2na verdade tem uma interface bastante rica e sofisticada.

>>> dir(2)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__str__', '__sub__', '__truediv__', '__xor__']

Como tudo é um objeto de primeira classe em Python, há relativamente poucos casos especiais obscuros.

Em Java, por exemplo, existem tipos primitivos (int, bool, double, char) que não são objetos adequados. É por isso que o Java tem que introduzir Integer, Boolean, Double e Character como tipos de primeira classe. Isso pode ser difícil de ensinar para iniciantes - não é óbvio por que tanto um tipo primitivo quanto uma classe precisam existir lado a lado.

Isso também significa que a classe de um objeto é - ela mesma - um objeto. Isso é diferente do C ++, onde as classes nem sempre têm uma existência distinta no tempo de execução.

O tipo de 2é o type 'int'objeto, que possui métodos, atributos e um tipo.

>>> type(2)
<class 'int'>

O tipo de um tipo interno como inté o type 'type'objeto. Isso também tem métodos e atributos.

>>> type(type(2))
<class 'type'>
S.Lott
fonte
1
Isso vale para o Python moderno. No Python antigo (versão 1 - era antes do meu tempo), você não podia herdar int. Assim, as classes "antiga" versus "nova moda" (e em 3, não há mais classes antigas).
Keith Pinson
17

"Primeira classe" significa que você pode operar com eles da maneira usual. Na maioria das vezes, isso significa que você pode passar esses cidadãos de primeira classe como argumentos para funções ou retorná-los de funções.

Isso é auto-evidente para objetos, mas nem sempre é tão evidente para funções ou até classes:

void f(int n) { return n * 2; }

void g(Action<int> a, int n) { return a(n); }

// Now call g and pass f:

g(f, 10); // = 20

Este é um exemplo em C #, onde funções realmente não são objetos de primeira classe. O código acima, portanto, usa uma pequena solução alternativa (a saber, um representante genérico chamado Action<>) para passar uma função como argumento. Outras linguagens, como Ruby, permitem tratar classes e blocos de código pares como variáveis ​​normais (ou, no caso de Ruby, constantes).

Konrad Rudolph
fonte
17

No slide Estrutura e Interpretação de Programas de Computador , palestra 2A (1986), que por sua vez cita Christopher Stracey :

Os direitos e privilégios dos cidadãos de primeira classe:

  • Para ser nomeado por variáveis.
  • Para ser passado como argumentos para procedimentos.
  • A ser retornado como valores de procedimentos.
  • Para ser incorporado nas estruturas de dados
Federico A. Ramponi
fonte
1

Na IMO, essa é uma daquelas metáforas usadas para descrever as coisas em uma linguagem natural. O termo é essencialmente usado no contexto da descrição de funções como objetos de primeira classe.

Se você considerar uma linguagem orientada a objetos, podemos fornecer vários recursos aos objetos, por exemplo: herança, definição de classe, capacidade de passar para outras seções do código (argumentos do método), capacidade de armazenar em uma estrutura de dados etc. Mesmo com uma entidade que normalmente não é considerada um objeto, como funções no caso de script java, essas entidades são consideradas objetos de primeira classe.

Primeira classe essencialmente aqui significa, não tratada como segunda classe (com comportamento degradado). Essencialmente, a zombaria é perfeita ou indistinguível.

questzen
fonte