lunes, 17 de diciembre de 2012

Yield en scala y en ruby


Yield es una palabra reservada en diferentes lenguajes por ejemplo en Ruby, podemos definir un código, dejando una definición a medias para poder ampliarla en el momento el que sea llamada, por ejemplo:


def ordena( vector )
     (0..(vector.size-2)).each do |i|
         k = i
         (i+1..(vector.size-1)).each do |j|
             k=j if yield(vector[k], vector[j])
         end
         if k!=i
             tmp = vector[k]
             vector[k] = vector[i]
             vector[i] = tmp
         end
     end
end

vector = [ 5, 3, 2, 4, 6, 1 ]

ordena(vector) do |e1, e2|
    (e1 > e2)
end

puts vector  # [1, 2, 3, 4, 5, 6]

ordena(vector) do |e1, e2|
    (e1 < e2)
end

puts vector  # [6, 5, 4, 3, 2, 1]

Como se ve en el ejemplo a ordena se le pasa un vector y también un pedazo de código o closure, y este se ejecuta donde se encuentra la palabra yield. Como se puede ver se aprovecha mucho que ruby es dinámicamente tipado.

Pero en Scala es diferente, yield es usado para retornar resultados múltiples desde una iteración. Por ejemplo:

val range = 1 to 5
for(val i <- range) yield i+1 //RandomAccessSeq.Projection[Int] = RangeM(2, 3, 4, 5, 6)

Como podemos ver con el for se itera y con yield es como se van acumulando los resultados.

Por lo visto, cambia mucho el uso de Yield desde Ruby a Scala. Cuidado con esto puede ser causa de muchas errores!