close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 14 years ago

Closed 14 years ago

#1180 closed enhancement (remind)

Avoiding function overloading warnings

Reported by: Pedro Gea Owned by: Víctor de Buen Remiro
Priority: normal Milestone: Mantainance
Component: Kernel Version: head
Severity: normal Keywords:
Cc:

Description

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:

// 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);
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:

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,...

Change History (2)

comment:1 Changed 14 years ago by Víctor de Buen Remiro

Yo es que no veo tanto problema con esto.
Cuando te sale el warning pones el cast y ya está.
Si algún día tenemos recursos de sobras se puede acometer pero esto es un trabajazo inmenso para poco premio.

comment:2 Changed 14 years ago by Víctor de Buen Remiro

Resolution: remind
Status: newclosed
Note: See TracTickets for help on using tickets.