You are on page 1of 6

L.A.M.M.

- Uned Denia

Tema 3: Principios de diseo de los lenguajes

ndice de contenidos

Ejercicio 3.2:...................................................................2
Ejercicio 3.3:................................................................................................................................2
Ejercicio 3.4:................................................................................................................................3
Ejercicio 3.8:................................................................................................................................3
Ejercicio 3.10:..............................................................................................................................4
Ejercicio 3.14:..............................................................................................................................4
Ejercicio 3.15:..............................................................................................................................4
Ejercicio 3.21:..............................................................................................................................5
Ejercicio 3.22:..............................................................................................................................6

1/6

L.A.M.M. - Uned Denia


Ejercicio 3.2:
De sus propios ejemplos para diferenciar los conceptos de ortogonalidad, generalidad y uniformidad.
Generalidad:
Al pasar arreglos multidimensionales a una funcin, el tamao del ndice puede quedarse sin
especificar, pero los tamaos siguientes deben obligatoriamente ser especificados.
voidf(intx[],inty[][10])/*correcto*/.
voidg(inty[][])/*incorrecto!*/.
La razn es que C permite punteros a los arreglos, por ello y++ debe avanzar a la siguiente posicin
de memoria donde se encuentre y en cualquiera de las funciones f o g arriba mencionadas.
En f, el compilador reconoce la interpretacin de y++ como y+10*sixeof(int), pero en g no tendr ni
idea de cuanto debe incrementar y. as, los tipos de arreglo incompletos son incompatibles con los
punteros.
La verificacin de igualdad == de hecho no es lo suficientemente general. Las asignaciones se
pueden aplicar a cualquier cosa excepto a los arreglos, pero la verificacin de igualdad solo se puede
aplicar a tipos escalares:
struct{inti;doubler;}x,y;
...
x=y;/*correcto*/.
if(x==y).../*incorrecto*/.
Los arreglos carecen de generalidad en C porque sus ndices deben ser enteros y comenzar siempre
por 0.
La declaracin switch en C restringe la validacin de expresiones a enteros, y tambin permite
nicamente un valor constante por cada case. Por ello, la declaracin switch no es lo bastante
general.
Uniformidad:
El operador coma "," no tiene uniformidad semntica en C. En una expresin como: y=(x++, x+1),
garantiza la evaluacin en orden de izquierda a derecha, mientras que en una llamada como: y=f(x+
+, x+1), no se garantiza que el primer argumento sea evaluado antes que el segundo.
El punto y coma ";" no se utiliza uniformemente como un terminador en C: se utiliza al terminar
declaraciones de variables y definicin de tipos, pero no se puede utilizar para terminar una funcin.
Int x; se requiere el punto y coma.
Int f(void) {}; error. No se requiere el punto y coma.
Ortogonalidad:
Las funciones pueden devolver estructuras y uniones, pero no arreglos. Es esto ortogonalidad o
generalidad? Actualmente esto es falso. Mientras que es cierto que las funciones no pueden
declararse para que devuelvan un arreglo de tamao fijo, utilizando un puntero a un arreglo se permite
que dicho puntero sea devuelto. As, la siguiente funcin f es incorrecta en C, pero g es correcta.
typedefinttipoArreglo[10];
tipoArreglof(void)
{inty[10];returny;}
int*g(void)
{inty[10];returny;}

Ejercicio 3.3:
En Ada existe un constructor loop exit, y en PL/I existe un constructor similar loop break. Existe
algn constructor similar en C o en Java? Es ste un ejemplo de algunos de los principios de diseo?
En C y Java, puede salirse de cualquier bucle loop utilizando la palabra clave break, la palabra clave
exit es utilizada para la terminacin del programa.
Desafortunadamente, la palabra clave break tambin se utiliza en la declaracin switch para prevenir
los cuelgues, y esto lleva con frecuencia al uso errneo del break para salir de la declaracin if en
diferentes puntos, a menudo con consecuencias desagradables.
Por ello, la declaracin break no tiene uniformidad semntica en C ni en Java.

2/6

L.A.M.M. - Uned Denia

Ejercicio 3.4:
En Java pueden asignarse los enteros a las variables reales, pero no viceversa. Qu principio de diseo
viola lo anterior? En C esta restriccin no existe. Qu principio de diseo viola lo anterior?
Esto es falta de ortogonalidad, pues es una interaccin entre asignaciones y tipos de datos relativos
a las asignaciones.
Podra incluso verse como una falta de uniformidad, aunque realmente estamos hablando de una
interaccin dentro de una sola construccin, ms que de una comparacin de construcciones.
No puede verse como una falta de generalidad, puesto que no tiene ningn sentido que las
asignaciones sean tan generales como para aplicarse a todos los casos (la asignacin debe
aplicarse solamente cuando los tipos de datos son comparables en un cierto sentido).
C permite la asignacin de un real a un nmero entero (con un truncamiento silencioso o redondeo),
pero esto es altamente cuestionable, puesto que de esta forma se pierde parte de la informacin, y
su comportamiento exacto es confuso dentro del cdigo mismo, pudiendo llegar a una ejecucin
incorrecta.
Uno podra tambin llamar a esto una falta de uniformidad o una falta de ortogonalidad en C: la
asignacin no trabaja de la misma manera, con una interaccin especial (truncamiento) ocurriendo
para tipos de datos especficos.

Ejercicio 3.8:
Debe requerir un lenguaje la declaracin de las variables? Lenguajes como Fortram y Basic permiten la
utilizacin de nombres de variables sin declaraciones, en tanto que C, Java y Ada requieren que todas las
variables se declaren. Analice, desde el punto de vista de la legibilidad, la capacidad de escritura, la
eficiencia, la seguridad y la expresividad, el requisito de que las variables deban ser declaradas.
Legibilidad. Requerir la declaracin de variables fuerza al programador a documentar sus
expectativas con respecto a los nombres de variables, tipos de datos, y alcance de los mismos (la
regin del programa donde ser aplicable la variable). De esta forma, el programa llega a ser mucho
ms legible para el programador y para otros.
Capacidad de escritura. Requerir la declaracin de variables puede disminuir la capacidad de
escritura en su sentido ms directo, puesto que un programador no puede utilizar simplemente
variables segn las vaya necesitando, pero debe escribir declaraciones en los lugares apropiados
para evitar mensajes de error. Esta carga creciente en el programador puede incrementar el tiempo de
programacin.
Por otra parte, sin declaraciones no puede haber variables locales, y el uso de variables locales puede
aumentar la capacidad de escritura permitiendo que el programador reutilice nombres sin la
preocupacin de referencias no locales. Forzar al programador a planear el uso de variables puede
tambin mejorar la capacidad de escritura a largo plazo.
Eficacia. Como vimos, legibilidad y capacidad de escritura pueden ser vistas como temas de eficacia
desde el punto de vista del mantenimiento y de la ingeniera del software, as que los comentarios
sobre esas ediciones tambin pueden aplicarse aqu en ese sentido.
El uso de declaraciones puede tambin permitir una puesta en prctica ms eficiente del programa.
Sin declaraciones deberemos utilizar mecanismos de acceso menos eficientes que usan punteros.
Tambin, el programador puede utilizar declaraciones para especificar el tamao exacto que se
necesita de la variable (por ejemplo Short int o Long int).
Restringiendo el alcance con el uso de variables locales puede tambin ahorrar memoria permitiendo
la desasignacin automtica de variables.
Nota, sin embargo, FORTRAN es un lenguaje muy eficiente en trminos de velocidad de la ejecucin,
as que no es siempre cierto que requerir declaraciones mejore la velocidad de ejecucin. Tambin, la
velocidad de la traduccin se puede disminuir por el uso de declaraciones, puesto que una mayor
informacin debe mantenerse en las tablas para no perder de vista las declaraciones.
Seguridad. Requerir declaraciones realza la capacidad del traductor de seguir el uso de variables y
de informar de los errores. Un ejemplo claro de esto aparece en la diferencia entre ANSI C y el Unix C.
El C moderno no requiri que los parmetros a las funciones sean declarados con los prototipos de

3/6

L.A.M.M. - Uned Denia


funcin. (Las declaraciones de parmetros estn relacionadas y puede verse como el mismo
concepto, Mientras que no ocurre lo mismo con la declaracin de variables). Esto signific que el
compilador C no poda garantizar que una funcin fuera llamada con el nmero o tipo de parmetro
apropiado. Tales errores aparecieron solamente como desplomes o valores basura durante la
ejecucin de programa. El uso de las declaraciones de parmetro en ANSI C mejor enormemente la
seguridad del lenguaje C.
Expresividad. La expresividad puede verse reducida si se requiere la declaracin de variables,
puesto que no pueden ser utilizadas de forma arbitraria.

Ejercicio 3.10:
El punto y coma se utiliz como un ejemplo de una no uniformidad en C++. Analice el uso del punto y coma
en C. Es su utilizacin totalmente uniforme?
C tiene los mismos problemas con el punto y coma que C++, de hecho, C++ lo ha heredado de C. As,
en C debe escribirse un punto y coma despus de cada declaracin struct:
struct X { int a; double b; } ; /* aqu se requiere el punto y coma*/
Pero nunca despus de una declaracin de una funcin:
int f( int x) { return x + 1; } /* no se pone el punto y coma */
La razn es que C permita que las variables fueran declaradas junto con la declaracin de tipos:
struct X { int a; double b; } x;
/* x es una variable del tipo struct X */
Adems de esta no uniformidad del uso del punto y coma, C tiene al menos otra: el punto y coma se
utiliza como separador dentro de un bucle for, en lugar de usarse como terminacin.
for (i = 0; i < n; i++ /* no se pone el punto y coma al final! */ )

Ejercicio 3.14:
Dos puntos de vista opuestos sobre la declaracin de los comentarios en un lenguaje de programacin son
representados por Ada y por C: en Ada, los comentarios empiezan con guiones adyacentes y terminan con
el final de una lnea o rengln:
- - Esto es un comentario en Ada.
En C, los comentarios empiezan con "/*" y siguen hasta un "*/" coincidente:
/* Esto es un comentario en C */
Compare estas dos caractersticas de comentarios con respecto a la legibilidad, capacidad de escritura y
confiabilidad. C++ agreg una convencin de comentarios (dos diagonales hacia delante "//") similares a las
de Ada. Por qu C++ no utiliz exactamente la misma regla convencional de Ada?
Legibilidad. La notacin de comentarios en Ada es difcil de confundir con otras construcciones, y los
indicadores de comentario estn siempre presentes en cada lnea de comentario. Por el contrario, los
caracteres de comentarios en C pueden estar separados, as que puede no ser fcil determinar cul
es un comentario y cul no lo es. Los comentarios de C pueden tambin ser confusos, puesto que " / "
y " * " son operadores aritmticos:
2 / 3 /* esto es un comentario */
2 / 3 / * esto es un error */
Los comentarios jerarquizados tambin pueden presentar problemas de legibilidad en C:
/ Un comentario
/ un comentario jerarquizado
...
Pero solo un cierre de comentario /

Ejercicio 3.15:
En el captulo 4 observamos que el operador "+" es asociativo por la izquierda, de modo que en la expresin
a + b + c se calcula primero a + b y luego se suma c. Sin embargo, en la seccin 7.1 dijimos que una
expresin a + b poda realizarse calculando primero b y despus a. Esto constituye una contradiccin? Su
respuesta es aplicable al operador de sustraccin? Razone su respuesta.
El principio de localidad implica que los constructores del lenguaje deban estar disponibles para las
variables para que puedan declararse cerca de donde se van a utilizar, y tambin permitir la
restriccin de acceso a las variables en reas del programa donde no se soporta su uso. Hay
diversos constructores en C que utilizan el principio de localidad.
Primero, C permite bloques que contengan declaraciones (encerrados por llaves {}), de esta forma
se permite la declaracin de variables locales dando mayor libertad. Por ejemplo, si una variable

4/6

L.A.M.M. - Uned Denia


temporal es solamente necesaria en algunas lneas del cdigo, entonces se puede escribir en C:
{inttemp=x;
x=y;
y=temp;
}
y temp se restringe a la regin dentro de las llaves. En Ada, C++, y Java esto tambin est
permitido, y (ms recientemente) en C tambin se permite que las declaraciones ocurran
dondequiera dentro de un bloque (en Ada no).
C tambin permite que las variables locales sean declaradas estticas, que permite la asignacin
esttica mientras que preserva la restriccin del alcance. El atributo esttico tambin se puede
aplicar a las variables externas, donde se restringe el acceso al compilador.
Esto tambin promueve el principio de localidad. Por otra parte, C permite solamente declaraciones
globales de funciones -- no se permite ninguna funcin local. As, una funcin que se utiliza
solamente en una pequea parte del programa deber ser declarada global. Esto compromete el
principio de localidad.
C tambin carece de un mecanismo para distinguir claramente qu debe y no debe ser visible entre
archivos compilados por separado.
C++ y Java ofrecen la clase, que permite un control mucho ms fino sobre el acceso.
Ada tiene la construccin package, que permite tambin el control de acceso (sin embargo no tanto
como C++ y Java).

Ejercicio 3.21:
En la mayora de las implementaciones de lenguajes, el tipo de dato entero tiene un tamao fijo, lo que
significa que el tamao mximo de un entero es dependiente de la mquina. En algunos lenguajes como
Scheme, sin embargo, los enteros pueden ser de cualquier tamao, convirtindose as en independientes
de la mquina. Analice las ventajas y desventajas de hacer que estos enteros de "precisin infinita"
resulten un requisito de una definicin del lenguaje. Se pueden o no implementar tambin nmeros reales
de precisin infinita? Puede hacerse que los nmeros reales sean independientes de la mquina? Analice
su respuesta.
Una ventaja obvia de nmeros enteros con precisin arbitraria es que libera el comportamiento de
los enteros de cualquier dependencia de representacin de nmeros enteros, incluyendo la
eliminacin de la necesidad de considerar desbordamiento en la definicin del lenguaje (vase el
ejercicio 1.10).
La desventaja es que el tamao de la memoria necesario para un nmero entero no es esttico
(fijado antes de la ejecucin), y por lo tanto la memoria para un nmero entero debe ser asignada
dinmicamente. Esto tiene consecuencias serias para un lenguaje como C. Por ejemplo, en el
cdigo siguiente;
struct X { int i; char c; } x;
...
x.i = 100;
x.c = 'C';
...
x.i = 100000000000000000;
...
la asignacin de memoria para x en la segunda asignacin a x.i significa que x.b debe tambin ser
reasignada y copiada, a menos que se utilice la indireccin. De hecho, una aproximacin razonable
sera representar variables de enteros como punteros y automticamente asignarlos y
desasignarlos. Esto significa que el sistema debe llegar a ser completamente dinmico (con un
colector de basura), substancialmente complicando la puesta en prctica del lenguaje. Los
operadores aritmticos, tales como adicin y multiplicacin, tambin se hacen mucho menos
eficientes, puesto que se debe utilizar un algoritmo software en lugar de operaciones de hardware.
En principio, un nmero real con precisin arbitraria se puede representar de la misma forma que un
nmero entero, con la adicin de una posicin distinguida (la posicin de la coma). Por ejemplo,
33.256 se podra representar como (33256.2), el 2 expresando el hecho de que la coma est
despus del segundo dgito. Los mismos comentarios se sostienen tanto para los nmeros reales
como para los nmeros enteros.
Sin embargo, hay otra complicacin: mientras que las operaciones de un nmero entero dan lugar
siempre a un nmero finito de dgitos, las operaciones con nmeros reales pueden dar lugar a

5/6

L.A.M.M. - Uned Denia


muchos dgitos (considere el resultado de 1.0/3.0 o el sqrt (2.0)). Cuntos dgitos deben presentar
estos resultados? Cualquier respuesta va a tener que ser arbitraria. Por esta razn, los sistemas con
nmeros enteros de precisin arbitraria ponen a menudo restricciones en la precisin de nmeros
reales. (Scheme llama a cualquier nmero con una coma inexacto, y en el momento en que un
entero se convierte a real, se vuelve inexacto, y algunos de sus dgitos se pueden perder.)

Ejercicio 3.22:
Brooks [1996] lista cinco principios bsicos de diseo:
(a) Disee, no improvise.
(b) Estudie otros diseos.
(c) Disee de arriba hacia abajo.
(d) Conozca el rea de aplicacin.
(e) Haga iteraciones.
Explique qu significa cada uno de estos trminos en funcin del diseo del lenguaje de programacin.
1. Disee, no improvise. Bsicamente significa: Tenga algunas metas de diseo y un plan para
llevarlas a cabo. Un conjunto de metas claras result ser de gran valor en el diseo de C++; si
Stroustrup tuvo un plan para conseguirlo est menos claro, debido especialmente a que una de las
metas era permitir la ampliacin del lenguaje basndose en la experiencia prctica.
2. Estudie otros diseos. Conozca las mejores y las peores caractersticas de otros lenguajes y
seleccione una mezcla apropiada de ellas.
3. Disee de arriba hacia abajo. Para el diseo de un lenguaje de programacin, esto significa:
comience con metas y criterios lo ms generales posibles, seleccione las caractersticas que
resolvern estas metas y finalmente refine las descripciones de las caractersticas en un lenguaje
de programacin real.
4. conozca el rea de aplicacin.
5. Haga iteraciones. Esto significa: No intente tomar todas las decisiones de diseo inmediatamente,
sino acumlelas cuidadosamente en una base de datos, ampliando las metas poco a poco hasta el
objetivo y las conseguir.

6/6

You might also like