Tenho visto muitas vezes declarações como- “Faça deste recurso um cidadão de primeira classe em fulano de idioma / plataforma”. Por exemplo, é dito sobre enums em C # / .net. Então, quando um recurso é considerado um “cidadão de primeira classe” em uma linguagem / plataforma de programação?
Comentários
- BTW: o termo ” cidadão de primeira classe ” não é recomendado, por exemplo pelo guia de estilo do google para linguagem inclusiva como um termo socialmente carregado: developers.google.com/style/inclusive-documentation
Resposta
Definição
Um objeto é de primeira classe quando:
- pode ser armazenado em variáveis e estruturas de dados
- pode ser passado como um parâmetro para uma sub-rotina
- pode ser retornado como o resultado de uma sub-rotina
- pode ser construído em tempo de execução
- tem identidade intrínseca (independente de qualquer nome)
O termo “objeto” é usado livremente aqui, não necessariamente se referindo a objetos na programação orientada a objetos. Os tipos de dados escalares mais simples, como números inteiros e de ponto flutuante, são quase sempre de primeira classe.
http://en.wikipedia.org/wiki/First_class_object
Comentários
- Então, o que torna enums objeto de segunda classe em .net / C #?
- @Gulshan – você poderia argumentar a falta de identidade intrínseca – enums C # são basicamente apenas um açúcar sintático (ou seja, um ” nome “) para um valor inteiro. Compare com Java, onde os enums são objetos por si próprios.
- @mikera, em .NET enums são valores por si próprios. Java simplesmente não tem valores, apenas objetos, que ‘ é a única diferença.
- @mikera: Embora isso impeça o Java ‘ s enums por terem algumas propriedades interessantes, como ser capaz de representar campos de bits com eles. Embora sua implementação seja provavelmente mais de primeira classe, a maioria de suas APIs ainda tem muitas constantes inteiras (ou strings) e muitos usos delas não podem ser facilmente substituídos por enums.
- Eu não ‘ acham que enums podem ser construídos em tempo de execução em .Net, podem? Achei que fossem sempre constantes.
Resposta
A noção de ” cidadão de primeira classe ” ou ” elemento de primeira classe ” em uma linguagem de programação foi introduzida pelo cientista da computação britânico Christopher Strachey na década de 1960 no contexto do primeiro -class functions. A formulação mais famosa desse princípio está provavelmente em Estrutura e Interpretação de Programas de Computador por Gerald Jay Sussman e Harry Abelson:
- Eles podem ser nomeados por variáveis.
- Eles podem ser passados como argumentos para procedimentos.
- Eles podem ser retornados como resultados de procedimentos.
- Eles podem ser incluídos em estruturas de dados.
Basicamente, isso significa que você pode fazer com isso elemento da linguagem de programação tudo o que você pode fazer com todos os outros elementos na linguagem de programação.
É tudo sobre ” direitos iguais “: você pode fazer tudo acima, digamos, com números inteiros, então por que qualquer outra coisa seria diferente?
A definição acima é um pouco restritiva no sentido de que só realmente fala sobre o aspecto de primeira classe em relação a ser objetos do programa. Uma definição mais geral seria Pode ser que uma coisa seja de primeira classe se você puder fazer tudo com ela, também pode fazer com outras coisas de tipo semelhante.
Por exemplo, os operadores Java e os métodos Java são de tipo semelhante. Você pode definir novos métodos, pode (de certa forma) escolher livremente os nomes de seus próprios métodos, pode substituir métodos, pode sobrecarregar métodos. James Gosling pode fazer tudo isso com operadores também, mas você e eu não podemos. Quero dizer, ao contrário da crença popular, Java oferece suporte à sobrecarga de operador: por exemplo , o operador +
está sobrecarregado para byte
, short
, int
, long
, float
, double
e String
e IIRC em Java 7 também para BigInteger
e BigDecimal
(e provavelmente alguns esqueci), é só que você não tem nenhuma influência sobre ele.Isso claramente torna os operadores de segunda classe de acordo com esta segunda definição. Observe que os métodos ainda não são objetos de primeira classe de acordo com a primeira definição. (Isso torna os operadores de terceira classe?)
Comentários
- Ótima resposta. Então, por exemplo, os documentos do pipenv dizem ” O Windows é um cidadão de primeira classe, em nosso mundo. ” Isso significaria que você pode fazer tudo com
pipenv
no Windows que você também pode fazer no Linux? - Não, eu não ‘ não acho que o uso do termo ” cidadão de primeira classe ” tem algo a ver com a definição formal do termo em Teoria da Linguagem de Programação . Acho que pipenv está apenas usando o termo com seu significado normal em inglês.
- Como em ” tratado com justiça? ” Obrigado por sua ajuda.
Resposta
Normalmente, este refe rs para uma construção que é passável como parâmetro, pode ser definido como um tipo de retorno de uma função ou pode receber um valor. Normalmente você precisa ser capaz de construí-los em tempo de execução. Por exemplo, uma instância de uma classe seria um cidadão de primeira classe em c ++ ou java, mas uma função em C não seria.
Comentários
- O que torna uma classe um cidadão de primeira classe em c ++?
- @bjarkef: Parece que já foi respondido por corresponder à descrição oferecida nas frases anteriores.
- @Jonathan: Sim, desculpe, eu interpretei mal a ” construí-los em tempo de execução “. Sim, você pode construir uma instância de uma classe em tempo de execução (um objeto), mas não a própria classe. Isso é o que me confundiu.
- Passar por parâmetro ainda não é suficiente. Em C / C ++, eu ainda consideraria as funções como cidadãos de segunda classe. Eles podem ser passados como parâmetros, retornados como resultados colocados dentro de outros objetos. Mas eles não podem ser manipulados sem a ajuda de outras construções (como std :: bind é necessário para vincular parâmetros a uma função).
- @Martin Eu nunca disse que funções eram cidadãos de primeira classe em C / C ++ .
Resposta
Eu diria que um elemento é um cidadão de primeira classe se for implementado exclusivamente pela linguagem .
isto é, não requer vários recursos de linguagem ou uma biblioteca padrão para implementar esse recurso.
Exemplo:
Em C / C ++, não considero as funções como o primeiro cidadão da classe (outros podem).
Isso ocorre porque há maneiras de manipular funções que não são suportadas diretamente pela linguagem, mas requerem o uso de outros recursos da linguagem. Parâmetros de vinculação a uma função não são diretamente suportados e você deve construir um functor para implementar este recurso.
Comentários
- Wouldn ‘ t que fazem as funções vinculadas (ou ” encerramentos “) não serem de primeira classe, enquanto as próprias funções são? Como o suporte de 0x ‘ s para fechamentos influencia sua análise?
- @Fred Nurk: Tudo depende do idioma. Em algumas linguagens, os encerramentos são sistemas de primeira classe. Em outros, não. Ainda não estou familiarizado o suficiente com C ++ 0x para fazer um comentário explícito.
- Vamos ‘ s dizer que a linguagem é C ou C ++ (mas não 0x ), como em sua resposta. A ‘ sua definição de ” primeira classe ” criaria funções limitadas (ou ” closures “) não são de primeira classe, enquanto as próprias funções são?
- @Fred Nurk: Se você limitar a única coisa que você pode fazer com uma função é torná-la um encerramento, então com certeza. Mas, para mim, ‘ é como dizer se sua plataforma suporta adição de inteiros apenas importando uma biblioteca. Então, os inteiros são cidadãos de primeira classe, mas a adição de inteiros não é considerada. Em minha opinião, o fechamento é uma operação que pode ser executada em uma função que efetivamente retorna uma nova função (mas depende de como você a define). Mas fechamento e vinculação são apenas duas operações, quantas outras estamos excluindo da discussão (não tenho certeza se foi uma pergunta).
- @Martin: Não devo estar me explicando com clareza. Dado ” um recurso é um cidadão de primeira classe se for implementado apenas pela linguagem “, então as funções em C e C ++ são implementadas apenas pela língua e, portanto, seria de primeira classe. Funções vinculadas (que também podem ser chamadas de ” encerramentos “) são o que você ‘ re falando sobre parâmetros de ligação, etc., mas isso ‘ é um recurso diferente.
Resposta
Para adicionar um exemplo às respostas já fornecidas:
No WCF / C # você atualmente precisa marcar um objeto de classe com um atributo de contrato de serviço para que ele opere como um serviço. Não existe algo como:
public **service** MyService (in relation public **class** MyClass).
Uma classe é um cidadão de primeira classe em c #, onde um serviço não é.
Espero isso ajuda