#1431 closed enhancement (fixed)
Reference Assignment Operator
Reported by: | Pedro Gea | Owned by: | Víctor de Buen Remiro |
---|---|---|---|
Priority: | highest | Milestone: | Mantainance |
Component: | Kernel | Version: | |
Severity: | critical | Keywords: | |
Cc: |
Description
Se solicita la implementación del operador de asignación pore referencia.
La motivación a este operador puede verse en el tique #1426, se sugirió incluso un símbolo =&
(véanse los comentarios: 1426#comment:2 y 1426#comment:5).
La mejor alternativa que encuentro hoy para trabajar con referencias es usar la asignación por referencia natural de los conjuntos y por estética apoyarse en una estructura:
Struct @R { Anything D };
y escribir código del tipo:
Set data. = @R(Get(...)); // siendo Get un método que devuelve un dato ya existente // por ejemplo uno cacheado ... = ... data.->D ...;
cuando sea conveniente, en lugar de:
Matrix data = Get(...); // pues aquí se vuelve a crear (repitiéndose) la matriz ... = ... data ...;
Change History (12)
comment:1 Changed 13 years ago by
comment:2 Changed 13 years ago by
Una opción de abreviatura más intuitiva sería crear un nuevo operador monario $
con el mismo efecto que el *
en C pero sin causar tanta confusión pues no se usa para ninguna otra cosa, aunque sí como parte de operadores como $*
y $/
, y el $
sí que recuerda el concepto de valor de algo
@Matrix M = @Matrix(...); Matrix d = $M + 2;
comment:6 Changed 13 years ago by
comment:7 Changed 13 years ago by
comment:9 Changed 13 years ago by
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:10 Changed 13 years ago by
comment:11 Changed 13 years ago by
Hola, tengo una duda: ¿cómo debe usarse este nuevo operador?
Me intentaré explicar. Si quiero hacer una asignación por referencia, entiendo que lo que persigo es lo siguiente:
1.- Definir una variable 'a'.
2.- Definir una variable 'b' que se identifique con 'a' antes de reasginar el valor de 'a'.
3.- Que al cambiar el valor de 'a', cambie el de 'b'.
No soy capaz de conseguir esto tras leer este ticket y el #1426.
Lo intento con el siguiente código:
Matrix a = Constant(1000,10,1); @Matrix M1 = @Matrix(a); Matrix b1 = $M1; Matrix a := Constant(500,10,1); Matrix b2 = $M1; Matrix b3 = a;
Yo esperaría que 'b1' tuviera 500 filas ('b2' y 'b3' por supuesto también). Sin embargo, sigue teniendo el valor original de 'a'. Si sólo puedo cambiar el valor 'b2' definiéndolo después de haber reasignado el valor de 'a', ¿para qué me sirve todo el artilugio de '$M1'? Para eso, no es más sencilla la definición de b3?
No sé, me he debido perder en algún punto, os agradecería que me dijerais dónde.
Un saludo.
comment:12 Changed 13 years ago by
La referencia es $M1
, el objeto b1
es una copia de la referencia que es lo mismo que copiar el original pues así se comporta el tipo Matrix
. Eso no ha cambiado ni se puede cambiar pues sería incompatible hacia atrás.
Supongo que el lío viene de que hay tipos en los que el operador de definición =
funciona como copia y otros tipos en los que funciona como copia. Esta lamentable situación ya he explicado cómo ha surgido y no es soluble por el mismo problema de compatibilidad hacia atrás.
El objetivo del $
y las estructuras @<type>
es precisamente permitir la creación explícita de referencias sea cual sea el tipo de datos y sin perder el control sintáctico sobre los tipos de datos.
La idea es usar expresiones tipo $M1
en las operaciones que queramos que tengan efectos secundarios en el objeto original y usar copias como b1
en las que no queramos modificar el original.
La referencia puede hacerse a un objeto, a un elemento de un conjunto, a un miembro de un NameBlock o, en general a cualquier función que devuelva una referencia a un objeto existente.
A mí no me parece nada mal esa solución, aunque se puede mejorar haciendo una estructura de referencia específica para cada gramática, para no perder el control de tipos y no abusar de
Anything
, lo cual resta eficiencia, robustez y legibilidad al lenguaje. Su uso es algo habría que restringir a los casos en los que no es posible dilucidar el tipo de datos en tiempo de programación.Dado un objeto previamente definido como por ejemplo
sería posible definir una referencia mediante tres formas alternativas y equivalentes
y luego habría dos formas alternativas de acceder al valor referenciado
Estas estructuras se pueden incorporar fácilmente a la
StdLib
y su uso es muy sencillo. Quizás se podría estudiar un operador monario del estilo de C que permitiera abreviar aún más la escrituraaunque esto podría despistar al usuario típico de TOL que no suele estar familiarizado con esta sintaxis.
Incluso se podría intervenir estas estructuras en el interfaz de TOLBase para representarlas directamente como su contenido en lugar de como un conjunto y evitar así acciones de ratón al usuario a la hora de explorarlos.