﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	severity	resolution	keywords	cc
1180	Avoiding function overloading warnings	Pedro Gea	Víctor de Buen Remiro	"Bastante a menudo se encuentran advertencias (e incluso errores) si al utilizar una función no se le antepone adecuadamente el tipo de su salida.

Los casos pueden dividirse en dos situaciones, cuando la sobrecarga de la función se debe a la implementación del mismo concepto para distintos tipos, y cuando se trata de distintos conceptos.

El primer tipo de sobrecarga puede dividirse en tres tipos:
 (a) Distinto tipo de salida y distinto tipo de argumento.
 Un ejemplo de este tipo es la función {{{Cos}}} que devuelve un objeto del mismo tipo que el argumento.

 (b) Distinto tipo de salida, pero mismo tipo de argumento.
 Un ejemplo de este tipo es la función {{{SetRow}}} que devuelve un objeto Matrix o VMatrix, pero siempre recibe un conjunto de reales.

 (c) Mismo tipo de salida, pero distinto tipo de argumento. 
 Esta sobrecarga no es factible, ya que no se admiten dos funciones con el mismo nombre y el mismo tipo de salida. Véanse {{{Rows}}} y {{{VRows}}}. Quizá lo más parecido en este sentido son las funciones con argumentos de tipo Anything (como {{{Compare}}}) o con un tipo mixto (como el segundo argumento del método {{{Matrix Eq}}}).

La cuestión que se pretende tratar en el tique es la primera (a) y en parte también el caso de funciones homónimas que representan conceptos distintos.

Veamos algunos casos de la aparición de dicha advertencia:

{{{
#!java
// Produce la advertencia pero acierta en la elección:
Real If(Sub(""Texto"",1,1)==""T"", 1, 0);

// Alternativa:
Real If(Text Sub(""Texto"",1,1)==""T"", 1, 0);
// Esto tiene el aspecto de que el primer argumento es de 
// tipo Text aunque es Real. También se puede indicar así:
Real If(Real Text Sub(""Texto"",1,1)==""T"", 1, 0);
Real If(Real (Text Sub(""Texto"",1,1)==""T""), 1, 0);
}}}


{{{
#!java
Anything Cos2(Anything x) { Cos(x)**2 };
Real Cos2(3);
Serie Cos2(SubSer(Trend(y2011,C),y2011, y2012));
// La llamada produce una advertencia y en el segundo caso un error

// Alternativa basda en el tipo del argumento:
Anything Cos2b(Anything x) { 
  Code cos = FindCode(Grammar(x), ""Cos"");
  cos(x)**2 
};
Real Cos2b(3);
Serie Cos2b(SubSer(Trend(y2011,C),y2011, y2012));
}}}

Nótese que los operadores no sufren dicha advertencia:
{{{
#!java
Anything Pow2(Anything x) { x**2 };
Real Pow2(3);
Serie Pow2(SubSer(Trend(y2011,C),y2011, y2012));
}}}

La propuesta es crear para este grupo de funciones compiladas del tipo (a) una nueva función con salida {{{Anything}}} que sea llamada en caso de no citarse explícitamente el tipo de salida y que escoja adecuadamente la versión de la función de acuerdo al tipo del argumento. 
Se entiende que esta versión no tipada puede ser algo más lenta que su versión tipada, pero no le veo otro inconveniente. En caso de tipar la salida, se utilizará la versión adecuada de manera directa.

Las funciones de este tipo (a) son:
 * And, Or, Not
 * Eq, NE
 * GT, GE LT, LE: podrían tener una versión para Date
 * Max, Min
 * Abs, Sign
 * Round, Floor
 * IsUnknown, IsFinite
 * IsPosInf, IsNegInf: podrían tener una versión para VMatrix
 * Sqrt, SqRt: Sqrt no tiene versiones en Real y Complex y SqRt no tiene para VMatrix.
 * Exp, Log
 * Log10, LogBase: Log10 no tiene versión en Complex y LogBase no tiene en Serie, Matrix y VMatrix.
 * [|A][Sin|Cos|Tan][|H]: las trigonométricas e hiperbólicas directas e inversas.

También hay otras funciones como:
 * Sum, Prod, Concat: de argumento múltiple parecidas a operadores y normalmente sustituidas por éstos ""+"", ""*"", ""<<"" o sus versiones con funciones de conjunto: ""SetSum"", ""SetProd"", o ""SetConcat"" (ésta sólo funciona con conjuntos).
 * Concat[Rows|Columns], Sub[Row|Col|Diag], RPow (RSum y RProd no devuelven VMatrix), Tra y otras funciones para el manejo de matrices virtuales o no.
 * Otras funciones donde el significado, el número de argumentos o incluso el orden de los mismos varía, como: Gaussian, Rand, Succ, DifEq, Sub, Quantile, Reverse, Replace, Expand, Day, Range, entre otros.

Destacaría 
 * la función Quantile, cuya versión sobre matrices debería llamarse MatQuantile y probablemente recibir la probabilidad como primer argumento.
 * la función Succ que confunde el orden de sus argumentos:
   {{{TimeSet Succ(TimeSet, Real, TimeSet)}}} pero {{{Date Succ(Date, TimeSet, Real)}}}. Aunque entiendo que tiene difícil arreglo.
 * la función Day, en su variante con salida TimeSet optaría por {{{TimeSet TheDay(Date date)}}} que evitaría confusión y facilitaría la implementación de otras como {{{TheMonth(), TheYear(),...}}} en caso de ser necesario, o quizá por algun nombre del tipo {{{YMD(year, month, date)}}} en analogía a la llamada {{{Y(year)*M(month)*D(day)}}}.

Respecto a las funciones para el manejo de textos, propongo introducir las variantes con el prefijo Text, con el fin de evitar, la advertencia y localizar fácilmente todas las funciones para el manejo de textos:
 * Sub, Replace, Reverse -> TextSub, TextReplace, TextReverse
 * TextLength, TextFind, TextMatch, TextOccurrences, TextBeginWith, TextEndAt,...








"	enhancement	closed	normal	Mantainance	Kernel	head	normal	remind		
