domingo, 20 de octubre de 2024

Un vistazo a la programación funcional

La Programación Funcional (Functional Programming)es un paradigma de programación declarativa (decir qué queremos, pero no cómo hacerlo) basado en el uso de funciones matemáticas donde:

  • Estaremos trabajando principalmente con funciones (el elemento principal para construir programas), evitaremos los datos mutables, así como el hecho de compartir estados entre funciones.
  • Y donde el valor generado por una función depende exclusivamente de los argumentos alimentados a la función.
  • Las funciones serán tratadas como ciudadanos de primera clase y podrán ser asignadas a variables además podrán ser utilizadas como entrada y salida de otras funciones.
  • Además, evitamos a toda costa los efectos secundarios que alteren el estado del programa u otros programas.
  • Ejemplos de lenguajes que soportan este paradigma son Haskell, Elixir, Erlang , Scala, y Clojure.

Características principales:

  1. Funciones puras: Las funciones siempre producen el mismo resultado para los mismos argumentos y no tienen efectos colaterales (no modifican variables globales ni realizan I/O directamente). 
  2.  Inmutabilidad: Los datos no se pueden modificar una vez creados. En lugar de cambiar valores, se crean nuevos valores. 
  3.  Funciones de orden superior: Las funciones pueden aceptar otras funciones como argumentos o devolver funciones. 
  4.  Composición de funciones: Las funciones se pueden combinar para crear otras más complejas, facilitando la reutilización de código. 
  5.  Evaluación perezosa: Las expresiones no se evalúan hasta que su resultado es necesario, optimizando el rendimiento en muchos casos.

Ventajas:

  1. Código más predecible y fácil de razonar gracias a la ausencia de efectos colaterales. 
  2. Facilidad para la concurrencia y el paralelismo, ya que no hay variables mutables que puedan causar conflictos.

Algunos conceptos clave de la Programación Funcional

  1. Funciones puras: Funciones que siempre producen el mismo resultado para los mismos argumentos. 
  2. Inmutabilidad: Los valores no pueden ser modificados una vez creados.
  3. Currificación: Funciones que pueden ser llamadas con menos argumentos de los que requieren originalmente.
  4. Composición de funciones: Encadenar funciones mediante el operador (.).
  5. Pattern matching: Hacer coincidir patrones en listas, tuplas, y otros datos estructurados.
  6. Guards y condicionales: Usar guards para control de flujo condicional.
  7. Recursión: La forma principal de control de iteraciones.

Ejemplo 1. Crear una función pura que nos sume dos números enteros. Este ejemplo lo haremos en Haskell.

suma.hs

suma :: Int -> Int -> Int
suma x y = x + y

main :: IO()
main = print (suma 8 3)

Como se puede ver, iniciamos con la delaración de tipos (Int). Definimos la función (suma) y en la d¿función principal (main) asignamos dos valores por default (8 y 3), lo cual nos dará como resultado 11.

Si solo queremos ejecutar el programa, abrimos una terminal y tecleamos lo siguiente:

runghc suma.hs

Si queremos compilar y crear un ejecutable, entonces:

ghc -o suma.exe suma.hs

Como la definición de una Función Pura indica, el resultado será el mismo cuando los argumentos son los mismos. Si invertimos el lugar del los valores (8, 3 por 3,8) el resultado seguirá siendo el mismo.

Aprender programación funcional se ha vuelto una "moda" que ya no solo implica el ámbito académico. Puesto que ya son muchos proyectos como la I.A. o Aprendizaje Automático que cada vez más requieren desarrolladores que dominen los principios de la matemática y, por ende, la programación funcional.

Enlaces:

https://codemonkeyjunior.blogspot.com/search?q=erlang
https://codemonkeyjunior.blogspot.com/search?q=elixir
https://emanuelpeg.blogspot.com/search?q=haskell

sábado, 19 de octubre de 2024

Terraform o Infraestructura cómo código

 

Según la Wikipedia, la Infraestructura como Código (Infrastructure as Code, en Inglés) es: el proceso de gestión y aprovisionamiento de centros de datos informáticos a través de archivos de definición legibles por máquina, en lugar de configuración de hardware físico o herramientas de configuración interactiva.

Básicamente:

  • Es la capacidad de aprovisionar y respaldar su infraestructura de computación a través de código en lugar de procesos y configuraciones manuales.  
  • Permite definir el estado deseado de su infraestructura sin incluir todos los pasos para llegar a ese estado.
  • Automatiza la administración de la infraestructura para que los desarrolladores puedan centrarse en crear y mejorar las aplicaciones en lugar de administrar los entornos.

Enfoques diferentes de la infraestructura como código

Declarativa

La IaC declarativa permite al desarrollador describir los recursos y la configuración que componen el estado final de un sistema deseado.

A continuación, la solución de IaC crea este sistema a partir del código de infraestructura. Esto hace que la IaC declarativa sea fácil de usar, siempre que el desarrollador sepa qué componentes y configuraciones necesita para ejecutar su aplicación.

Imperativa

La IaC imperativa permite al desarrollador describir todos los pasos para configurar los recursos y llegar al sistema y al estado de ejecución deseados.

Si bien no es tan sencillo escribir la IaC imperativa como la IaC declarativa, el enfoque imperativo se hace necesario en las implementaciones de infraestructuras complejas. Esto es especialmente cierto cuando el orden de los eventos es crítico.

¿Qué es Terraform?

Terraform es una herramienta de Infraestructura como Código (IaC) que permite definir, provisionar y gestionar infraestructura en la nube o en entornos locales mediante archivos de configuración.

Estos archivos, escritos en un lenguaje declarativo llamado HashiCorp Configuration Language (HCL), describen los recursos y servicios que se quieren desplegar, como servidores, redes, bases de datos, entre otros.

Terraform es capaz de interactuar con múltiples proveedores de servicios en la nube (como AWS, Azure, Google Cloud) y otras plataformas, facilitando la creación y modificación de infraestructuras complejas de forma eficiente.

Se relaciona con IaC porque permite automatizar y versionar la infraestructura de la misma manera que se gestiona el código de software, asegurando que las configuraciones sean reproducibles, auditables y escalables.

Instalando Terraform

En Linux:

Abrimos una terminal y escribimos estos comandos:


# Actualizar paquetes
sudo apt-get update && sudo apt-get install -y gnupg software-properties-common

# Añadir repositorio oficial de HashiCorp:

wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list

# Instalar Terraform
sudo apt-get update && sudo apt-get install terraform

# Verificar instalación
terraform -v

Tendremos instalado Terraform en Linux.

En Mac OS:

Abrimos una terminal y escribimos estos comandos:


# Instala Terraform con Homebrew:
brew tap hashicorp/tap

brew install hashicorp/tap/terraform

terraform -v

Tendremos instalado Terraform en Mac OS.

En Windows:

Para esto es necesario contar con Chocolatey instalado en nuestras máquinas:

choco install terraform

Verificamos la instalación:

terraform -v

Tendremos Terraform instalado.

Ahora imaginemos que queremos crear una instancia de EC2 en AWS. Usaremos Terraform para lograrlo. La extensión del programa será *.tf

main.tf

# Especifica el proveedor de nube, en este caso AWS
provider "aws" {
  region = "us-east-1"  # Región donde se va a desplegar la infraestructura
}

# Definir una clave SSH para conectarse a la instancia
resource "aws_key_pair" "example" {
  key_name   = "example-key"
  public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3..."  # Llave pública SSH
}

# Crear una instancia de EC2 en AWS
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"  # Identificador de la AMI (Amazon Machine Image)
  instance_type = "t2.micro"  # Tipo de la instancia

  # Configurar la clave SSH para la instancia
  key_name = aws_key_pair.example.key_name

  tags = {
    Name = "Terraform Example Instance"  # Etiqueta para identificar la instancia
  }
}

# Salida para ver la IP pública de la instancia creada
output "instance_public_ip" {
  value = aws_instance.example.public_ip
}

1. Inicializamos el proyecto:

$ terraform init

2. Previsualizar los cambios (plan):

$ terraform plan

3. Aplicar cambios:

$ terraform apply

4. Destruir la infraestructura (cuando ya no sea necesaria):

$ terraform destroy

Hemos dado una breve explicación de lo que es IaC y cómo se relaciona con Terraform.

Enlaces:

https://chocolatey.org/
https://www.terraform.io/

PL/SQL: creando Stored Procedures (1era parte)

PL/SQL es un lenguaje de programación procedimental diseñado para operar en entornos Oracle.

Con este lenguaje podemos hacer:

  • Automatizar tareas complejas dentro de la base de datos mediante procedimientos y funciones.
  • Implementar reglas de negocio complejas con triggers y validaciones. 
  • Gestionar transacciones y manejar errores de manera robusta. 
  • Manipular conjuntos de datos utilizando cursores. 
  • Integrar lógica de negocios en aplicaciones que interactúan con bases de datos Oracle.

En esta ocasión veremos cómo crear Stored Procedures o procedimientos almacenados. Los cuales son procedimiento que pueden o no devolver algún valor (contrario a las funciones que siempre devuelven algún valor). Estos podrán, una vez que sean creado, ser invocados en tus scripts.

La sintaxis para crear un Stored Procedure es la siguiente:

-- Sintaxis para crear un Stored Procedure 
CREATE [OR REPLACE] PROCEDURE procedure_name
    [ (parameter [,parameter]) ]

IS
    [declaration_section]

BEGIN
    executable_section

[EXCEPTION
    exception_section]

END [procedure_name];

Para su invocación debemos anteponer la palabra ``CALL`` seguido del nombre.

CALL miprocedimiento();
CALL miprocedimiento(arg1, arg2, argN);

En un anterior post vimos cómo crear bloques PL/SQL. Un Stored procedure contiene bloques que harán determinada tarea que nosotros definamos.

BEGIN
  DBMS_OUTPUT.PUT_LINE('Hola desde PL/SQL');
END;

Ejemplo 1. Crear un Stored procedure para mandar un mensaje a pantalla.

hola.sql

CREATE OR REPLACE PROCEDURE hola 
IS 
  nombre VARCHAR2(6):='Thomas';
BEGIN 
  IF nombre IS NOT NULL THEN 
    dbms_output.put_line('Hola, '||nombre);
  END IF;
END;
/

Lo invocamos de está forma:

SET VERIFY OFF;
SET SERVEROUTPUT ON;

-- Invocar Stored procedure
CALL hola;

Ejemplo 2. Crear un Stored Procedure para ver la versión de Oracle instalada.

mi_proc.sql

CREATE OR REPLACE PROCEDURE mi_proc
    IS
    version_inst VARCHAR(200);
    consulta VARCHAR(200):='SELECT BANNER FROM v$version';    
BEGIN
    dbms_output.put_line('Version instalada: ');
    -- Ejecutamos consulta
    EXECUTE IMMEDIATE consulta INTO version_inst;
    dbms_output.put_line(version_inst);
END;
/

Lo invocamos:

SET VERIFY OFF;
SET SERVEROUTPUT ON;

CALL mi_proc;

Enlaces:

https://codemonkeyjunior.blogspot.com/2023/07/plsql-bloques.html
https://www.plsqltutorial.com/

GCP BigQuery: funciones de cadena y tiempo

En otras entregas hemos visto la creación de funciones y el uso de funciones propias de BigQuery. Ahora nos enfocaremos en las funciones de manejo de tiempo.

Funciones de tiempo

  • CURRENT_TIME
  • EXTRACT
  • FORMAT_TIME
  • PARSE_TIME
  • TIME
  • TIME_ADD
  • TIME_DIFF
  • TIME_SUB
  • TIME_TRUNC

Algunos ejemplos de su uso pueden ser:

SELECT CURRENT_TIME() as now;

Esto nos mostrará el tiempo actual.

BEGIN 

DECLARE T1 STRING;

SET T1 = "16:33:00";

SELECT EXTRACT(HOUR FROM TIME T1) as hour;

END;

Esto extraerá la hora de la variable ``STRING`` en formato de hora (hora:minutos:segundos).

BEGIN 

DECLARE T1 STRING;

SET T1 = "09:12:00";

SELECT PARSE_TIME("%I:%M:%S", T1);

END;

Esto convertirá la cadena ``STRING`` a una hora válida.

Como se puede ver, se ha creado una variable y se da el valor de una hora con sus minutos y segundos.

BEGIN 

DECLARE T1 STRING;
DECLARE T2 STRING;

SET T1 = "09:12:00";
SET T2 = "04:23:22";

SELECT PARSE_TIME("%I:%M:%S", T1);

SELECT PARSE_TIME("%T", T2);

END;

La función ``PARSE_TIME`` es muy útil a la hora de convertir cadenas a variables tipo ``TIME``. Si la cadena cumple el formato, la conversión será correcta.

Ahora veremos la función ``PARSE_TIME` que nos sirve para representar el tiempo (horas, minutos, segundos):

SELECT TIME(15, 30, 00) as time_hms;

Como se puede ver, las funciones de tiempo en BigQuery nos pueden ayudar para obtener los valores de fecha y hora con un formato adecuado.

Enlaces:

https://codemonkeyjunior.blogspot.com/2024/08/gcp-calculando-el-imc-con-bigquery.html

domingo, 13 de octubre de 2024

¿De qué trata esProc SPL?

esProc SPL es un lenguaje de procesamiento y cálculo de datos.

  • Se ejecuta como una base de datos de análisis o middleware.
  • Útil para cálculo y procesamiento de datos estructurados y semiestructurados. Ofrece un rendimiento superior y es ideal para tareas con uso intensivo de datos en el entorno impulsado por datos actual. 
  • Útil para trabajo por lotes sin conexión, consulta en línea.
  • Ni sistema SQL ni tecnología NoSQL. Trabaja directamente sobre los datos.
  • Con sintaxis SPL de creación propia, más concisa y eficiente SPL: Lenguaje de proceso estructurado.

En conclusión, esProc SPL está diseñado para el procesamiento avanzado de datos y se destaca en el manejo eficiente de conjuntos de datos masivos.

Los sitios oficiales del lenguaje son:

Si quieres aprenderlo, puedes revisar la documentación oficial:

https://www.scudata.com/html/SPL-programming-book.html

Al iniciar la aplicación, se abre un grid similar a las hojas de Excel. Es aquí donde se escribe el código:

Escribimos el código o instrucciones de manera similar a lo que se hace en Excel:

=2*1.5
=1*(2+3)
=65536*65536*65536*65536
=1*(2-3*(4+5))

Se pueden operar con tipos de datos Integer, Float, Long, etc. Además de también realizar operaciones booleanas (que dan resultados TRUE o FALSE). Hacer uso de sentencias de control para los bucles o condiciones a cumplir en el programa (for, ).

=if(x>0,x,-x)
=if(x>y,x,y)

!true = false
!false = true

=A1*A1*A1
>A1=B1

for 20

=[3,9,0,2,2.3,9.8]

if B1<=100

Podemos concluir en que esProc SPL es un lenguaje de script para procesamiento de datos, con funciones de biblioteca ricas y bien diseñadas y una sintaxis poderosa, que puede ejecutarse en un programa Java a través de la interfaz JDBC y computarse de forma independiente.

Continuaremos en próximas entregas.

Enlaces:

https://dev.to/bigsondev/10-programming-languages-worth-learning-in-2024-afa
https://github.com/SPLWare/esProc
https://www.scudata.com/
https://www.reddit.com/r/esProc_SPL/
https://www.scudata.com/html/SPL-programming-book.html

sábado, 5 de octubre de 2024

Gleam en ejemplos

Continuamos con el tema de Gleam, un lenguaje que corre sobre la máquina virtual de Erlang (BEAM). Similar a Elixir en algunos aspectos.

Si quieres programar usando este lenguaje y además usas VsCode como editor, existe un plugin que podrás instalar:

https://marketplace.visualstudio.com/items?itemName=Gleam.gleam

Te ayudará en el resaltado de estilo, formato, definición y autocompletado.

Recordemos cómo crear un proyecto en Gleam:

gleam new proyecto

Nos ubicamos en el directorio creado:

cd proyecto

Podemos usar VsCode. Abrimos una terminal y tecleamos:

code .

Esto abrirá el editor de código.

Ejemplo 1. Crear una función que mande un saludo.

La sintaxis para crear una función es la siguiente:

pub fn nombre_funcion() {
  // Cuerpo del procedimiento o función
}

Nuestra función será esta:

pub fn saludo() {
  io.println("\t Hola, mundo desde Gleam")
}

La invocamos desde el método main del programa principal.

proyecto.gleam

import gleam/io

pub fn main() {
  saludo()
}

pub fn saludo() {
  io.println("\t Hola, mundo desde Gleam")
}

Construimos y ejecutamos:

gleam build
gleam run

Salida:

        Hola, mundo desde Gleam

Ejemplo 2. Crear una función que calcula el factorial de un número.

Teniendo el siguiente pseudo código:

numero = 5
IF numero = 0 THEN
   result = 1
IF ELSE numero = 1 THEN
   result = 1
ELSE 
   result = numero * FACTORIAL(numero - 1)

La función en Gleam quedaría de tal modo:

pub fn factorial(x: Int) -> Int {
  case x {
    0 -> 1
    1 -> 1
    _ -> x * factorial(x - 1)
  }
}

La invocamos de esta manera:

import gleam/io
import gleam/int

pub fn main() {
  io.println("\t===== Factorial en Gleam =====")
  io.println("El factorial de 5: ")
  io.debug(factorial(5))
  io.println("El factorial de 7: ")
  io.debug(factorial(7))
}

Ejemplo 3. Crear una función anónima que sume dos número enteros.

fn suma(a: Int, b: Int) -> Int {
  a + b
}

Y la invocamos de la siguiente forma:

import gleam/io
import gleam/int


pub fn main() {
  io.println("\t===== Sumando en Gleam =====")
  let add = suma(3, 4)
  io.println("Suma (3,4) es: ")
  io.debug(add)
}

Este post se irá actualizando para agregar más ejemplos.

Enlaces:

https://codemonkeyjunior.blogspot.com/2024/03/conociendo-gleam-un-lenguaje-que-corre.html
https://emanuelpeg.blogspot.com/search?q=gleam