Concordo sobre o for enhanced…
E não citei ruby quanto a ter ou não sobrecarga.
Meu exemplo foi apenas para citar que esse é mais um dos que um cara acostumado com outra linguagem mais vai olhar um código java e vai dizer “WTF”.
Ao invés de agilidade, traríamos mais complexidade sem agregar em nada.
Qual a diferença na agilidade você consegue enxergar nessas duas representações?
public add(T a){
/*codigo*/
}
public +(T a){
/*codigo*/
}
Eu acho a diferença entre uma chamada de método e o uso de operador bem pequena, se comparada à entre for-enhanced e usar iterator (embora eles pudessem ter criado um “foreach”).
Não consigo ver muita vantagem no uso de sobrecarga de operadores. Talvez se conhecesse melhor, veria.
Eu não. O enhanced for é só uma maneira de não tornar aparente o uso do Iterator, não uma sobrecarga de lógica.
Quem quiser comparar, compile e rode depois com javap -verbose:
[code]import java.util.ArrayList;
import java.util.Iterator;
public class TesteFor {
public static void main(String[] args) {
ArrayList listaTeste = new ArrayList();
listaTeste.add(“String 1”);
listaTeste.add(“String 2”);
listaTeste.add(“String 3”);
System.out.println(“Maneira 1 de fazer o for”);
Iterator it = listaTeste.iterator();
do{
String nome = (String) it.next();
System.out.println(nome);
}while(it.hasNext());
System.out.println("Maneira 2 de fazer o for");
for (String string : listaTeste) {
System.out.println(string);
}
}
}[/code]
Coincidentemente, os dois loops em bytecode são muito parecidos. O mesmo não aconteceria se fosse trabalhado sobrecarga do operadores como no C++.
Continuo convicto que a verborragia é uma convenção muito boa. espalhar métodos parônimos por todo lado pode ser extremamente prejudicial.
[quote=nbluis]Concordo sobre o for enhanced…
E não citei ruby quanto a ter ou não sobrecarga.
Meu exemplo foi apenas para citar que esse é mais um dos que um cara acostumado com outra linguagem mais vai olhar um código java e vai dizer “WTF”.
Ao invés de agilidade, traríamos mais complexidade sem agregar em nada.
Qual a diferença na agilidade você consegue enxergar nessas duas representações?
public add(T a){
/*codigo*/
}
public +(T a){
/*codigo*/
}
StringBuilder b = new StringBuilder();
b.append("A").append("B").append("C").append("D").append("E").append("F")
.append("G").append("E").append("H").append("I").append("J").append("L")
.append("M").append("N");
System.out.println(b.toString());
StringBuilder b = new StringBuilder();
b.append("A").append("B").append("C").append("D").append("E").append("F")
.append("G").append("E").append("H").append("I").append("J").append("L")
.append("M").append("N");
System.out.println(b.toString());
Até![/quote]
Mais ai voce esta escrevendo 8 caracteres a mais para implementar:
b.append(“A”)
e o código fica bem mais dificil de entender.
no outro não, voce só de bater o olho ja sabe o que esta havendo.
Eh claro que também não adianta escrever pouco e depois se ferrar para entender o código, mais no caso com o operador fica até mais claro a intenção do código.
Vais ter que criar outro método para fazer o que o append já faz, além de ter que transformar o “+” em um método que já existe (será que não irá montá-lo como append em bytecode?).
Conheço bons programadores que reclamam do C++ por permitir isso, pois eles odeiam os antigos mantenedores do código que eles estão trabalhando agora.
Mas “+” o mais poderia significar add(), append(), put(), offer(), doSomethingThatIDontKnowWhatItDoes() e tantos outros métodos diferentes que eu acho que a vantagem que ele talvez desse em criação seria sobrepujado pela complicação em manutenção.
Não só delegar para o original, assim se mudar a implementação os dois mudam, no caso de classes basicas eles simplesmente dariam os operadores como uma maneira mais simples de fazer o mesmo trabalho do metodo. Não tiraria a compatibilidade com nada antigo e ainda quando o programador quisesse mudar o metodo append por exemplo ele só mudaria ele, ja que o operador chama este…
public StringBuilder +(Object o){
return append(o);
}
Que complicação haveria em dar manutencao nestes metodos ?
[quote=AndrewAguiar]…
Que complicação haveria em dar manutencao nestes metodos ?
[/quote]
Pense que você tem 200 classes que o “+”, “-”, “/” “>>” fazem coisas diferentes? Como saber qual será o comportamento sendo que “>>” pode simplesmente dar um System.out.println() ou pode fazer uma operação maluca? Isso em não garante legibilidade, garante que você pode se confundir com o tempo.
IMHO:
Faz sentido a implementação do “+” ser kill, concat ou whatever? Se sim, quem está fuçando no código vai saber.
A criação de um novo simbolo realmente é uma coisa estranha (mas que, dependendo de como o seu sistema/ambiente/plataforma oferece acesso/suporte, pode ser legal) , a redefinicão de uma mensagem é uma coisa normal.
Em java, sobreescrever “+” faz 0 de diferença. Eu quero reescrever o new, o class, o …
Sobrecarga de operadores é um artifício muito útil, especialmente para construir Human Interfaces e DSLs internas, mas não é essencial.
O ‘mistério’ que poderia fazer com que olhar o JavaDoc para cada classe e ver o que o + (ou-, ou/,ou []) faz deriva do fato de que você está assumindo que + é um operador quando em uma linguagem decente que tenha sobrecarga de operadores ela é apenas um apelido para um método e assim como todos os métodos você precisa saber o que esperar.
[quote=faq]IMHO:
Faz sentido a implementação do “+” ser kill, concat ou whatever? Se sim, quem está fuçando no código vai saber.
[/quote]
Não necessariamente. O cara pode estar se adaptando ao código e encontrar isso. O nome auto-explicativo dos métodos vai para onde?
[quote=faq]
A criação de um novo simbolo realmente é uma coisa estranha (mas que, dependendo de como o seu sistema/ambiente/plataforma oferece acesso/suporte, pode ser legal) , a redefinicão de uma mensagem é uma coisa normal.
Em java, sobreescrever “+” faz 0 de diferença. Eu quero reescrever o new, o class, o …[/quote]
Faz diferença sim, como já mostrei. E depois ainda queres trazer os define para o Java? :shock:
[quote=maquiavelbona][quote=AndrewAguiar]…
Que complicação haveria em dar manutencao nestes metodos ?
[/quote]
Pense que você tem 200 classes que o “+”, “-”, “/” “>>” fazem coisas diferentes? Como saber qual será o comportamento sendo que “>>” pode simplesmente dar um System.out.println() ou pode fazer uma operação maluca? Isso em não garante legibilidade, garante que você pode se confundir com o tempo.
Até![/quote]
Voce olha no javadoc, qualquer API que voce pegar para usar voce vai ser obrigado a olhar a documentação. se voce ve o seguinte metodo numa api que voce pegou de um terceiro
Messenger msg = new Messenger();
msg.enviar("Olá");
blz voce ( Presume ) pelo nome que este metodo envie a mensagem.
porem voce ainda não sabe que exceções ele lança, não sabe se há uma restrição no seu uso, não sabe no que impacta no Objeto, não sabe se esta depreciado ou não etc.
Simplesmente olhar o nome do método não te diz muita coisa.
Thread thread = new Thread( new Runnable(){
public void run() {
System.out.println("Foi");
};
});
thread.start();
Imagine que voce nunca usou a Thread, voce conseguiria só vendo o nome do metodo start dizer que ele lança um IllegalThreadStateException se voce tentar startar ela denovo ?
O fato do nome do metodo ser verboso ajuda, mais não te livra de ler sua documentação.
Ok. Vamos levar em consideração que quem escreveu o código tem bom senso. Você costuma ver muitos “adds” fazendo - subtrações - ? Eu espero que o “+” faça algo como somar.
Maquiavel sobre criação de novos simbolos:
Define do c? Eu não quero trazer nada pro java. Só acho que criar novos simbolos pode ser legal.
Acho que no fim cada um continua com uma opinião. Uns achando que a linguagem deve ser o que deve ser (sem reescritas) e outros achando que reescrever coisas é legal. Eu fico com o segundo grupo, pois até onde sei/entendo é esse tipo de coisa que permite expressividade e simplicidade.
Eu achei que simplificaste demais a acepção do uso da Sobrecarga de Operadores. O que mais critico nela ( como na tupla também, apesar de ser assunto para outro tópico ) é o péssimo uso e a falta de senso na aplicação da mesma. E o pior que isso não afeta somente as linguagens de programação.
Estava conversando com um doutorando na área de literatura, e ele me dizia que no meio acadêmico estuda-se a penetração e crescimento das sinonímias e paronímias vulgares dentro de línguas consagradas ( português é um exemplo ), e como isso afetava a norma culta, levando tanto ao emprego errôneo de várias palavras, quanto ao desuso e desconhecimento de outras. Na frase “Percebo R$5000,00 todo mês”, quantas pessoas pensariam que o cara estaria falando do seu salário? Mas “Tomaram o cara” todo mundo entende. É a mesma cosia da vulgarização do método add(), pode significar várias coisas e nenhuma ao mesmo tempo.
Outro termo que ele estávamos discutindo é o uso dos verbos reduzidos de infinitivo, que o uso correto e lógico dentro de uma frase, pode torná-la mais compreensível ao nosso cotidiano, mas que quase nunca é empregado corretamente ( não lembra a sobrecarga do “+” ? ).
Como na língua portuguesa, poderíamos ter a disposição vários artifícios como esses, o problema seria fazê-los compreensíveis a todos e que a implementação dos mesmos não ficasse tão vulgar quanto o uso do define do C.
As Línguas de maneira geral, como o Português e Java num menor grau, têm que ser dinâmicas e se adaptarem aos usos e necessidades, se quiserem sobreviver. Quem realmente dita as regras é quem usa, não quem especifica (por isso as reformas da norma culta e o JCP ). As novas regras de qualquer língua têm sua origem no uso vulgar.
Quanto à semântica de um operador sobrecarregado, não consigo ver como isso seria diferente de um nome de método. O programador dá o significado que quiser em ambos os casos.
Na língua portuguesa, a "reforma" vulgar não vem da "lei do menor esforço" e sim da "lei estudar-para-que?". No Java, algumas (eu disse algumas) mudanças seriam bem aceitas, mas outras seriam simplesmente um paleativo para pessoas que sabem que estão usando errado e querem um jeito de não ser tão feio o que estão fazendo ou não saber realmente como fazer e para infelicidade do destino, descobre-se que ele pode refazer os operadores ( ao melhor jeito do define ) e transformá-los em mutantes comedores de código legível. No começo do código, o "<<" vai estar jogando um valor num objeto e no fim vai estar juntando um valor randômico com o número do MAC adress e escrevendo isso num socket.
Não é porque você pode ( e consegue ) escrever código legível com isso, que os estagiários que mantiveram as URAs donde trabalhas vão ter o mesmo esmero.
Durante muitos anos estive convencido de que uma das melhores coisas do Java era não ter sobrecarga de operadores que foi uma das coisas que mais sofri quando aprendi C++ há uns 15 anos atrás.
Mas depois que andei estudando erlang, Scala e até mesmo Ruby, que são linguagen que tem coisas bem mais esquisitas do que isto, penso que Java poderia ter isto sim.
Como disse o CV, não é coisa que todo mundo iria usar a toda hora. Mas nos poucos momentos em que pode ser útil seria muito vantajoso. Um exemplo clássico são as aplicações que precisam de números complexos. Outro momento em que faz falta é quando a gente usa BigDecimal ou quer fazer operações aritméticas com vetores.
Hoje em dia acho que o Java precisa de muitas coisas a mais na linguagem para continuar útil nos próximos anos. Muitas destas coisas talvez devam ser oriundas das linguagens funcionais e podem complicar a VM mas sobrecarga de operadores deve ser coisa simples porque de certa forma já existe nas Strings.