O que essa declaração sobre C # e Java sendo metade de uma linguagem significa? [fechadas]

32

No artigo: Por que o POCO , existe esta frase:

Maciej Sobczak coloca bem: "Eu simplesmente não gosto quando alguém me dá metade da língua e me diz que é para minha própria proteção".

Eu não entendo o que ele quer dizer, mesmo que o C # seja de propriedade da Microsoft e Java seja de propriedade da Oracle , isso não significa que eles possuem metade da linguagem, não é? Não encontrei nenhuma evidência para provar essa frase, e estou realmente curioso sobre isso. E ainda mais curioso sobre a parte 'para minha própria proteção'.

123iamking
fonte
12
Eu interpretei isso como uma crítica contra deixar o programador fazer coisas como alocar livremente e liberar memória e esse tipo de "proteção", mas não tenho certeza se esse era o ponto que ele estava tentando fazer.
Kayaman
15
Não tenho certeza exatamente, porque o artigo de que ele está citando parece estar morto, mas parece que ele está dizendo que Java e C # estão faltando vários recursos mais 'perigosos' ou controversos do C ++, como herança múltipla ou metaprogramação de modelos.
GoatInTheMachine
3
O contexto da citação está ausente (o link é 404), então a única coisa que você encontrará aqui são as pessoas adivinhando o que ele provavelmente quis dizer, ou (mais provavelmente) as pessoas que estão apenas apresentando sua própria opinião. Se você realmente deseja conhecer o contexto, ou seja, o que está na página perdida, a melhor aposta é provavelmente escrever o autor diretamente, ou talvez tentar encontrar a página perdida através da máquina de wayback ou similar.
precisa saber é o seguinte
2
A declaração está perdendo o ponto, mesmo que você possa lidar com isso, nem sempre deseja expor todos os aspectos possíveis do desenvolvimento de software em um idioma. Claro que você pode não ter problemas ao ler o código de gerenciamento de memória, mas outros desenvolvedores podem não estar muito animados para manter esse código. É semelhante ao conceito de encapsulamento. Além disso, o C # permite acessar várias coisas, diretivas do compilador, atributos especiais e reflexão, embora não se deva usar essas coisas.
Mark Rogers
32
Para seu próprio bem, não preste atenção nas pessoas que pensam que uma linguagem deve ter todos os recursos do C ++ para ser considerada "real" e "completa". Não preste atenção nas pessoas que pensam que segurança de tipo, segurança de memória e comportamento bem definido são "rodas de treinamento". A correção está se tornando o aspecto mais importante do software na maioria dos setores e as pessoas que se orgulham de não se importarem com ele logo se tornarão irrelevantes.
Theodoros Chatzigiannakis

Respostas:

162

Sobczak não está falando sobre propriedade corporativa. A "meia" linguagem que ele está perdendo é tudo o que você não pode fazer em muitas línguas modernas, mesmo sendo um especialista em informática bem educado e que saiba que elas podem ser possíveis: herdar de quantas classes você quiser. Atribua qualquer objeto a qualquer outro sem restrições de tipo. Controlar a alocação e liberar recursos manualmente, em vez de confiar no compilador e no tempo de execução para fazer isso por ele.

O fato é que todas essas restrições foram colocadas em linguagens de programação por um motivo. Nós que têm línguas que permitiu tudo isso. Com o tempo, descobrimos que o programador médio está melhor com uma certa quantidade de restrições e manipulação de mãos, porque o potencial de cometer erros muito ruins é grande demais para valer o poder e a expressividade adicionais.

(Obviamente, isso às vezes irrita os programadores que realmente não precisam de tanta ajuda. Suas queixas são às vezes legítimas. Mas as pessoas são notoriamente ruins em avaliar suas próprias habilidades, e muitos que pensam que não precisam das salvaguardas precisam, Nem sempre é fácil distinguir intelectos superiores reais que se sentem impedidos por restrições em linguagens de alto nível dos codificadores comuns que pensam que a reclamação os fará parecer superiores ou que não sabem melhor.)

Kilian Foth
fonte
67
Este é o meu Goto resposta.
Neil
71
Também acrescentaria que não existem intelectos superiores que não precisem das restrições. É sempre seguro supor que todo mundo erre mais cedo ou mais tarde. E geralmente quanto maior o intelecto, maior o erro.
Neil
29
Há um pouco mais em Java e C # do que simplesmente impedir que as pessoas se atirem no pé. O gerenciamento de memória exigiu uma quantidade significativa de tempo e esforço do desenvolvedor antes da coleta de lixo, por exemplo, e é difícil executar o gerenciamento manual de memória corretamente. A coleta de lixo melhora a produtividade do programador.
Robert Harvey
12
@RobertHarvey Eu concordo 100%. Sendo um programador de C ++ há muito tempo, eu era cético em relação ao gerenciamento automático de memória ao mudar para C #. Depois que passei disso, foi incrivelmente libertador não ter que me preocupar com isso 99% do tempo. Isso liberou minha capacidade de pensar em outras questões.
17 de 26
8
"Atribua qualquer objeto a qualquer outro sem restrições de tipo." ... Então dynamic,?
Arturo Torres Sánchez
34

Isso é explicado muito bem na fonte original da citação :

Decidi aprender mais sobre C ++ e tornei-me um apaixonado fiel - isso inclui meu interesse na maneira como essa linguagem provavelmente evoluirá. Além disso, notei que as técnicas mais avançadas e avançadas são necessárias para desenvolver bibliotecas úteis , não as aplicações reais. Tendo isso em mente, tentei escrever algumas das minhas próprias bibliotecas para diferentes propósitos (veja minha página de download) e também tento olhar por cima dos ombros dos desenvolvedores do C ++ Boost (veja minha página de links) para saber o que esses técnicas de ponta são. Gastar tempo no desenvolvimento de bibliotecas que deveriam ser genéricas e úteis ao mesmo tempo é realmente exigente. É por isso que os programadores nunca param de aprender.

[...]

Continuo brincando com C ++ e as técnicas para escrever software robusto. Para ganhar uma perspectiva mais ampla na área de software confiável, decidi investir algum tempo na aprendizagem de Ada (e coisas relacionadas), que é uma linguagem que parece ser completamente abandonada pelos negócios, mesmo sendo Ada que foi realmente projetado para ser complexo e confiável. sistemas. Eu tenho que admitir que aprender Ada foi realmente benéfico para mim, no sentido em que me permitiu dar uma nova olhada em minhas abordagens de trabalho e desenvolvimento. Mais importante, algumas das idéias do mundo Ada podem ser aplicadas mais ou menos diretamente ao C ++, com bons resultados na área de robustez e correção.

[...]

OK, eu esqueci. Jurei um dia não aprender Java. Mas eu fiz. Bem, na medida em que me permite ler e escrever código de trabalho. Eu li 'Thinking in Java' (disponível on-line, gratuito) e 'Core Java' (não online, não gratuito), também fui indiretamente envolvido em algum desenvolvimento Java e ... Bem, eu não compro isto. Só não gosto quando alguém me dá metade do idioma e me diz que é para minha própria proteção. É como um martelo de papel, leve, para que ninguém se machuque ao acertar o dedo ... O mesmo se aplica ao C #. Escolho o marreta de aço, para ter certeza de que, quando quero jogar machão, ele aguenta.
A questão é: por que tantas pessoas o usam (Java, C # etc.)? Hmmm ... Talvez porque seja muito bom em alguns lugares. Mas há situações em que o idioma e a biblioteca mostram que eles foram projetados antes para applets (inicialmente) do que para se tornarem utilitários de fazer tudo. Ele promete demais e dá muito pouco para a tecnologia abrangente. Ou como uma solução que poderia arar sobre qualquer concorrência ..

Eu gosto de C ++ quando é necessária potência máxima e perspectiva mais ampla. Em lugares onde a expressividade do C ++ não é obrigatória, linguagens como Tcl ou Python parecem se encaixar. Não apenas eles são abertos no que diz respeito à sua evolução, mas é possível estendê-los e incorporá-los, dependendo de necessidades específicas. Eu vejo muitas possibilidades sonhando com essas tecnologias. Também tendem a abandonar o C como uma linguagem para programação regular - essa parece ser uma escolha razoável apenas como destino para a geração de código, caso contrário, é muito propenso a erros. Hoje, Ada é minha provável segunda opção para projetos mais sérios, desde que eu tenha livre escolha (o que, infelizmente, não é o caso na maioria das vezes).

Então, em outras palavras, o autor dessa citação gosta de C ++, e ele não gosta de Java, e sente que Java está perdendo metade do C ++. E isso é tudo o que há nessa citação.

Jörg W Mittag
fonte
18
Ironicamente, ele não gosta de C exatamente pelo mesmo motivo que gosta de C ++, é muito aberto, permitindo muita energia e muitos erros.
precisa saber é o seguinte
8
Ele considera C ++ para ser mais expressiva do que Python
benxyzzy
12
@ GreySage Isso chamou minha atenção também ... C é muito propenso a erros, mas C # não fornece energia suficiente? C está tão longe do C ++? C # não tem cantos "inseguros" que lhe dão mais controle? Interessante mistura de Thats opiniões com certeza ...
WernerCD
10
O @WernerCD não pode realmente dizer sobre C # inseguro, mas C e C ++ praticamente não têm nada em comum, exceto que você pode obter um trecho básico do C90 em um trecho C ++ válido, no qual o compilador não engasga.
Quentin
23

O artigo vinculado ao blog que você postou foi removido, por isso é difícil ter certeza, mas, como diz Kilian, é provável que quando ele diz "metade da linguagem", ele quer dizer que C # e Java parecem C ++, mas com muito recursos e construções removidos para torná-los mais fáceis de usar ou mais seguros.

Em 2006, quando isso foi escrito, quando o C # era relativamente jovem e o Java era, de muitas maneiras, imaturo, e quando o poder versus a segurança parecia uma troca em que você só podia escolher um, essa não era uma posição totalmente irracional a ser tomada. .

Hoje em dia essa posição não é razoável. Pensando apenas nas linguagens mainstream, o C # e o Java amadureceram enormemente, emprestando recursos de outras linguagens (particularmente funcionais) para promover a escrita de código seguro. Também temos idiomas como Rust e Swift que são criados desde o início para fazer isso.

Se alguém desprezar um idioma porque ele segura sua mão ou disser que um idioma difícil de usar é, de alguma forma, uma coisa boa, eu aceitaria qualquer coisa que eles dissessem com um grão de sal. Você só precisa olhar para o número embaraçoso de bugs encontrados no código de que dependemos todos os dias, escritos pelas mentes mais brilhantes do setor, que teriam sido evitados trivialmente usando linguagens 'seguras', para ver o porquê.

GoatInTheMachine
fonte
6
Concordo com a sua posição no último parágrafo. C ++ deve ser chamado de "Fonte de façanhas".
Caleb Mauer
3
Também para complementar seu segundo parágrafo, Java e C # sintetizaram C e C ++ fortemente por várias razões, incluindo atrair desenvolvedores de C / C ++ existentes com a promessa de uma curva de aprendizado mais baixa. À medida que amadureceram, adicionaram seus próprios recursos e seu próprio sabor, mas nos primeiros dias era mais fácil vê-los como "C ++ mas menos poderosos", pois estavam mais diretamente posicionados como uma alternativa ao C ++.
Harrison Paine
12

Olhando para os arquivos , parece que essa citação era de 2003 (apesar do artigo citá-lo de 2006). Naquela época, o C # estava na versão 1. x , e faltava muitos de seus recursos modernos :

Novas características

C # 2.0

  • Genéricos
  • Tipos parciais
  • Métodos anônimos
  • Iteradores
  • Tipos anuláveis
  • Acessibilidade separada do getter / setter
  • Conversões de grupos de métodos (delegados)
  • Co-variação e contra-variação para delegados
  • Classes estáticas
  • Delegar inferência

C # 3.0

  • Variáveis ​​locais implicitamente digitadas
  • Inicializadores de objetos e coleções
  • Propriedades implementadas automaticamente
  • Tipos anônimos
  • Métodos de extensão
  • Expressões de consulta
  • Expressão lambda
  • Árvores de expressão
  • Métodos parciais

C # 4.0

  • Ligação dinâmica
  • Argumentos nomeados e opcionais
  • Co- e contravariância genérica
  • Tipos de interoperabilidade incorporados ("NoPIA")

C # 5.0

  • Métodos assíncronos
  • Atributos de informações do chamador

C # 6.0

  • Compilador como serviço (Roslyn)
  • Importação de membros do tipo estático no namespace
  • Filtros de exceção
  • Aguarde na captura / finalmente bloqueia
  • Inicializadores de propriedades automáticas
  • Valores padrão para propriedades somente getter
  • Membros com expressão corporal
  • Propagador nulo (operador nulo-condicional, verificação nula sucinta)
  • Interpolação de string
  • nome do operador
  • Inicializador de dicionário

C # 7.0

  • Variáveis ​​de saída
  • Correspondência de padrões
  • Tuplas
  • Desconstrução
  • Funções locais
  • Separadores de dígitos
  • Literais binários
  • Devoluções e locais de referência
  • Tipos de retorno assíncrono generalizado
  • Construtores e finalizadores corporais de expressão
  • Getters e setters corporais de expressão

C # 7.1

  • Assíncrono principal
  • Expressões literais padrão
  • Nomes de elemento de tupla inferidos

- "C Sharp" , Wikipedia (referências e links removidos)

Provavelmente é mais compreensível que o C # parecesse meia linguagem nesse contexto, pois faltava muito do que é hoje o C #. É estranho pensar que ele nem tinha staticaulas!

Também faltava mais coisas, já que o C # estava vinculado ao .NET. Por exemplo, o WPF não existia naquela época; era tudo WinForms.

Nat
fonte
classes estáticas podem ser uma má escolha de um recurso ausente, pois o Java ainda não as possui (o tipo C #). A menos que isso seja um golpe no Java?
user253751
1
@immibis Não é uma facada intencional em Java, mas, caramba, sério? staticas classes parecem um recurso tão primitivo; Eu meio que imaginei que eles eram anteriores às aulas.
Nat
2
Parece como dizer que os jatos de motor a pistão eram anteriores aos jatos de motor a jato; uma "classe não instanciada" é geralmente chamada de módulo ou espaço para nome , exceto nos idiomas em que todo o código deve estar dentro de uma classe. (Ou chamando uma bicicleta um automóvel manual ou chamar um telefone fixo um celular estacionário, ou ...)
user253751
@ Nat - Ter aulas estáticas é bom, mas não tê-las muda absolutamente nada. Você pode simplesmente tornar todos os membros da classe estáticos, e tudo o que você perde são alguns tipos de erros do compilador se esquecer que a classe foi criada para permanecer estática.
Jirka Hanika
@JirkaHanika Sim, staticna maioria dos casos não sou um grande fã de aulas. Honestamente, eu o escolhi como um recurso a ser destacado, porque parecia realmente parte simples e primitiva do C #; Não considerei que eles não estavam em Java.
Nat
3

Ele estava reclamando da falta de recursos de linguagem que permitem um controle mais refinado. Isso inclui ferramentas para

  • Aplicação da imutabilidade (como a constpalavra-chave C ++ )
  • Controlando a vida útil e a propriedade do objeto
  • Controlando o uso da memória, estilo de cópia e alocação

Isso me lembra uma das minhas críticas ao Java:

tudo é um ponteiro, mas não existem ponteiros.

Nos objetos C ++, ponteiros e referências são três conceitos distintos com semântica clara. Em Java, você apenas possui o pseudo-objeto-ponteiro. Ao unir essas informações e evitar a verdadeira semântica de ponteiros, o modelo de objetos fica menos claro.

Em um programa C ++ bem definido, o programador pode esperar que as referências sejam válidas e não nulas. Devido ao seu modelo simplificado, o Java não pode fazer as mesmas garantias.

Os sintomas desse modelo menos claro incluem o padrão de objeto nulo e condicionais yoda como 5.equals(potentiallyNullIntegerReference).

Wes Toleman
fonte
5
Isso é muito confuso. Ponteiros (no sentido lógico existem em Java), você simplesmente não pode mexer com eles. O objetivo de simplificar o modelo é permitir mais garantias. A lógica que você pode assumir mais sobre o código em um idioma terá menos restrições ao contrário. Mais restrições -> mais garantias.
21917 JimmyJames
1
@JimmyJames a frase significa que, mesmo que todas as classes java tenham semântica de referência implícita (eca, btw), você não pode ter um ponteiro real. Por exemplo, não há como obter uma "referência" a uma referência. Isso prejudica o idioma em vários lugares, exigindo algumas soluções alternativas insanas (veja Map.mergequando você simplesmente deseja atualizar um valor em um mapa).
Quentin
3
@ JimmyJames: Alguns tipos de garantias úteis não podem ser praticamente oferecidos sem a imposição de certas restrições. Além disso, algumas otimizações úteis podem exigir a imposição de algumas restrições. Algumas linguagens, no entanto, impõem restrições inúteis que não oferecem garantias úteis aos programadores e não devem ser necessárias para a otimização útil. Algumas restrições são simplesmente ruins.
Supercat
3
@JimmyJames: Por outro lado, algumas das restrições mais fundamentais do Java e do C # "de modo seguro" oferecem uma garantia muito útil de que o C ++ não pode: qualquer referência (o que em C ++ seria um ponteiro) sempre observado para identificar um objeto em particular nunca será observado para identificar mais nada .
Supercat
3
Você pode fornecer algumas citações para apoiar sua resposta? Por exemplo, AFAIK, a página não menciona const. Ele faz menção "programação funcional", no entanto, a linguagem que ele usa como exemplo é Scheme, que é não uma linguagem funcional pura (na verdade, os designers de esquema têm o cuidado de evitar o uso da palavra "função" e falar sobre " procedimentos "), então parece que ele está usando a interpretação de" sub-rotinas de primeira classe "do FP e não a" transparência referencial ".
Jörg W Mittag
1

Concordo com a resposta @Kilian, mas adicionarei alguns elementos.

1- Correndo contra uma máquina virtual e não o SO

Como Java e C # estão sendo executados em uma máquina virtual, espera-se logicamente que você não possa fazer exatamente o que deseja quando estiver diretamente no sistema operacional, porque é provável que você corrompa algo na VM. Além disso, com o Java sendo orientado como independente de plataforma, é ainda mais lógico.

2 - Toneladas de aplicativos não exigem que você precise desse tipo de coisa.

Existem muitos aplicativos que realmente não precisam de você pesquisar muitos detalhes, mas se você fizer isso com um idioma que exija que você o faça, você obtém:

  • Mais riscos de ter erros devido a essas coisas desnecessárias.
  • Mais custo de desenvolvimento, gerenciamento de memória e teste, levam tempo e muito dinheiro!

3- O idioma é feito com base em algumas opções de ponderação de custo / uso / riscos, como ... tudo.

Com o C ++, você pode fazer praticamente o que deseja, essa é a escolha das pessoas em C ++. No entanto, quanto mais houver, mais você precisará lidar.

Portanto, coisas como herança múltipla não são abandonadas apenas pelo fato de serem perigosas, porque a implementação delas tem um custo (desenvolvimento, manutenção), tudo isso para um recurso que raramente é usado corretamente e pode geralmente são reescritos de maneira diferente.

Walfrat
fonte
O custo real da herança múltipla reside no fato de que não é possível manter as duas garantias a seguir: (1) Se um membro da classe base Bfor substituído na classe média M, Ba versão desse membro será acessível apenas por M" substituição; (2) dada qualquer referência do tipo T, convertendo-a em qualquer supertipo e retornando para Tproduzirá uma referência equivalente ao original. Ambas as garantias são úteis, e o suporte à herança múltipla exigiria renunciar a pelo menos uma.
Supercat #
-1

Basta colocar todas as restrições em linguagens de alto nível, como C # e Java, para proteger o programador. Eles existem não tanto para proteger o programador de si mesmo, mas para proteger o programador de outros programadores!

Quantas vezes nós, como programadores, encontramos bibliotecas absolutamente terríveis em suas práticas de codificação e design, mas que fomos forçados a usar por um motivo ou outro?

Esses programas geralmente têm as características do antigo método processual de programação, com falta de encapsulamento, muita gravação direta na memória com pouca ou nenhuma captura ou manipulação de erros. Segfaults buscam massa ao tentar usá-los em qualquer projeto de grande escala.

É aí que linguagens como Java e C # são extremamente úteis; não é que eles gostem do fato de não nos deixar fazer todas as coisas legais que outras linguagens fazem, é que gostamos da falta de dores de cabeça que temos de suportar, porque outros programadores abusariam das coisas legais que outras linguagens podem Faz.

As interfaces valem bem qualquer tipo de troca em termos de memória ou velocidade de execução em minha mente. Espero que você possa ver que, em qualquer tipo de aplicativo de missão crítica com tempo limitado, todas essas proteções, tratamento adequado de erros e geralmente ter certeza de que a memória não está sendo manipulada são coisas boas!

Akumaburn
fonte
este não parece oferecer nada substancial sobre pontos feitos e explicado em anteriores 5 respostas
mosquito
1
They exist not so much to protect the programmer from him/herself, but rather to protect the programmer from other programmers!ou é para proteger outros programadores do programador?
Tobia Tesan
@TobiaTesan That too :)
Akumaburn