1

Todos mis apuntes.

Máquina abstracta

¿Qué es?

Computadora digital que ejecuta algoritmos los cuales están formalizados para que la maquina entienda.

Se trata de una maquina abstracta porque estamos aislando las características de una computadora para llevarlas a este concepto. La estructura general de una maquina abstracta es que tiene una memoria donde almacena datos y sus programas, además tiene un interprete del lenguaje de programación que maneja las secuencias de control del programa, controla la transferencia de datos y además maneja su memoria. Para realizar operaciones que nos darán un resultado que será la instrucción que deseamos y lo que resulta de estas instrucciones.

Puede realizar operaciones para:

  • Procesar datos primitivos: Un dato primitivo es aquél con el que un lenguaje de programación trabaja de forma nativa. Puede tener datos primitivos de tipo entero, flotante, booleanos, etc. Los datos primitivos de un lenguaje, no son necesariamente primitivos en otro.
  • Controlar secuencia de ejecución de operaciones: La maquina abstracta no solo será capaz de llevar la secuencia de operaciones, también estructuras de control y condicionales como If, Else. Podrá usar ciclos como el bucle While, etc.
  • Controla transferencia de datos: Manejará una transferencia de datos. Quiere decir que la información puede pasar de las instrucciones a una estructura de dato y viceversa. Con tal de que la información pueda ser utilizada para sus procesamientos.
  • Manejo de memoria: Es capaz de manejar la memoria, haciendo uso de este recurso para almacenar los datos que se derivan de las operaciones de los programas o incluso, almacenar información que le indiquemos.

Ciclo de ejecución

Al ser algo conceptual tanto su estructura como ciclo de ejecución, es el mismo para todas.

Primero inicia el programa, se traen las instrucciones a través del intérprete del lenguaje, el cual las decodifica, trae sus operandos y elige que operación ejecutará. Si la operación 1,2,3 o 4. O incluso puede ser el caso en el que se fuerza a detener la ejecución del programa. Si se elije una operación que lleva más procedimientos, esto traerá resultados, los cuales se almacenan en la memoria de la maquina y se vuelve a repetir el ciclo.

La maquina de Turing:

Es un ejemplo de maquina abstracta, han existido muchas replicas y la maquina de Turing lo que hace, es que tiene 2 cintas en cada lado y en el centro tiene un dispositivo lecto escritor, es capaz de leer o escribir sobre él mismo, en los rodillos hay instrucciones, indicadas con números 1 y 0. Puede indicar que escriba, lea, etc. En un punto profundo, podemos entender que la maquina de Turing, realiza los procesos que vimos antes.

Lenguajes de programación vs Lenguaje natural

Un lenguaje lo usamos entre humanos para comunicarnos, expresar nuestros sentimientos, o incluso de forma colaborativa para llegar a un fin.

En las computadoras, nosotros usamos un lenguaje de programación para decirle qué hacer, cómo hacerlo, a través de qué recursos. Algunos lenguajes permiten ser especifico con las instrucciones.

La computadora no comete errores, nosotros dimos mal las instrucciones.

¿Qué es un lenguaje?

Estilo y modo de hablar y escribir de cada persona en particular.

Lenguaje de programación

Un lenguaje de programación es un formalismo artificial en el cual los algoritmos pueden ser expresados.

Niveles de descripción

Gramática Responde a ¿Qué oraciones son las correctas?

  • Secuencias y símbolos que forman palabras/tokens
  • Sintaxis para formar frases del lenguaje propio,

Semántica Responde a ¿Qué significan las palabras?

  • While/mientras
  • Variables
  • Funciones
  • Clases

Pragmática Responde al ¿Cómo usarlos?

  • ¿Cómo utilizamos una oración significativa? Entender de pragmática en la programación es importante, ya que al comunicarnos con la computadora, la computadora puede interpretar de una forma diferente y de ahí se derivan diferentes problemas.

Implementación

Es la forma en que se transforman esas instrucciones en acciones.

¿Qué son los paradigmas de programación?

Teoría o conjunto de teorías cuto núcleo central se acepta sin cuestionar y que suministra la base y modelo para resolver problemas y avanzar en el conocimiento

  • Clasificación de lenguajes

Basado en sus características y entendiendo que existen lenguajes multiparadigma.

  • Estilo de programación

Por su forma de abordar un problema o herramienta utilizadas.

  • Paradigmas puros

Smalltalk → P.O.O

Haskell → Funcional

  • Multiparadigma

C++, Java, JavaScript, Scala, PHP, Python, Ruby, F#, etc.

¿Qué significa tener un paradigma?

Prohibir o limitar ciertas acciones:

  • Efectos colaterales
  • Uso de goto.

Principales paradigmas de programación

  • Imperativo
  • Órdenes directas de qué hacer.
  • Enfocado al “cómo”.
  • Instrucciones paso a paso.

→Por procedimientos

→Orientado a objetos

→Fortran, Java, C, Python, Ruby, PHP, etc.

  • Declarativo
  • Se enfoca en el resultado.
  • Reduce o elimina efectos colaterales.

→Funcional

→Lógico

→Matemático

→Reactivo

→Prolog, LISP, Haskell, SQL, Elixir, XPath, Regex, etc.

  • Dirigido por eventos

Programación estructurada

Inicialmente los programas eran escritos línea a línea, siendo secuencial, podían haber programas con 5.000 líneas.

Origen

A mitad de los años 40 se reconoció que un programa y sus datos podían residir en la memoria de una computadora.

Arquitectura de Von Neumann

Se trata de una maquina que tiene un dispositivo de entrada, los procesa, tiene una unidad de control donde maneja memoria, después nos da una salida de da una salida de datos.

Estructuras de control

En 1968 Dijkstra advirtió el daño de la expresión “GOTO”. La expresión GOTO se indicaba para saltar de una línea a otra.

<h1>Programación funcional</h1>

Es un paradigma que usa funciones como “Ciudadanas de primera clase”. Puede crear funciones de orden superior. Prioriza el uso de recursividad y HOF para resolver problemas.

Una función puede recibir y dar salidas a otros datos como resultado, incluyendo a otras funciones. Se busca eliminar o reducir los efectos secundarios.

Origen

En los años 30, Alonzo Church desarrolla el cálculo Lambda. Alan Turing demuestra que este es el equivalente a las maquinas de Turing.

A finales de los 50, se desarrolla LISP, implementando la notación lambda de Church.

Dato curioso

La saga de video juegos Jack and Daxter, fueron desarrollados en GOAL (Game Oriented Assembly Lisp). Está basado en Lisp, fue desarrollado con programación netamente funcional.

(print"Hello, World!")
(defun factorial (n)
(if (= n 0) 1
(* n (factorial (- n 1)))))

Funciones

Relación entre dos conjuntos que asigna cada elemento del primero un elemento del segundo o ninguno.

En matemáticas una función es algo similar:

Un tipo de dato u objeto que toma un valor “X” y genera un valor “Y”

Puede o no devolver un resultado.

f(X) = X + 3

f(X) = X^2 + 3

Aquí tenemos el ejemplo de una función en python. Toma dos parámetros y nos va a retornar como resultado, la suma de ambos parámetros.

def suma (a, b)
return a + b
def suma (a, b): 
a + b
operacion_1 = suma(3, 2)

Ciudadanas de primera clase

Son reconocidas por el lenguaje, se utilizan como un tipo de dato y en cualquier parte del programa.

Funciones de orden superior

Es una función que puede:

  • Tomar una o más funciones como parámetro o;
  • Retornar una función como salida.

Funciones puras

  • Son determinísticas.
  • Un valor de entrada da un solo valor de salida.
  • No genera efectos secundarios.
  • No incluye funciones impuras.

Funciones lambda

  • Función anónima.
  • Comportamiento de uso único.
  • Contexto específico o corto tiempo.
  • Simplicidad.
<h1>Efectos secundarios</h1>

Es común escucharlo cuando hablamos de programación imperativa. Lo podemos ver cuando manejamos funciones o variables de contexto global o que están delimitadas. Ej: En JavaScript es muy importante tener un manejo del SCOPE (alcance de las variables)

Cuando escribimos código sabemos que lo que esta dentro de una función, no afecta a otra, si es que usamos la sintaxis correcta. Pero también existen funciones que utilicen parámetros o que tengan alcance global y puede tener efectos secundarios.

Forma en que alguien o algo se comporta ante un determinado estímulo.

Cambios observables

  • Estado de la aplicación.
  • Valores de datos.
  • Modificación de archivos, etc.
<h1>Lenguajes</h1>
  • LISP
  • SCHEME
  • CLOJURE
  • RACKET
  • ERLANG
  • HASKELL
  • F#

Como podemos ver, aquí está la función que se llama a sí misma y solamente modifica los parámetros cuando lo hace, como característica hay muchos paréntesis, pero es simplemente parte de la sintaxis.

(defun factorial (n)
(cond
((= n 0) 1)
((= n 1) 1)
(t (* n (factorial (- n 1 ))))))

Tenemos en Haskell donde calculamos el factorial de un número, en ejemplos anteriores habíamos podido ver como se define el tipo de dato, después se asignan los tipos de valores y se empieza a llamar a la función. Podemos ver que el código no es tan amplio como si lo hubiéramos escrito de forma no recursiva con otros lenguajes.

module Main whereimport Text.Printf

factorial :: Integer -> Integerfactorial0 = 1factorial n = n factorial (n - 1)

line x = printf "%d! = %d\n" x $
factorial x

main = mapM_ line [0..16]

Aquí también tenemos un ejemplo con F# que es un lenguaje funcional y vemos que también es recursivo porque la función factorial se está llamando a sí misma.

letrec factorial n = 
match n with
| 0 | 1 -> 1
| _ -> n * factorial(n-1)

<h1>Programación lógica</h1>

¿Qué es la programación lógica?

Paradigma declarativo que expresa los objetivos como una colección de afirmaciones o reglas acerca de los resultados y restricciones en lógica matemática.

Áreas de aplicación

  • NLP (Procesamiento de lenguaje natural)
  • Recuperación de información en BBDD
  • Aplicaciones matemáticas

Cláusula de Horn

La programación lógica se basa en las clausulas de Horn las cuales son preposiciones definidas por predicados, donde tenemos un hecho (algo que damos por sentado) y tenemos uno o varios predicados, lo correcto sería tener por lo menos 2, para poder determinar si algo es verdadero o falso, también se les conoce como cuerpo/body.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2da4d66f-5c12-4657-8621-ccdc51d4b84b/Untitled.png

H= Hecho/Head of the rule.

P= Predicado/Body

Ejemplo:

Podemos decir que es verdadero que está nevando en la ciudad, C es el nombre de la ciudad. Si está lloviendo y hace frío, entonces es verdadero que está nevando. Y por el contrario si quisiéramos negar que está lloviendo, pero hace frío, entonces es falso que está nevando. Esto tiene una estrecha relación con las tablas de verdad.

nevando© ← lluvia©, frío©

Origen

Se origina en los 60’s cuando Cordell Green propuso el uso de cláusulas en programas a finales de los 60.

Prolog impulsó este paradigma.

Lenguajes

  • Prolog
  • Alf
  • Fril
  • Mercury
  • Oz
  • Visual Prolog
  • XSB

No es muy frecuente este paradigma de programación en la industria, se usa más para investigación y cuestiones académicas, dada su naturaleza.

% Hola mundo

?- write('Hello World!'), nl
> HelloWorld!
> true

En este ejemplo podemos ver como le indicamos que hay personas que hablan un lenguaje, hacemos la evaluación de la persona 1 con la persona 2 y cuál es el resultado. Luego hacemos también la evaluación, preguntando “Quién habla francés” El resultado retornado debería ser “Juan”

speaks(juan, french)
speaks(isabel, english)
speaks(eduadro, french)
speaks(eduardo, english)

talkswith(Person1, Person2) :-
speaks(Person1, L),
speaks(Person2, L),
Person1 \= Person2

?- speaks(Who, French)
<h1>Programación dirigida por eventos</h1>

Se caracteriza porque no controla la secuencia de ejecuciones, reacciona a los sucesos ocurridos.

Generalmente los programas corren indefinidamente integrando manejadores de eventos (event handlers).

Eventos

  • Clicks
  • Teclas
  • Sensores
  • Mensajes
  • Triggers

Casos de aplicación

  • GUIs
  • Aplicaciones web
  • Sistemas de booking
  • Sistemas de alarmas
  • Robótica
  • Videojuegos

Cómo funciona

Sí lo comparamos con la programación imperativa, tenemos una secuencia de pasos que se van a ejecutar de manera secuencial y después puede repetirse el ciclo o puede llegar a detenerse el programa porque así lo decidimos o porque forzamos su detención. En la programación dirigida por eventos, tenemos un ciclo que puede ser un while el cuál mientras haya una condición sea verdadera o falsa, se puede estar ejecutando de manera indefinida. Entonces este ciclo va a recibir ciertos eventos que van a modificar algunas variables de estado, que puede ser como el caso de un videojuego, el contador de vidas, en el cual la condición dice que mientras que el número de vidas sea mayor que 0, se va a estar ejecutando el programa, pero habrán ciertos eventos que van a hacer que ese número de vidas disminuya o aumenten y por consecuencia el videojuego termine en ese ciclo.

Lenguajes

  • Java

  • Javascript

  • C#

  • Librerías/Frameworks de GUI

    -JavaFX, React.js, PyQT

  • Prácticamente cualquier lenguaje orientado a objetos.

<h1>Programación concurrente</h1>

Analogía: Imagina ser el propietario de una panadería, mientras se calienta el horno, estás cortando masa, cortándola, preparándola y una vez que se están horneando, al sacarlos hay que esperar a que se enfríen y después colocar una cobertura de chocolate. Tú intentarás optimizar los recursos, mientras el horno se está calentando, debes preparar más masa, para que así, cuando termine, inmediatamente meter el otro lote de masa o si contratas a una persona que te ayude, dividirás las tareas, al hacer esto, estás ejecutando el paralelismo, que es dividir las tareas entre los recursos disponibles, siempre y cuando puedan dividirse.

Concurrencia

Coincidencia, concurso simultáneo de varias circunstancias.

Es cuando hay una serie de peticiones a un mismo recurso que podría ser limitado y se están atendiendo esas solicitudes de forma parcial o totalmente desordenada. Una analogía útil para entender, puede ser la panadería, imagina que tu panadería empieza a crecer y a ser muy grande, por lo tanto es bastante concurrida y los clientes empiezan a acumularse, por lo tanto, tú no puedes atenderlos a todos, empezarían a enojarse por no ser atendidos de forma rápida y ordenada. Una forma de solucionarlo, podría ser un sistema de tickets, para así atender a los clientes en su orden de llegada.

Concurrencia vs Paralelismo

En la concurrencia

tenemos una serie de peticiones con un solo recurso limitado para atenderlos, ¿Cuál sería el orden, la prioridad? etc.

En el paralelismo

Tenemos recursos divididos que pueden atenderlos de forma simultanea sin ningún problema

El paralelismo y la concurrencia, son conceptos diferentes pero que van de la mano, por ello debemos entender ambos para entenderlos entre sí.

Secuencia vs Concurrencia

En una secuencia

Vamos a tener los pasos A, B, C, D. Y estos serán atendidos en el orden que se hizo la petición.

En la concurrencia

Podemos iniciar en el proceso A, saltar al D, luego al C, completar el A y después pasar al último proceso.

Todo esto se hace mediante los hilos de un procesamiento

Estados de un hilo

  • Creado: No está listo para correr.
  • Ejecutable/Listo: Espera para ejecutarse.
  • Ejecutando: Se ejecuta en el procesador.
  • Bloqueado: Espera a entrar al código que requiere acceso al recurso compartido o abandona el procesador.
  • Terminado: Se ha detenido y no puede reiniciarse.

Sección crítica del hilo

Es una sección de código que requiere acceso exclusivo a una variable compartida.

Comunicación entre hilos

  • Acceso exclusivo a un recurso compartido.
  • Intercambiar información con otro hilo.
<h1>Problemas de concurrencia</h1>

Carreras (Critical races)

Sucede cuando dos o más hilos desean acceder a un recurso lo más pronto posible. Podemos ver este ejemplo, tenemos una variable C, inicializamos en 0, pero después en alguna parte del código a C, le asignamos el valor de C + 1, entonces un hilo llegará primero y al ver que vale 0, le agregará el valor de 1, almacena ese dato y ahora C vale 1. Pero sí otro hilo llega después, pensará que C vale 1, entonces añadirá otro 1, almacenará ese dato y entonces C vale 2. Esto puede ser un problema en un sistema automatizado de dosificación de medicamentos. Sí el sistema es concurrente, ¿Entonces que hará? ¿Le dará una dosis o dos dosis? ¿Cómo se resuelve?.

Puntos muertos (deadlock)

Ocurre cuando un hilo espera por un evento que nunca sucederá.

Para que suceda un punto muerto deben de cumplirse 4 condiciones:

  • Los hilos deben tener derechos exclusivos a los recursos.
  • Los hilos deben contener algunos recursos mientras esperan otros.
  • Los recursos no se pueden eliminar de los hilos en espera.
  • Existe una cadena circular de hilos en las que cada uno contiene uno o más recursos del siguiente hilo.

Problema de los filósofos

El problema plantea que hay una mesa redonda donde hay 5filósofos que están conversando, frente a ellos hay un plato de comida, a su derecha y a su izquierda, hay otros filósofos y hay un palillo chino a la derecha y otro a la izquierda, para comer se necesitan ambos palillos chinos, eso significa que habrá una persona que no comerá. Hay muchas formas de abordar el problema, pero esas soluciones pueden dar otros problemas, podría ser un sistema de turnos, pero entonces algunos se quedarían esperando hasta que la comida esté fría o tenga mucha hambre. Podríamos hacer que se alternen los turnos de comida.

Estrategias

Evitar que se cumpla alguna de las condiciones

  • Semáforos: Funcionarían como una variable de tipo entero, asociado a un mecanismo de cola de hilos. Si el semáforo toma valores de “0” y “1”, es binario. En caso contrario es un “semáforo contador”.
  • Monitores: Estructuras de datos abstractas basados en los monitores o kernel de los S.O.

Los monitores tienen 4 componentes principales:

  • Inicialización: Contiene código a ser ejecutado.
  • Datos privados: Procedimientos que se utilizan desde dentro del monitor.
  • Métodos del monitor: Procedimientos que se pueden llamar desde fuera.
  • Cola de entrada: Hilos que llaman a algún método del monitor pero no tienen permiso para ejecutarse aún.

Algunos lenguajes

  • JavaScript
  • C#
  • Golang
  • Rust
  • Elixir
  • Haskell
<h1>Historia de algunos lenguajes de programación.</h1>

Década de los 40: primeras computadoras y lenguajes ensambladores.

La primer computadora no fue una maquina abstracta, eso es un concepto teórico, sin embargo, sabíamos que las computadoras épocas atrás, tenían tamaños enormes, ocupaban canchas de tennis, trabajaban con switches.

Hay distintos criterios para definir cuál fue la primer computadora y algunos autores mencionan que fue la EDSAC. Sus características:

  • Electrónica y digital.
  • Realiza 4 operaciones básicas.
  • Es programable.
  • Almacena programas y datos.

Las precursoras

Carecían de herramientas lingüísticas para ser programadas al nivel de la EDSAC.

Iniciaron con código máquina, llamados first-generation languages (1GL)

Lenguajes ensambladores

  • Representaciones simbólicas del lenguaje máquina.
  • Un programa “ensamblador” traduce las instrucciones.
  • Cada maquina tenía su propio lenguaje, había nula portabilidad.
  • Son llamados second-generation languages (2GL)

Década de los 50: Fortran y Algol

Los lenguajes de alto nivel son lenguajes abstractos, ignoran las características físicas de HW y se expresan como algoritmos. Third generation languages (3GL).Cuando hablamos de lenguaje ensamblador nos referimos a uno específico. Esta afirmación es:

Escribe tu comentario
+ 2