jueves, 29 de abril de 2010

Problema: las tres puertas

Para copiarle un poco la idea a Andrés de plantear problemas (ver acá, acá y acá), acá va uno que me dejó pensando varios días...

El enunciado es algo así: En un programa de concursos, el jugador tiene que elegir una puerta entre tres. Atrás de una de las puertas hay un premio, las otras dos no tienen nada. Una vez que el jugador elige, el conductor del programa (que ya sabe donde está el premio) abre una de las otras dos puertas.

La pregunta es: ¿conviene quedarse con la puerta elegida al principio o conviene cambiar?

La respuesta en unos días en los comentarios...

martes, 27 de abril de 2010

Código repetido: cálculo del valor en varias monedas

Siguiendo con la inteción de minimizar el código repetido en la base de conocimiento, me encuentro ante un problema que no tengo del todo claro como resolver. Capaz que a alguien se le ocurre alguna solución que no estoy viendo :)

En varios lugares de la KB, se manejan valores de productos en tres monedas, llamémosles &Moneda1, &Moneda2 y &Moneda3. Las monedas 1 y 2 son siempre distintas entre sí. La moneda 3 puede ser igual a la 1, igual a la 2, o no coincidir con ninguna.

Entonces, el código que se repite es el siguiente:
&Valor1 = udp(PAlgunProc, &Moneda1, [otros parámetros])
&Valor2 = udp(PAlgunProc, &Moneda2, [otros parámetros])
if &Moneda3 = &Moneda1
    &Valor3 = &Valor1
else
    if &Moneda3 = &Moneda2
        &Valor3 = &Valor2
    else
        &Valor3 = udp(PAlgunProc, &Moneda3, [otros parámetros])
    endif
endif
El procedimiento que se llama depende del contexto en que se esté. No es siempre el mismo. La propiedad que tiene es que es siempre más costoso que un if, y por lo tanto no quiero llamarlo para la &Moneda3 si coincide con alguna de las otras.

Lo ideal sería poder extraer este código,  y tener un programa que reciba las tres monedas, y un procedimiento que reciba un parámetro de tipo Moneda. El problema es que esto no se puede hacer, porque los programas tienen todos parámetros distintos...

¿A alguien se le ocurre una alternativa a repetir el código de arriba cada vez que se precisa?

Capaz que sería bueno tener una forma mejor para hacer invocaciones dinámicas de objetos...

Se me ocurre poder tener una variable de algún tipo especial, que pudiera asignar con una llamada a un procedimiento. Se podría sustituir la línea
&Valor1 = udp(PAlgunProc, &Moneda1, [otros parámetros])
por
&miProc = createProc(PAlgunProc, @Moneda, [otros parámetros], @Valor)
&Valor1 = udp(&miProc, &Moneda1)
¿Para que serviría esto? Así no parece tener demasiada ventaja, estoy escribiendo lo que podría hacer en una línea en dos...

Pero si vemos como quedaría en el ejemplo anterior, podría pasar la invocación con algunos parámetros instanciados y otros no a una función genérica:
&miProc = createProc(PAlgunProc, @Moneda, [otros parámetros], @Valor)
call(PCalcula3Monedas, &Moneda1, &Moneda2, &Moneda3, &miProc, &Valor1, &Valor2, &Valor3)
La  implementación del procedimiento Cacula3Monedas sería entonces
&Valor1 = udp(&miProc, &Moneda1)
&Valor2 = udp(&
miProc, &Moneda2)
if &Moneda3 = &Moneda1
    &Valor3 = &Valor1
else
    if &Moneda3 = &Moneda2
        &Valor3 = &Valor2
    else
        &Valor3 =
udp(&miProc, &Moneda3)
    endif
endif
Algunas consideraciones:
  1. El createProc sería una forma nueva de "invocar" un objeto, que construiría otro "objeto", con menos parámetros, que podría ser invocado en otro contexto. Además debería aparecer dentro de los objetos referenciados.
  2. Los parámetros que no le voy a pasar en el momento, es decir, lo que voy a diferir para cuando haga la invocación real, debería marcarlos de alguna forma. En el ejemplo, con una @.

viernes, 16 de abril de 2010

La gente de Observa no entiende como funciona internet

Hoy me llegó como todos los días el mail con los titulares de Observa, con una nota que decía:
INTERNET
Blog de viajes es el mejor en lengua castellana
Su título es “La vuelta al mundo de Asun y Ricardo” y narra las peripecias de una pareja española por distintos puntos del planeta
El mejor blog en lengua castellana, puede ser interesante... Entré a la nota para ver el blog, ¡pero no tiene link al blog!

El otro día leía una nota de Jorge Oyhenard, que decía que [el] Diario El País de Uruguay no sabe ni prenderla. ¿Será que ninguno de los medios de prensa escrita uruguayos entiende como funciona internet?

Es decir... lo importante de una nota que habla sobre "el mejor blog en lengua castellana", es el blog en sí. Lo demás es anecdótico. ¿No es obvio que deberían haber puesto el link?

Ah, la nota de Observa está acá. Si quieren ver el blog del que habla, búsquenlo en Google.

martes, 13 de abril de 2010

Algoritmos sobre SDTs en GeneXus

Los SDTs en GeneXus (Structured Data Type) tienen cierto grado de felxibilidad, pero creo que como están hoy, no es suficiente.

Nota: lo que sigue es basado es el conocimiento que tengo de los SDTs en GeneXus 9.0. Creo que no se hizo ninguna mejora significativa en este sentido en las versiones posteriores...

Supongamos que tengo un algoritmo que recibe dos SDTs de cierto tipo, los compara y devuelve otros dos SDTs con las diferencias. Es un algoritmo que se pensó bien, se analizaron las condiciones de borde, se testeo, está funcionando en producción.

El problema es que ahora preciso hacer lo mismo con otro SDT con otra estructura distinta... ¡Y para hacerlo tengo que repetir la programación de mi algoritmo!

Esto claramente no es lo más eficiente...

Lo que me gustaría, sería tener una sola versión del algoritmo, que pudiera invocar con distintos tipos de SDTs. De alguna forma debería poder:
  • definir variables de tipo "SDT Collection", genéricas, que se pudieran recibir como parámetro pasando cualquier SDT que sea una colección
  • definir variables de tipo "SDT Collection Item", genéricas, que pudiera usar para recorrer colecciones de tipo "SDT Collection" genéricas o cualquier otra colección
  • pasar una función (o varias), cuya firma dependerá del algoritmo que estoy implementado, que podrá recibir items de algún SDT (acá sí, específico), que será invocada desde el algoritmo pasando items del SDT genérico
El último punto, pasar una función por parámetro, ya se puede hacer, pero no me gusta como está resuelto... Igual eso es para otra nota.

Otra cosa que sería útil para los SDTs, que es bastante parecido a lo que decía hace unos días sobre la definición de variables, es que se pudieran definir campos en tiempo de ejecución. Hoy tenemos muchos SDTs distintos, algunos que se usan en un solo objeto.

Si pudiera combinar un SDT genérico con la posibilidad de definir campos en tiempo de ejecución, hay muchos SDTs que ni siquiera tendría que definir. Dejaría definidos solo aquellos que se usan más, o que son compartidos entre varios objetos.

A lo que me refiero es que si tengo una variable &item de tipo "SDT Collection Item", que pueda hacer:
&item.MiCampo = 'Hola mundo'
y que el generador asuma que "MiCampo" es de tipo char(N).

viernes, 9 de abril de 2010

Definición de variables en GeneXus

En GeneXus, las variables se debe definir indicando el tipo de datos y en algunos casos el largo y la cantidad de decimales.

Con esto, estamos ayudando de alguna forma al especificador/generador, que ya sabe de que tipo tiene que definir cada una.

Pero en realidad, ¿no debería ser al revés? ¿No debería el especificador solucionarnos los problemas?

En algunos casos GeneXus infiere el tipo de las variables, como por ejemplo cuando se llama igual que un atributo, o cuando termina con el nombre de un dominio.

Hay otros casos donde los infiere el especificador, pero dando un warning, y en realidad no quedan definidas en el objeto. Por ejemplo, cuando asignamos una valor a una variable que no fue definida.

Lo que propongo en realidad es mucho más genérico: que no haya que definir ninguna variable.

El especificador debería validar que se usen correctamente (que no se asigne un char a una variable que antes se asignó un número, por ejemplo) y dar errores si corresponde. Otro control que debería hacer es que no se use una variable antes de ser asignada, para evitar que hayan errores de escritura en los nombres.

También debería haber un paso antes, en el IDE. La primera vez que uso una variable en el código, ya debería quedar definida de alguna forma, para que la muestre la próxima vez que escribo un &.

Le estoy dando vueltas al tema desde hace un rato, y cada vez estoy más convencido que es una funcionalidad que deberíamos tener. ¿Tiene alguna contra que se les ocurra?

domingo, 4 de abril de 2010

Aplicación uruguaya en el top 15 del iPad

Hace unos días la gente de SouthLabs anunciaba en su blog la publicación de la aplicación SharePlus en la App Store de Apple, su primer aplicación para el iPad.

Hoy anuncian que la aplicación fue aprobada, y que integra la primer tanda de aplicaciones disponibles para el iPad. No solo eso, sino que además está dentro de las 15 aplicaciones de negocios más bajadas.

Es bueno ver que una empresa uruguaya alcanza estos logros. Así que: ¡felicitaciones!