Lenguajes de Programación 1
Elementos de un lenguaje de
programación
Lenguajes de Programación 2
Que nos brinda el lenguaje
• a + b
• que tipos de valores brinda
• qué operaciones proporciona
• qué significan los símbolos a y b
• es legal sumar a y b
• expresiones y funciones
Lenguajes de Programación 3
Little Quilt
• Manipula objetos geométricos
– ancho
– altura
– patrón
• pueden estudiarse y visualizarse de manera
independiente de los constructores del
lenguaje.
Lenguajes de Programación 4
• Los primeros lenguajes de programación,
manejaban: enteros, reales y arreglos de
enteros y reales. Que podía ser visualizados
y estudiados de forma independiente de
cualquier lenguaje.
Lenguajes de Programación 5
• los dos objetos primitivos del lenguaje son
piezas cuadradas con los siguientes
patrones:
• los retazos se pueden girar y coser
Lenguajes de Programación 6
Reglas de retazos
• un retazo es una de las piezas primitivas, o
• se forma girando 90° un retazo hacia la
derecha, o
• se forma cosiendo un retazo a la derecha de
otro de igual altura
• ninguna otra cosa es un retazo
Lenguajes de Programación 7
• los retazos se pueden girar y coser
• los giros conducen a retazos diferentes
Lenguajes de Programación 8
Sintaxis de las expresiones que
denotan retazos
• La primera etapa en la construcción de un
lenguaje es asignar nombres a las piezas
primitivas y a las operaciones sobre retazos.
• Los objetos se llaman a y b ;las operaciones
son giro y costura.
Lenguajes de Programación 9
• Las expresiones complejas se construyen a partir
de expresiones más simples y las más simples
comienzan con los nombres a y b.
• E es una expresión si:
– E es a, o
– E es b, o
– E es giro (E1) y E1 es una expresión , o
– E es costura (E1 , E2) y E1 y E2 son expresiones
– Ninguna otra cosa es una expresión.
Lenguajes de Programación 10
Una versión BNF
• < expresión> ::= a
• | b
• | giro (<expresión>)
• | costura (<expresión>),
<expresión>)
Lenguajes de Programación 11
Semántica de las expresiones
• La semántica de las expresiones especifica
el retazo formado por la aplicación de una
expresión. ¿ qué retazo genera la siguiente
expresión ?
– costura (giro (giro ( b ) ), a)
– la respuesta se construye a partir de los retazos
generados por las sub-expresiones {28}
Lenguajes de Programación 12
Funciones definidas por el
usuario
• El universo de las expresiones se expande al
definir funciones de retazos a retazos.
• Las funciones permiten que los retazos se
especifiquen de manera más conveniente.
– girar a la izquierda (giro_iz)
– colocar un retazo encima de otro del mismo
ancho (apila) {29}
Lenguajes de Programación 13
• De esta forma las operaciones pueden
usarse sin que se necesite pensar:
– fun giro_iz (x) = giro(giro(giro(x)))
– fun apila (x,y) = giro_iz (costura (giro (y), giro
(x)))
– ahora se usa giro_iz (E) para cualquier
expresión y puede usarse para declarar otras;
como es el caso de apila.
Lenguajes de Programación 14
Declaraciones locales
• Las expresiones de asignación o
asociaciones de asignación permiten que
las declaraciones aparezcan dentro de las
expresiones.
– let <declaraciones> in <expresión> end
Lenguajes de Programación 15
• Las expresiones de asignación permiten el
uso de nombres en los lenguajes de
programación– let fun giro_iz (x) = giro(giro(giro(x)))
– fun apila (x,y) = giro_iz (costura (giro (y),
giro (x)))
– in apila (giro_iz (b), giro (b))
– end
Lenguajes de Programación 16
Nombres definidos por el usuario
para valores
• las declaraciones locales convienen cuando se
escriben expresiones grandes en términos de otras
más simples
– val <nombre> = <expresión>
– asigna nombre a una expresión
• y así la declaración de valores se usa junto con las
declaraciones locales
Lenguajes de Programación 17
• let val x = E1 in E2 end
• significa las apariciones del nombre x en E2
representan el valor de E1
• se puede usar cualquier otro nombre en
lugar de x, sin que cambie el significado de
la expresión.
Lenguajes de Programación 18
• let val sup_izq = giro_izq (b)
• val inf_der = giro (b)
• in
• apila (sup_izq, inf_der)
• end
• {31}
Lenguajes de Programación 19
Notaciones de expresiones
• Operador binario: necesita dos operandos
– notación infija
• a+b
– notación prefija
• +ab
– notación posfija
• ab +
Lenguajes de Programación 20
Propiedad asociativa y
precedencia
• En notación infija los operadores aparecen entre
sus operandos
– + b *c
– la división y la multiplicación tienen precedencia sobre
la suma y la resta.
– Sin reglas de precedencia, los paréntesis serían
necesarios
– los operadores con la misma precedencia se agrupan de
izquierda a derecha
– 4-2-1 = 1
Lenguajes de Programación 21
• Operadores
– asociativo a la izquierda: si las sub-expresiones que
contienen apariciones múltiples del operador se
agrupan de izq a der; 4-2-1 = (4-2) -1 = 1. Porque la
resta de la izq es la primera en efectuarse.
• +, -, * y /
– asociativo a la derecha: si las sub-expresiones que
contienen apariciones múltiples del operador se
agrupan de der a izq; 234;
• 3 a la 4 = 81
• 2 a la 81
Lenguajes de Programación 22
Declaraciones y aplicaciones de
funciones
• Una vez declarada una función se puede
aplicar como un operador
• funciones como correspondencias
– función es total
– función es parcial
Lenguajes de Programación 23
Función total
• Si se asocia un elemento del conjunto B con
cada elemento del conjunto A; siendo A el
domino y B el contra dominio.
• A B, para el conjunto de todas las
funciones de A en B. Si f hace corresponder
a y b, escribimos f(a) = b y b se conoce
como el valor de f en a.
Lenguajes de Programación 24
Función parcial
• Una función es parcial si, por cada a en su
domino A, se tiene que f(a) = b, para
alguna b en B, o f(a) se encuentra indefinida
debido a que no existe una b tal que b = f(a)
Lenguajes de Programación 25
Cómo se calcula el valor de f en a
• Es posible definir una función
– enumeración explícita de sus valores para cada
elemento de su dominio.
• Sucesor (0) = 1
• Sucesor (1) = 2
• Sucesor (2) = 3
• Sucesor (3) = 4
• ...
Lenguajes de Programación 26
• g(x) es el entero n 0 más grande tal que
n2 x
• esta regla no nos indica explícitamente
cómo calcular el valor de g en x
Lenguajes de Programación 27
Funciones como algoritmos
• En cualquier lenguaje de programación una función va de
la mano con un algoritmo para calcular el valor de la
función en cada elemento de su dominio.
• Las declaraciones de funciones tienen 3 partes:
– el nombre de la función
– los parámetros de la función y
– una regla para calcular un resultado a través de los parámetros
Lenguajes de Programación 28
• fun <nombre> (<parámetros - formales>) =
<cuerpo>;
– ejem: fun sucesor (n) = n + 1;
• la notación prefija es la regla para la
aplicación de funciones declaradas:
– <nombre> (<parámetros-actuales>)
– sucesor (2+3) {notación infija}
Lenguajes de Programación 29
• Nombres que se utilizan para designar a los
parámetros:
– parámetro = parámetros formales
– argumento = parámetros actuales
Lenguajes de Programación 30
Evaluación más interna
• Se calcula como sigue:
– se evalúan las expresiones en <parámetros -
actuales>,
– se substituyen los resultados en los parámetros
formales del cuerpo de la función,
– se evalúa el cuerpo de la función y
– se devuelve el valor de la función como
respuesta
Lenguajes de Programación 31
• Ejemplo:
– sucesor (2 + 3)
• se activa activa + para evaluar +(2,3)
• se devuelve el resultado 5 de +
• se activa el sucesor (5) y
• se devuelve la respuesta 6
• la técnica de evaluar los argumentos antes del
cuerpo se conoce también como técnica de
invocación por valor
Lenguajes de Programación 32
Evaluación selectiva
• Si <condición> entonces <expresión>1 otro
<expresión>2
• condición da como resultado
verdadero/falso
• expresiones booleanas
• sólo se evalúa una de las expresiones
dependiendo del valor de la condición
falso/verdadero
Lenguajes de Programación 33
Funciones recursivas
• Una función es recursiva si su cuerpo
contiene una aplicación de f
• f es recursiva si f puede activarse a sí misma
• Existen dos tipos de recursión
– lineal
– cola
Lenguajes de Programación 34
Recursión lineal
• Si la activación f(a) de f puede iniciar como
máximo una nueva activación de f.
• ejemlo:
• fun factorial (n) =
– si n = 0 entonces 1 otro n*factorial (n-1);
Lenguajes de Programación 35
• La evaluación de una función recursiva
lineal tiene dos fases:
– una fase de activación, en la cual se inician las
nuevas activaciones, y
– una fase de solución, en la cual el control
regresa de las activaciones con una modalidad
última entrada - primera salida
Lenguajes de Programación 36
Función factorial líneal
• Ejemplo:
– f(3) = 3 * f(2)
– = 3 * (2*(f (1))
– = 3 * (2*(1*f(0)))
– = 3 * (2*(1*1))
– = 3 * (2*1)
– = 3 *2
– = 6
Lenguajes de Programación 37
Recursión de cola
• si una función recursiva puede ser eficientes
si se puede implementar con recursión de
cola
• si devuelve un valor sin necesidad de
recursión o si devuleve simplemente el
resultado de una activación recursiva
Lenguajes de Programación 38
• ejemplo:
– fun g (n,a) =
– si n = 0 entonces a otro g (n-1, n*a)
– a si n = 0
– g (n,a) =
– g(n-1, n*a) en caso contrario
Lenguajes de Programación 39
• g (3,1)
• si 3 entonces 1 otro g(3-1, 3*1)
• g(3,1) = g(2,3) = g(1,6) = g (0,6) = 6
Lenguajes de Programación 40
g(3,1) = g(2,3)
g(2,3) = g(1,6)
g(1,6) = g(0,6)
g(0,6) = 6Función factorial con
recursión de cola
Lenguajes de Programación 41
• Todo el trabajo de una función lineal con
recursión de cola se realiza en la fase de
activación, cuando se inician las
activaciones nuevas; siendo la fase de
solución trivial debido a que el valor
calculado por la activación final se
convierte en el valor de toda la evaluación.
Lenguajes de Programación 42
• En el caso de f(3) = 3 * f(2)
• la multiplicación se realiza después de que
el control regresa de la activación de f(2).
Lenguajes de Programación 43
Ambito léxico
• EL cambio de nombre no tiene efecto en el
valor de una expresión, siempre y cuando
cambio es consistente
• la re-asignación de nombres se especifica
con precisión mediante la presentación de
una noción de variables locales o acotadas
Lenguajes de Programación 44
• El principio de re-asignación de nombres es
la base para la regla de ámbito léxico, que
ayuda a determinar el significado de los
nombres en los programas.
• fun sucesor (x) = x +1;
• fun sucesor (n) = n +1;
Lenguajes de Programación 45
• surgen ciertas sutilezas cuando una declaración de
función puede hacer referencia a nombres no
locales, es decir , a nombres que no son
parámetros formales, por ejemplo el resultado de
la función sumay depende del valor de y:
• fun sumay (x) = x + y
• como y no es local algún contexto determina su
valor
Lenguajes de Programación 46
• Las reglas de ámbito léxico usan el texto del
programa que rodea a la declaración de la
función para determinar el contexto en el
cual se evaluarán los nombres no locales.
• El texto del programa es estático, a
diferencia de la ejecución, así que tales
reglas se conocen también como reglas de
ámbito estático.
Lenguajes de Programación 47
Utilizaremos let ...
• Para comprender las reglas de ámbito
léxico:
• let val x = 2 in x + x end
• a val se le conoce como una asociación de x
Lenguajes de Programación 48
• let val x = E1 in E2 end
• que todas las apariciones de x en E2 se
encuentran dentro del ámbito de esta
asociación
• el valor de una expresión no se altera si se
cambia de variable
• let val z = E1 in E2 end
Lenguajes de Programación 49
• Caso de asociaciones anidadas de la misma
variable
• let val x = 2 in val x = x + 1 in x *x end end
Lenguajes de Programación 50
• Se aplica una reasignación de nombres de la
asociación más interna
• let val x = 2 in val y = x + 1 in y *y end end
Lenguajes de Programación 51
Tipos
• El tipo de una expresión nos indica los
valores que esta puede representar y las
operaciones que pueden aplicarse
• es posible sumar los enteros y no los
booleanos
Lenguajes de Programación 52
• un principio de diseño de lenguajes de uso extendido es:
toda expresión debe tener un tipo único y lo que
proporciona un mecanismo para clasificar expresiones
• la única estructura de los datos dentro de la máquina es su
disposición física en memoria
• mismas secuencias de bits pueden ser identificada de
manera diferente por distintos programas:
– entero,
– secuencia de caracteres, o
– como instrucción de máquina
Lenguajes de Programación 53
• Por ejemplo el patrón de bits para el carácter @,
puede ser el mismo patrón de bits que el del
número 64.
• Tal flexibilidad es una característica de las
máquinas de propósito general y una invitación a
la equivocación de los programadores ya que las
máquinas no verifican que que las expresiones se
utilicen como se definen
Lenguajes de Programación 54
• Los tipos en los lenguajes de programación
surgen de necesidades en diferentes niveles:
– nivel de máquina
– nivel de lenguaje
– nivel de usuario
Lenguajes de Programación 55
Nivel de máquina
• Los valores proporcionados directamente por una
máquina pueden clasificarse en tipos básicos:
enteros, caracteres, reales y booleanos. Debido a
que la instrucción de máquina para sumar enteros
suele ser diferente que la instrucción para sumar
reales; los compiladores necesitan información
sobre el tipo para generar expresiones en código
de máquina.
Lenguajes de Programación 56
Nivel de lenguaje
• Además de los tipos básicos, los lenguajes
proporcionan tipos estructurados: arreglos,
registros y listas; que se construyen a partir de
tipos más simples. Los tipos estructurados se usan
para definir las estructuras de datos que
manipulará un programa. El constructor de tipos
es un constructor del lenguaje para definir un tipo
estructurado.
Lenguajes de Programación 57
Nivel de usuario
• Los tipos definidos por el usuario son
grupos de datos con nombres y funciones.
Son los TAD’s que permiten al usuario
enriquecer el lenguaje definiendo tipos que
se adaptan al problema que debe resolverse.
Lenguajes de Programación 58
Tipos estructurados
• A través de la teoría de conjuntos se presentan los
tipos estructurados
• se supone la existencia de algunos conjuntos
básicos:
– bool {verdadero, falso}
– color {rojo, blanco, azul}
– entero los enteros
– caracteres un conjunto de caracteres
– real un conjunto de números reales
Lenguajes de Programación 59
• Y de tres constructores de conjuntos:
– producto
– función
– secuencia
• la descripción de cada constructor consata de tres
partes:
– la sintaxis
– los elementos del conjunto construido, y
– algunas operaciones para examinar la estructura de los
elementos del conjunto construido
Lenguajes de Programación 60
Producto
• El producto A x B de dos conjuntos contiene pares
ordenados que se escriben como (a,b)
• así el conjunto bol x color tiene seis elementos:
– {(verdadero, rojo), (verdadero, blanco), (verdadero,
azul), (falso,rojo), (falso, blanco), (falso, azul)}
• el conjunto enero x entero
– contiene pares de enteros
Lenguajes de Programación 61
• Asociados con el constructor x se encuentran las
operaciones:
– primero y segundo
– ejemplo : primero (verdadero, azul) = verdadero
– ejemplo : segundo (verdadero, azul) = azul
• operaciones se llaman funciones de proyección
• Un producto de n conjuntos A1xA2 x ...x An
– tuplas (a1,a2, ... an) donde ai es un elemento del conjunto
Ai
Lenguajes de Programación 62
• Función: el conjunto de todas las funciones del
conjunto A al conjunto B se denota:
– A B aplicación
– la única operación asociada con el conjunto A B es la
aplicación toma una f de A B y un elemento de a
de A y devuelve un elemento de b de B.
– La notación usual para la aplicación de f a a es f(a)
Lenguajes de Programación 63
• Ejemplo : el conjunto color bool
– consiste en todas las funciones del conjunto color
aplicadas al conjunto bool
– como el conjunto color tiene tres elementos y bool dos,
existen 23 = 8 de esas funciones, una de ellas es la
función que satisface las siguientes igualdades:
• f(rojo) = falso
• f(blanco) = falso
• f(azul) = verdadero
Lenguajes de Programación 64
• Por convención el constructor producto (x) tiene
mayor precedencia que el constructor d función
aplicación () de tal forma que:
– entero x entero entero
• es el conjunto de todas las funciones de pares de enteros a
enteros
• dentro de estas funciones se encuentran (+, -, *); para
enteros)
– ejemplo: la función + aplicada al par (2, 3) le hace corresponder
el entero 5.
Lenguajes de Programación 65
• Ejemplo el conjunto entero x entero bool
– es el conjunto de todas las funciones de pares
de enteros a () booleanos
– estas funciones pueden ser los operadores
relacionales (,,,,,) para comparar
enteros.
Lenguajes de Programación 66
• Secuencias: la cerradura de Kleene o
cerradura estrella de un conjunto A, que se
denota con A*, esta constituida por todas las
tuplas que pueden formarse con los
elementos de A
– ejemplo color* es el conjunto
• {( ),(rojo), (blanco), (azul), (rojo, rojo), (rojo,
blanco), (rojo, azul), ...}
Lenguajes de Programación 67
• La cerradura Kleene se relaciona con los
constructores de listas en los lenguajes de
programación funcionales, donde una lista es una
secuencia finita de elementos.
– Operaciones de listas: nula (sabes si es nula), cabeza
(extrae el primer elemento), cola (extrae el resto de los
elementos)
Lenguajes de Programación 68
• Sistemas de tipos: en un lenguaje es el conjunto de
reglas para asociar tipos a expresiones del lenguaje
– el sistema de tipos rechaza una expresión si esta no se
encuentra asociada a un tipo
– ejemplo FORTRAN, donde una expresión es tanto una
variable como una constante o se forma aplicando los
operadores: +, -, * o / a dos sub - expresiones. El tipo
de una expresión es entero o real
Lenguajes de Programación 69
• Una expresión tiene tipo ssi se cumple una de las
siguientes reglas:
– los nombres de variables que comienzan entre I ..N son
de tipo entero. Todos los demás nombres tienen tipo
real. Ejem. Contador es de tipo real
– Un número tiene tipo real si contiene un punto decimal;
en caso contrario tiene tipo entero
– la clasificación de variables y constantes se extiende a
las expresiones
Lenguajes de Programación 70
• Si las expresiones E y F tienen el mismo
tipo entonces:
– E + F
– E - F
– E * F
– E / F
• son expresiones del mismo tipo
Lenguajes de Programación 71
• Y que sucede cuentan con tipos distintos ..
– Al no cumplir las reglas se rechaza la expresión
• La principal diferencia entre el sistema de tipos de
FORTRAN y Modula - 2 y C y otrs lenguajes
– es la declaración explícita, que especifiquen el tipo de
una varaible
Lenguajes de Programación 72
• En el centro de todos los sistemas de tipos
se encuentra la siguiente regla para la
aplicación de funciones:
– el símbolo es un constructor de función, de
modo que S T es el tipo de una función que
va del tipo S al tipo T:
• Si F es una función de tipo S T y a tiene tipo S,
entonces f(a) tiene tipo T.
Lenguajes de Programación 73
Variantes de la regla
• Operadores aritméticos: existe una regala asociada
a cada operador op que especifica una expresión E
op F en términos de los tipos E y F
– si E y F son de tipo entero, entonces
E mod F es también de tipo entero
– si mod es una función de tipo entero x entero, y
el par (E,F) es de tipo entero x entero, entonces
mod (E,F) tiene tipo entero
Lenguajes de Programación 74
• Sobrecarga: los operadores familiares
como + y *; tienen sobrecarga, es decir
poseen significados diferentes en diferentes
contextos:
– +: entero x entero entero
– +: real x real real
Lenguajes de Programación 75
• Reglas para re-definir un operador
sobrecargado:
– si E y F son de tipo entero entonces
E + F es de tipo entero
– si E y F son de tipo real entonces
E y F son de tipo real
Lenguajes de Programación 76
• Coerción: el sistema de tipos original de
FORTRAN rechazaba expresiones como X
+ I y 2 * 3.142, esta restricción se eliminó
en versiones posteriores ...la expresión
anterior es manejada como 2.0 * 3.142; lo
que hace que el entero 2 se convierta en real
antes de la multiplicación (IMPLICIT
NONE).
Lenguajes de Programación 77
• Polimorfismo: esta función tiene un tipo
parametrizado, conocido también como tipo
genérico.
Lenguajes de Programación 78
Los tipos se usan para la
verificación de errores
• la verificación de Tipos asegura que la de un
programa se apliquen de manera apropiada
• el propósito de la verificación es prevenir errores,
si un programa se ejecuta sin errores de tipo, tiene
seguridad de tipos.
• los programas se verifican estáticamente, hasta
donde es posible; sólo una vez durante la
traducción del texto fuente
Lenguajes de Programación 79
• La verificación dinámica se realiza insertando
código extra en el programa para encontrar errores
inminentes.
– El código extra ocupa espacio y tiempo, lo que significa
que es menos eficiente en tiempo de ejecución.
– Los errores pueden esconderse hasta que son
alcanzados pro la ejecución.
– Los programas grandes suelen tener porciones que se
ejecutan rara vez, así que se puede utilizar mucho
tiempo antes que la verificación dinámica lo detecte.
Lenguajes de Programación 80
• La verificación estática es efectiva y la dinámica
muy cara. Así que la mayoría de los compiladores
sólo hacen verificación estática.
• Las propiedades que dependen de valores
calculados como en tiempo de ejecución como la
división por cero, o los índices de arreglos que se
encuentran dentro de los límites; se verifican muy
rara vez.
Lenguajes de Programación 81
• los términos estricto y no estricto se refiere a la
efectividad con la cual un sistema de tipos evita
errores
• un problema que se puede presentar con un
sistema verificador de tipo estricto es que
rechazará muchos programas
• lo ideal es que un lenguaje tenga verificación
estática usando un sistema de tipos poderoso y
estricto