• No se han encontrado resultados

Lenguajes de Programación I

N/A
N/A
Protected

Academic year: 2021

Share "Lenguajes de Programación I"

Copied!
20
0
0

Texto completo

(1)

Lenguajes de Programación I

Control de Flujo - Expresiones

Ernesto Hernández-Novich <[email protected]>

(2)

Control de Flujo Expresiones Consideraciones de Eficiencia

Definición

ElControl de Flujo es fundamental para la mayoría de los

modelos de cómputo, pues establece elorden en que debe

(3)

Organización de los Mecanismos

Secuenciación (Sequencing): orden específico,

usualmente el de aparición en el programa.

Selección (Selection): se escoje entre dos o más

instrucciones según alguna condición a tiempo de ejecución.

Iteración (Iteration): un fragmento de código se ejecuta

de manera repetida bien sea un número de veces o hasta cumplirse determinada condición a tiempo de ejecución.

Abstracción procedimental (Procedural Abstraction):

una colección de construcciones de control se encapsula como una unidad, sujeta a parametrización.

(4)

Control de Flujo Expresiones Consideraciones de Eficiencia

Organización de los Mecanismos

Recursión (Recursion): una expresión se define en

términos de si misma directa o indirectamente.

Concurrencia (Concurrency): dos o más fragmentos de

programa se ejecutan/evalúan al mismo tiempo.

No determinismo (Nondeterminacy): el orden o

escogencia de instrucciones y expresiones no es especificado deliberadamente.

Dejaremos los Procedimientos y la Concurrencia para más adelante.

(5)

Expresiones

Una expresión puede ser:

Un objeto simple – nombre de variable o constante literal. La aplicación de una función u operador a una colección de argumentos u operandos, cada uno de los cuales es a su vez una expresión.

El término operador se usa para referirse a las funciones incluídas en el lenguaje que tienen una sintaxis especial simplificada a propósito – + en lugar de “la función suma”.

(6)

Control de Flujo Expresiones Consideraciones de Eficiencia

Notación

Prefija (Scheme, LISP)

(+ (* 4 3) (* 0.5 (sin pi))) Infija (casi cualquier lenguaje)

4 * 3 + 0.5 * sin(pi) Postfija (Forth, Postscript) 4 3 * pi sin 0.5 * + Mezclada (mixfix, Smalltalk)

msg sendTo: "[email protected]" text: "Hola Mundo" En ocasiones los operadores son adornos (sintactic sugar) sobre funciones concretas – en C++ a + b en realidad es a.operator+(b).

(7)

Precedencia y Asociatividad

La notación infija es ambigua para las expresiones aritméticas.

Utilizar paréntesis para indicar explícitamente el orden de evaluación.

Emplear reglas de precedencia y asociatividad para ahorrarse los paréntesis (siempre que se haya leído el manual).

Precedencia – en ausencia de paréntesis, ¿cuál operador

opera antes que otro?

Asociatividad – en ausencia de paréntesis, ¿cómo aplicar

los operadores de una secuencia en la cual todos tienen la misma precedencia?

(8)

Control de Flujo Expresiones Consideraciones de Eficiencia

Operadores Inusuales

Incremento y decremento pre y postfijos.

En vez de a = a + 1, escribir a++.

El efecto de borde siempre se efectúa – el valor cambia según la posición del operador.

Producto de enteros por colecciones (cadenas, listas, . . . ) $a = $n x "a"; # $a tiene $n aes.

@b = (42) x 1; # Una lista con 42 unos. @b = (42) x @b; # Ahora son 42 42.

Generadores de listas por enumeración @a = -10..10;

Operador ternario if-then-else a = (b > c) ? d : e

(9)

Más operadores inusuales

Algunos lenguajes (Haskell, Prolog) permiten crear nuevos operadores.

Asociados a una función particular.

Incorporados a la jerarquía de precedencia y asociatividad para cooperar con el resto del lenguaje.

“Suma y producto de tuplas numéricas” en Haskell infixl 5 :+:

infixl 7 :*:

(:+:), (:*:) :: (Num a,Num b) =>

(a,b) -> (a,b) -> (a,b) (a1,b1) :+: (a2,b2) = (a1+a2,b1+b2) (a1,b1) :*: (a2,b2) = (a1*a2,b1*b2)

(10)

Control de Flujo Expresiones Consideraciones de Eficiencia

Un lenguaje lleno de operadores inusuales

IBM “engendró” APL – lenguaje puramente funcional. Lleno de operadores funcionales aplicativos . . . Generar la lista de primos de 1 hasta N

(∼N ∈ N ◦ . × N)/N ← 1 ↓ ιN

(11)

Un lenguaje lleno de operadores inusuales

IBM “engendró” APL – lenguaje puramente funcional. Lleno de operadores funcionales aplicativos . . . Generar la lista de primos de 1 hasta N

(∼N ∈ N ◦ . × N)/N ← 1 ↓ ιN . . . pero requiriendo un teclado especial

(12)

Control de Flujo Expresiones Consideraciones de Eficiencia

Asignación

Si una instrucción de cómputo influye en los cómputos que le siguen más allá de retornar un valor simple, se dice que tiene unefecto de borde o colateral (side effects).

En los lenguajes puramente funcionales (Haskell) no existen los efectos de borde y se dice que tienen

transparencia referencial.

Asignar un valor a un símbolo sólo lo hace disponible durante la evaluación actual.

Solamente hay valores que producen valores por aplicación funcional.

En los lenguajes imperativos, los efectos de borde son la norma – modificar el estado es lo que produce resultados.

Asignar un valor a un símbolo lo hace disponible durante la evaluación actual y posiblemente más allá de ella.

(13)

Valores vs. Referencias

La dualidad existencial de las variables

En los lenguajes imperativos los nombres de variable denotan “contenedores” para valores.

Los roles del lado derecho e izquierdo son diferentes en una asignación cualquiera:

El lado derecho debe producir unvalor.

El lado izquierdo debe referir unaubicación. Las expresiones que denotan valores se denominan r-values y las expresiones que denotan ubicaciones se denominan l-values.

(14)

Control de Flujo Expresiones Consideraciones de Eficiencia

l-values vs. r-values

Algunas expresiones no pueden ser l-values

2 + 3 = a, no tiene sentido.

a = 2 + 3, tampoco, cuando a es una constante.

Un l-value no tiene que ser necesariamente un nombre ni tampoco simple

Aprovechando apuntadores

(f(a)+3)->b[c] = 2 El lenguaje permitefunciones l-value

substr($a,5,4) = "hola mundo!"

El mismo objeto puede actuar como r-value o l-value en una misma expresión – depende cuál atributo de la asociación interesa.

(15)

Modelo de acceso para variables

En elModelo de Valor, la variable puede considerarse un

r-value o l-value según aplique.

En elModelo de Referencia, toda variable siempre es

considerada como un l-value.

Esto obliga a seguir la referencia (dereferencing) en los casos en que sea necesario.

En la mayoría de lenguajes con ese modelo, eso es automático; en algunos es responsabilidad del programador.

Acarrea la incomodidad del encajonado (boxing) en algunos lenguajes (Java).

(16)

Control de Flujo Expresiones Consideraciones de Eficiencia

Ortogonalidad

Cuando las características del lenguaje pueden ser utilizadas en cualquier combinación de manera consistente, se dice que esortogonal.

Lenguajesorientados a expresiones no distinguen

instrucción de expresión (Algol fue el primero). begin a := if b < c then d else e; a := begin f(b); g(c) end; g(d); 2 + 3; end;

Lenguajes con una aproximación intermedia (como C, Java, Perl) contemplaninstrucciones con valor

(expression statements). a = (b < c) ? d : e;

(17)

Asignaciones Especiales

La asignación como una expresión. a = b = 1;

$a = ($b = 5) * ($c = f($d) + 9); Combinar un operador con una asignación. a += 5; b[8].a->b *= 2; $str = "foo"; $str .= " bar"; Asignación múltiple ($a,$b) = (42, "hola");

($b,$a) = ($a,$b) # Look ma! No temp ($a,$b,$c) = foo(...);

(18)

Control de Flujo Expresiones Consideraciones de Eficiencia

Inicialización de Variables

Proveer un valor inicial al momento de la declaración reduce la posibilidad de errores difíciles de identificar. Para variables con almacenamiento estático, el valor inicial puede colocarse directamente a tiempo de compilación ahorrando tiempo de ejecución.

Algunos lenguajes no tienen mecanismo de inicialización especial, salvo asignar manualmente los valores.

Algunos lenguajes establecen reglas de inicialización automática.

Los lenguajes orientados a objetos proveen

(19)

¿Cuándo se evalúan los operandos?

a - f(b) - c * d f(a,g(b),c)

Puede influir (bugs) si hay efectos colaterales.

Permite mejorar el código objeto. Es por esto que en la mayoría de los lenguajes el orden de evaluación de operandos no está definido.

Algunas excepciones:

Java y C# insisten en evaluar de izquierda a derecha. C y C++ evalúan los argumentos para funciones de derecha a izquierda.

Algunos compiladores de Fortran reordenar expresiones según las propiedades matemáticas.

(20)

Control de Flujo Expresiones Consideraciones de Eficiencia

Corto circuito – Evaluación de McCarthy

Mínimo trabajo necesario para obtener el resultado

Las expresiones lógicas (boolean expressions) pueden optimizarse para evitar la evaluación total

Una secuencia de or es cierta tan pronto una sea cierta. Una secuencia de and es falsa tan pronto una sea falsa.

Algunos lenguajes (Pascal) no ofrecen evaluación con cortocircuito.

Algunos lenguajes (Erlang) ofrecen ambas posibilidades, vía operadores diferenciados.

andy or –no usan cortocircuito.

andalsoy orelse –si usan cortocircuito.

Al emplear corto-circuito, dejan de ser estrictas – ya no son expresiones sino instrucciones

Referencias

Documento similar