Faz sentido um dia ter isso em Java?

  1. Suporte a RegEx direto na linguagem como perl.
if (s =~ /^aqui$/) {
    System.out.println("MATCH");
}
  1. Suporte a retorno composto, tb como perl.
(int x, int y) = getPoint();

o primeiro acho melhor como ja é hoje em java :smiley:

if("aqui$".matches(s)){ }

retorno composto eu não acho muito legal não, mas acho que isto é meio que questão de gosto só :smiley:

Regex direto na linguagem não. PELO AMOR DE DEUS, não! Só vai aumentar a quantidade de código write-only, assim como Perl. :smiley: É uma complicação que a linguagem não precisa.

Retorno composto eu não vejo muita utilidade. Adicionar uma feature na linguagem pra economizar 2 linhas de código? (Ou tem alguma vantagem nisso além disso que eu não tou vendo?)

Suporte a tuplas e tipos primitivos compostos seria bem legal.

tipos primitivos compostos seria legal, mas não acho assim necessário :smiley:

mas o que são tuplas?

[quote=urubatan]tipos primitivos compostos seria legal, mas não acho assim necessário :smiley:

mas o que são tuplas?[/quote]

http://en.wikipedia.org/wiki/Tuple :wink:

[quote=Wikipedia]Using this definition, (1,2,2) would be

(1,(2,(2,()))) = (1,(2, {{2}, {2, ∅}} )) = (1, {{2}, {2, {{2}, {2, ∅}}}} ) = {{1}, {1, {{2}, {2, {{2}, {2, ∅}}}}}} [/quote]

Medo :shock:

É quase a mesma coisa que o “retorno composto” :wink:

Mas não é nada que uma classe Tuple (de preferência definida em java.util ou java.lang, para não ter uma multidão de implementações independentes) não resolva.
No C++ (Standard Template Library) existe o template pair<> que é usado a torto e a direito. Esse pair<> é aproximadamente equivalente a:

class Pair&lt;T, U&gt; {
    public T first; 
    public U second;
    public Pair(T _t, U _u) { first = _t; second = _u; }
    public Pair(Pair p) { first = p.first; second = p.second; }
    public static Pair&lt;T,U&gt; make_pair (T t, U u) { return new Pair(t, u); }
}

Para ser útil um Tuple deve implementar Comparable, Serializable ou algo parecido.

Exemplo:

class Pair< T extends Comparable< T >, U extends Comparable< U > > implements Comparable< Pair< T,U > > {
    public T x;
    public U y;
    public Pair (T x, U y) { this.x = x; this.y = y; }
    public int compareTo (Pair< T,U > p) {
    	int comp = x.compareTo (p.x);
    	if (comp == 0)
    	    return y.compareTo (p.y);
    	else
    	    return comp;
    }
    public String toString() { return "{" + x + "," + y + "}"; }
    public int hashCode() {
    	return x.hashCode() * 37 + y.hashCode();
    }
    public boolean equals(Pair2 p) {
    	return x.equals(p.x) && y.equals(p.y);
    }
}

acho q so meio burro, mas pq nao usar um Object[] como retorno?? com autoboxing e unboxing, dah ateh p/ usar tipos primitivos… as tuplas tem alguma vantagem q nao estou conseguindo enxergar?

Tem que criar um array só para retornar. Isso é ineficiente.

Agora entendi direito o que está sendo pedido (suporte a tuplas).

É que o valor de retorno de um método Java é sempre um valor de 32 ou 64 bits (1 ou 2 palavras na pilha de execução), sem criação de objetos.

Se houvesse retornos múltiplos, seria possível retornar mais dados na pilha em vez de apenas 1 ou 2 palavras. Isso não envolveria criação de objetos, como é o caso de criar um array, ou pior, um objeto da classe Pair (tal como mostrado).

Modificações necessárias:

  • Obviamente tem-se de alterar o compilador (alteração na linguagem)
  • Alteração do verificador de classes da JVM (para checar se algum fluxo de execução no seu método pode causar um stack underflow, por exemplo)
  • Não sei se seria preciso algum bytecode adicional
  • Alteração no formato do .class para suportar um atributo adicional (dos retornos múltiplos)

Acho que é coisa demais para eles quererem implementar para um benefício pequeno - se bem que muitos acham que generics também são um benefício pequeno :wink: .

Se não me engano isso era um RFE que foi avaliado, muito votado e depois rejeitado.

Seria legal, nem que fosse pra fazer Java parecer mais com Python, mas tb eh facil de ver o estrago que isso faz quando eh abusado. Pense num metodo do do tipo “public (int, int, int, String) doStuff() throws Exception” da vida… torna a vida mais dificil se o codigo nao estiver documentado pra te fazer entender que diacho ta dentro da tupla.

De qualquer forma, thingol, nao era so usar um retorno Object[] escondidinho, mais ou menos o que se faz com varargs hoje em dia, so que pro retorno ao inves dos parametros?

Pois é, poderia ser um array de objetos escondido. Por exemplo:

public |Integer, String| retornaPar () {
    return {4, "Qualquer coisa"};
}
public void usaPar() {
    int x;
    String y;
    |x, y| = retornaPar();
}

seria compilado para:

public Object[] retornaPar () {
    return new Object[] {4, "Qualquer coisa"};
}
public void usaPar() {
    int x;
    String y;
    Object[] ret = retornaPar();
    x = (Integer)ret[0]; // note que o typecast já é inferido pelo retorno |Integer, String| do programa original
    y = (String)ret[1];
}

Aí não seria necessário alterar o verificador de classes ou o compilador JIT.
Mas, como ocorre com generics e varargs, não há melhoria no desempenho.

Qual a diferença da implementação como Perl:

(int x, int y) = getPoint();

com o q foi apresentado pelo thingol?

[quote=thingol] public |Integer, String| retornaPar () { return {4, "Qualquer coisa"}; } public void usaPar() { int x; String y; |x, y| = retornaPar(); }
[/quote]

Ué, se retornos multiplos já existem com objetos escondidos então pra q refazer de outra forma? O fato de compilar para Objects[] é ruim?

Bom, ja da para ter isso tudo hoje mesmo:

http://jse.sourceforge.net/

Rafael

Legal, vamos ver se dá para implementar isso com JSE.