Qué problema tiene este código? (II)

“Captured by the moment
In the magic of a yesterday
Captured by the moment
And I hope it never fades away”
(“Captured by the moment”, Steve Perry, 1984)

Aquí va otro puzle del que seguramente algunos ya sabrán la respuesta, pero espero que a otros les enseñe algo nuevo. Se me ocurrió presentarlo aquí después de leer la reciente (y excelente) serie de posts sobre las expresiones lambda de José M. Aguilar.

El siguiente programa intenta calcular las potencias de 2 (1, 2, 4, 16, 32, etc.) utilizando un array de funciones lambda para elevar a cada una de las potencias. Pero… ¿consigue su objetivo? La respuesta (la letra de la canción contiene, por supuesto, una pista) – en una próxima entrega.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        const int MAX_POWER = 6;

        static void Main(string[] args)
        {
            // Create array of ‘power’ functions
            var powers = Func<int, int>[MAX_POWER];
            for (int i = 0; i < MAX_POWER; i++)
                powers[i] = x => (int) Math.Round(Math.Pow(x, i));

            // Print powers of 2
            for (int i = 0; i < MAX_POWER; i++)
                Console.WriteLine(powers[i](2));
        }
    }
}


Pop/rock tip: Journey fue una de las bandas de rock más populares de Norteamérica durante finales de los ’70 y la década de los ’80. Temas suyos como “Don’t stop believing” siguen apareciendo frecuentemente en la radio y la televisión (por ejemplo, la serie “Los Soprano“) y utilizándose en eventos deportivos (sobre todo cuando el equipo local va perdiendo :-). Un elemento distintivo de la música de Journey fue siempre la espectacular voz de su cantante Steve Perry, que paralelamente a su trabajo con la banda hizo su debut en solitario con el exitoso álbum “Street Talk” (1984), al que pertenece a canción que hemos utilizado aquí.

Por cierto, Journey aún sigue “dando guerra”, y el pasado verano pudimos verlos en Madrid ahora con otro cantante, Arnel Pineda, cuya voz se parece bastante a la de Perry.

Octavio Hernandez

Desarrollador y consultor en tecnologías .NET. Microsoft C# MVP entre 2004 y 2010.

6 comentarios en “Qué problema tiene este código? (II)

  1. Mejor así.
    for (int j = 0; j < MAX_POWER; j++) { int i = j; powers[i] = x => (int)Math.Round(
    Math.Pow(x, i));

    }
    Nada elegante, por cierto.

  2. Como las lambdas de C# sean como las del C++0x está claro, o eso creo (sólo lo he leído).

    🙂

    En un predicado no se modifican las… 😛

  3. Las expresiones Lambda ven las variables del ámbito en el que son declaradas y las usan cuando se ejecuta, no al declarar la función, por eso i siempre vale 6, ya que ve el i del ámbito del primer loop.

    Así pues si escribiésemos…

    // Create array of ‘power’ functions
    var powers = new Func[MAX_POWER];
    int i=0;
    for (i = 0; i < MAX_POWER; i++) powers[i] =x => (int) Math.Round(Math.Pow(x, i));
    // Print powers of 2
    for (i = 0; i < MAX_POWER; i++) Console.WriteLine(powers[i](2)); ...daría un resultado correcto. A veces un error compensa al otro. Da miedo eh?

  4. @Avalon, jmservera: Respuestas correctas.

    @Rafa: Mucho me temo que mi C++ se ha quedado un poco estancado. ¿Podrías recomendarme algún libro u otra fuente sobre C++ 0x?

    @jmservera: Efectivamente, esto da cierto miedo… Pero no queda otro remedio que coger el toro por los cuernos y conocer lo que hay para que no nos pille desprevenidos..

    Salu2 – Octavio

  5. Hola, gracias por la referencia, Octavio!

    La verdad es que esta “magia” asusta un poco cuando te enfrentas a ella las primeras veces. Creo que no conseguí entender del todo estos mecanismos hasta que vi con Reflector el resultado de compilar código con casos de captura de variables (levantamiento, creo que es más exacto) que ese.

    Saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *