Ejercicio: ¿Cómo calcularías el mínimos de 3 números?
// Es una forma más declarativa que simplemente hacer varios if/else
// También tiene un mayor nivel de abstracción
return Arrays.sort({a, b, c})[0];
Tema 1. Paradigmas de programación
Declarativo vs Imperativo
- Lo declarativo es de más alto nivel (qué quiero obtener pero sin especificar el cómo), mientras que imperativo es de más bajo nivel (qué quiero obtener especificando el cómo)
Paradigmas
- No estructurado: hay saltos en cualquier sitio del código. Difícil de entender y mantener
- Estructurado basado en procedimientos
- Orientado a objetos
- Funcional: los datos manejados son inmutables (a diferencia de el POO, ej: un setter que modifica un objeto)
- Lógico
Tecnología de la Programación
C#
es un lenguaje multiparadigma
Tema 2. Paradigma Orientado a Objetos
- Encapsulamiento: ocultación de la información
Propiedades
- Sintaxis para realizar los getters y los setters
- Permiten acceder al estado de los objetos como si de atributos se tratase
- Las propiedades son azúcar sintáctico
Acoplamiento y Cohesión
- Acoplamiento: nivel de interdependencia entre módulos
- Cohesión: uniformidad entre las responsabilidades de un módulo (fácil entendimiento)
Herencia vs polimorfismo vs enlace dinámico
- Herencia: mecanismo de reutilización de código por el cual una clase hija extiende y comparte el comportamiento de una clase más general.
- Polimorfismo: En la clase hija se puede modificar o ampliar el comportamiento de la clase padre
- Enlace dinámico: la redefinición de la implementación de un método en una clase hija que hereda de la clase padre
Asertos
- Excepciones que se deben cumplir para que la ejecución del programa sea correcta
# if DEBUG
...
#else
...
#endif
Ejercicio Diseño Reloj
Genericidad
- Usar
<T>
, lo que se conoce como variable de tipo
Genericidad acotada
La diferencia es que en el primero el T pueden ser de la clase Personas y además esas Personas han de implementar la interfaz IComparable, mientras que en el segundo, el vector está compuesto exclusivamente de IComparable.
En la segunda versión, sólo tenemos los métodos de IComparable, mientras que en la primera podemos invocar cualquier método del tipo:
// Supón la clase Persona, con Edad, Nombre...
//Caso 1
Puedes llamar a -> v[0].getEdad, v[0].getNombre()...
//Caso 2
Puedes llamar a -> v[0].compareTo(...) exclusivamente
Paradigma funcional
- El tipo de una función es su tipo de retorno + el tipo de sus parámetros
Expresiones Lambda
λx.M
(x son los parámetros y M es el retorno)
Reducción ß
(λx.M)N
→ M[x:=N]
-
Para
(λx.x+x)(3)
- M es lo que va dentro de la función (x+x)
- N es el valor que va a recibir (3)
-
Ejemplo de retorno:
- Se devuelve un resultado
(λx.x+x)3
→3+3
- Se devuelve otra función:
(λx.x)λy.y*2
→λy.y*2
- Se devuelve un resultado
Conversión α
- Calcular el doble del doble de n:
(λf.(λx.f(fx)) (λx.x+x)n
→(λf.(λx.(λy.y+y) ((λy.y+y)x)n
→(λx.(λy.y+y) ((λz.z+z)x)n
→(λy.y+y) ((λz.z+z)x)n
→((λz.z+z)n) ((λz.z+z)x)n
→(n+n) + (λx.x+x)n)
→(n+n)+(n+n)
Tipos delegados predefinidos
Func<T>
oFunc<T1,T2>
: siempre devuelve algo (no tiene por qué tener parámetros)Action
oAction<T>
: método que no devuelve nunca nada (puede tener o no parámetros)Predicate<T>
: método que retorna unbool
y recibe unT
Expresiones Lambda
IDictionary > calculadoraFuncional = new Dictionary>(); calculadoraFuncional["add"] = (op1, op2) => op1 + op2; calculadoraFuncional["sub"] = (op1, op2) => op1 - op2; calculadoraFuncional["mul"] = (op1, op2) => op1 * op2; calculadoraFuncional["div"] = (op1, op2) => op1 / op2; calculadoraFuncional[“add"](3, 4); // 7
IList> condiciones = new List>();
condiciones.Add(s => s.Length < 5);
condiciones.Add(s => !s.StartsWith("F"));
condiciones.Add(s => s.EndsWith(“i")); string str = “Hi";
foreach (var cond in condiciones) { if (!cond(str)) {…} }
Bucles y Recursividad
Combinador de Punto Fijo
Currificación
Aplicación parcial
Transparencia referencial
- Si un lenguaje ofrece clausuras, ¿puede ofrecer transparencia referencial?
- Si
Memoización
- Si una expresión posee trasparencia referencial, se puede optimizar mediante memoización
- La primera vez que se invoca, se guarda en una caché
static class FibonacciMemoizacion {
private static IDictionary<int, int> valores = new Dictionary<int, int>();
internal static int Fibonacci(int n) {
if (valores.Keys.Contains(n))
return valores[n];
int valor = n <= 2 ? 1 : Fibonacci(n - 2) + Fibonacci(n - 1);
valores.Add(n, valor);
return valor;
}
}
- Tiene como ventaja ahorrar secuencias de fibonacci previamente calculadas
eval("10 + 20")
# returns 30
Pattern matching F#
- Función de Orden superior: Es un Map
- Como característica usa el Pattern Matching
- La principal diferencia es que no se usa recursividad
- Para el +, se aplica aplicación parcial
- Imprimiría
2 3 4 5
, pues se va sumando 1 a cada elemento
f(a,b)
f(a)(b) //como está currificada, f(a) devuelve otra función a la que se le pasa b
f(a) //aplicación parcial, para no tener que pasar el parámetro b, creando así una nueva función distinta a la f(a) original
Pattern Matching en C#
Funciones de Orden Superior
-
Una función currificada es una función de orden superior, pues devuelve otra función
-
Funciones y su equivalente en Linq:
- Filter → Where
- Map → Select
- Reduce → Aggregate
Ejemplos de Select
Ejemplos de Where
Ejemplos de Reduce
Otras funciones
Fundamentos de la programación paralela y concurrente
- La fecha del 1 indica que es asíncrono
- La flecha del 2 indica que es síncrono
async
y await
Sincronización de Hilos
¿Cómo funciona el lock?
lock(Console.Out)//Es importante decidir qué objeto usar y a qué referenciase refiere (en tiempo de ejecución ha de ser la misma referencia)
{
...
}
- El lock NO impide que el objeto lockeado se use en otras partes de la aplicación
- Por tanto, esto nos puede conllevar a condiciones de carrera
- El bloqueo se hace considerando el objeto en tiempo de ejecución
- No se pueden ejecutar a la vez porque apuntan al mismo objeto (misma referencia)
- Se pueden ejecutar a la vez porque cada hilo puede apuntar a un objeto distinto
Interbloqueo
- El interbloqueo está en el
lock(this)
TPL y PLINQ
- TPL (Task Parallel Library)
- PLINQ (Parallel LINQ)
Parallel.ForEach
- Justo al final se hace un
Join
Tema 5. Tipado Dinámico y Metaprogramación
Multiple Dispatch
- Ejercicio obligatorio:
- Q1 llama a A
- Q2 llama a K
- Q3 llama a K en tiempo de compilación y de ejecución (no hay multiple dispatch en C#)
- Un solución sería usar el visitor