Expresiones Lambda y las Funciones
Así como con los métodos las expresiones ofrecen una serie de herramientas poderosas, en el caso de las funciones, tampoco existen excepciones a esta regla. Analicemos el siguiente código.
Dim strCol As String = ""
Dim numeros() = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Dim lastIdx = Function(intArr() As Integer) intArr.Length - 1
For i = 0 To lastIdx(numeros)
numeros(i) += 1
strCol &= numeros(i).ToString & vbCr
Next
MsgBox(strCol)
|
Se procede a crear una variable de cadena para acumular los datos para la muestra final del proceso, luego, se crea una variable tipo vector donde se proceden a cargar diez números indexados partiendo del cero como origen y como límite el número 9. La siguiente línea crea la expresión lambda. La función encapsulada en la expresión se trata de un vector. Luego, dentro de lo que sería el cuerpo de la función, se determina el límite del vector mediante la propiedad Length. Se le resta uno para ajustar el recorrido tope final del vector por sobre su índice y evitar que se desborde la cuenta por parte del bucle For…Next. Por último, el bucle For…Next procede a la cuenta y recorrido del vector y cada valor contenido en cada una de las celdas del vector se le suma el valor uno, lo que como resultado final, se obtendrá la lista de los números contenidos en el vector más uno, lo que refleja una tirada del 1 al 10.
Expresiones Lambda y el Lenguaje LINQ
No cabe la menor duda que las expresiones lambda junto a las instrucciones que proporciona LINQ resultan en una dupla complementarias en materia de desarrollo de software. La inclusión y el uso de expresiones lambda en consultas de base de datos utilizando LINQ son elementales y poderosos.
Cabe señalar que mediante LINQ resulta posible construir suficiente y eficiente código para, no solamente poder acceder bases de datos, tablas, consultas, storeprocedure, triggers, etc., sino que también resulta posible manipular dichos datos en dichos centros de datos de forma directa y eficaz. No se requiere de mucho esfuerzo y su principal ventaja es que no es necesario aprender por completo el lenguaje SQL y todos sus artilugios, de manera que de esta forma, se pueda explotar todas sus virtudes. LINQ ofrece una forma menos exhaustiva de desarrollar software y para ello recurre al uso de expresiones lambda entre otras técnicas.
El moderno concepto de OODBMS (Oriented Object Database Managment System) bases de datos orientado a objetos utiliza como eje central de desarrollo el uso del lenguaje LINQ y adiciona a este compendio el uso de expresiones lambda como un modelo de desarrollo excepcional. No obstante, también es utilizado en escenarios donde se utiliza la persistencia de datos, aplicadas tanto a RDBMS (Relational Database Managment System) base de datos relacionales como en OODBMS bases de datos orientado a objetos.
En efecto, en este extracto de código se reafirma lo dicho. Analicemos esta propuesta basada en un extracto de código basado en el lenguaje LINQ.
Dim customers As List(Of Customer) = GetCustomerList()
Dim customersByCountry = From cust In customers
Order By cust.Country, cust.City
Group By CountryName = cust.Country
Into RegionalCustomers = Group, Count()
Order By CountryName
For Each country In customersByCountry
Console.WriteLine(country.CountryName &
" (" & country.Count & ")" & vbCrLf)
For Each customer In country.RegionalCustomers
Console.WriteLine(vbTab & customer.CompanyName &
" (" & customer.City & ")")
Next
Next
|
La primera línea carga la base de datos y sus componentes en una colección tipo lista e incluye como parámetro una clase entidad de los clientes llamada Customer. La clase entidad tan solo contiene los campos y sus atributos para modelar su estructura. En la segunda línea encontramos la construcción lambda de estudio. Se crea entonces la variable llamada customersByCountry (clientes por país) y se lo asocia a la estructura SQL LINQ junto a todos sus atributos; como podrá observar en el extracto de código. La estructura SQL se trata de una consulta que construye un grupo de selección, los cuenta, los ordena por nombre de países a través de sus regiones mostrándolos por grupos de países y detallando cada una de sus regiones. Luego, con el uso de dos bucles For…Each…Next se los muestra en pantalla a través de la consola del sistema. El tipo de salida es ocurrente, pero Ud., podría destinarlo a otro tipo de objetos visuales si lo desea. El efecto será el mismo.
Expresiones Árboles basadas en Expresiones Lambda
Las expresiones árboles se basan en la estructura tradicional de árboles. Los árboles son secciones jerarquizadas que contienen una serie de nodos subordinados. Así como se compone la estructura de los archivos XML que tienen una serie contigua de nodos que generalmente se los conoce con el nombre de hijos y padres, conforma así, la jerarquía de datos de información y sus relaciones coercitivas. Las expresiones lambda utiliza la estructura arborescente para construir expresiones más complejas o anidadas, como hemos visto al principio de este artículo.
Gran parte de esta organización tiene como relevancia dos aspectos interesantes. Por empezar la forma en cómo se construye el código y, por el otro lado, cómo este código es tratado y ejecutado en sistema. Lo interesante al respecto de cómo es ejecutado es que parte de la estructura no es tratada directamente por el MSIL, sino que son tratados como evaluaciones de la compilación del Framework, lo que en teoría, los convierte en más veloces. Se dicen que este tipo de expresiones están optimizadas. Esto es al menos lo que afirma Microsoft en su arquitectura Framework 4 al respecto.
A continuación, analizaremos una estructura de expresión tipo árbol basada en una expresión lambda. Demás está de aclararle que para poder utilizar la clase Expression debe importa la librerías de LINQ como señala este trozo del siguiente código y al que podrá probar en su entorno de desarrollo.
Imports System.Linq.Expressions
...
Dim expr As Expression(Of Func(Of Integer, Boolean)) = Function(num) num > 17
Dim result As Func(Of Integer, Boolean) = expr.Compile()
Dim numero As Integer = InputBox("Ingrese su edad")
Dim mensaje = Function(x As Boolean) IIf(x, "Mayor de Edad", "Menor de Edad")
MsgBox(mensaje(result(numero)))
|
Este trozo de código resulta ser muy sencillo de comprender. En la primera línea se crea la expresión árbol mediante el uso de la clase Expression. Esta clase contiene como parámetro a la clase Func. Finalmente, esta última clase contiene como parámetro los tipos de datos que devolverá y que aceptará como entrada para su posterior procesamiento. Para cerrar, la función final que determina mediante un axioma lógico la determinación si un número ingresado y pasado a una variable, aquí llamada num, resulta ser un número mayor o menor al valor 17. Según sea el resultado de la comparación del axioma lógico, este arrojará un valor booleano de salida. Siendo verdad o falsedad según el resultado del analices de dicha axioma.
En la segunda línea entramos en el concepto más interesante que justifica el uso de expresiones árboles. Notará que al final de la línea, la variable expr ejecuta el método Compile(). Este método invoca que el código se compile y, de esta forma, se evita que sea tratado por el MSIL. He aquí la estrategia de obtener un código más rápido y ágil puesto que al ser compilado directamente se ahorra el tiempo de latencia que insume lógicamente el proceso que realiza generalmente MSIL.
El resto de las líneas se reduce a determinar si el número ingresado por consola se trata de un tipo de edad que redunda en ser mayor o menor de edad respectivamente. Resulta interesante destacar el uso de una expresión lambda sencilla para reducir el código para determinar el tipo de edad y emitir el mensaje en pantalla.
Resulta importante señalar que la estructura árbol puede descomponerse en partes utilizando una serie de clases específicas contenidas dentro de la librería Expressions, por ejemplo, aquí cito algunos elementos más significativos de dicha descomposición.
Dim param As ParameterExpression = expr.Parameters(0) Dim binOper As BinaryExpression = expr.Body Dim paramLeft As ParameterExpression = oper.Left Dim constRight As ConstantExpression = oper.Right |
Veamos cómo aplicar esta descomposición en un código más legible y saque sus propias conclusiones.
Dim expr As Expression(Of Func(Of Integer, Boolean)) = Function(num) num > 17
Dim param As ParameterExpression = expr.Parameters(0)
Dim binOper As BinaryExpression = expr.Body
Dim paramLeft As ParameterExpression = binOper.Left
Dim constRight As ConstantExpression = binOper.Right
MsgBox(String.Format("Descomposición de la Expresión: {0} > {1} {2} {3}",
param.Name, paramLeft.Name, binOper.NodeType, constRight.Value))
|
El resultado sería este:
|
Descomposición de la Expresión: num > num GreaterThan 17
|
Desarrollado y redactado por Wagner, Ariel Alejandro
Job Systems Solutions
No hay comentarios:
Publicar un comentario