Lenguajes de Programación Tema Paradigma Imperativo



Descargar 50,55 Kb.
Fecha de conversión24.03.2017
Tamaño50,55 Kb.

Lenguajes de Programación Tema 3. Paradigma Imperativo

  • Pedro García López
  • pgarcia@etse.urv.es/
  • © University Rovira i Virgili
  • Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; A copy of the license is available at:
  • http://www.fsf.org/licenses/fdl.html
  • Copyright

Indice

  • Introducción
  • Estudio de caso: Pascal
  • Estudio de caso: ADA
  • ADA Avanzado
  • Conclusiones
  • Pascal
  • Objetivo: lenguaje para enseñar a programar, eficiente, elegante y simple. Influido por Algol-60.
  • Valores y tipos:
  • Tipos Primitivos: Integer, Real, Boolean
  • Tipos compuestos: record, variant recor, array y punteros.
  • Tipado estáticamente.
  • Punteros para representar tipos recursivos.
  • Pascal
  • Ejemplos:
  • type letter = ‘A’..’Z’;
  • var profile : array[letter]of
  • record
  • frequency: o .. Maxint;
  • followers: set of Letter;
  • end;
  • var letter1, letter2: LETTER;
  • for letter1 := ‘A’ to ‘Z’ do
  • begin write (profile[letter1].frequency); (...)
  • Pascal
  • Expresiones
  • No tiene expresiones condicionales n iexpresiones de bloque
  • No tiene agregados y las funciones no pueden devolver resultados compuestos.
  • Actualización selectiva y no total de tipos compuestos.
  • El cuerpo de una expresion es un comando e implica una asignación.
  • Pascal
  • Declaraciones
  • Deben ser declaradas en la cabecera y agrupadas por categorias. Dificulta la programación modular.
  • const
  • (...)
  • type
  • (...)
  • var
  • Comandos y secuenciadores
  • if , case,while, repeat, for. goto.
  • Pascal
  • Abstracciones:
  • Procedimientos y funciones. No son valores de primer clase, pueden ser pasados como parametro pero no pueden ser asignados ni utilizqados como componentes de tipos compuestos.
  • Paso de parámetros: valor, variable, procedural y funcional.
  • No soporta encapsulación y modularidad, ni tipos abstractos, ni ocultación de informacion, ni genericidad, ni polimorfismo, ni excepciones.
  • Ada
  • Objetivo: Lenguaje de proposito general. Con influencia de Algol-60, Simula y Pascal. Lenguaje mas moderno
  • Valores, tipos y subtipos
  • Similar a Pascal, tambiém necesita punteros para representar tipos recursivos. El lenguaje no los incluye.
  • Expresiones
  • Como Pascal tiene un conjunto muy limitado de expresiones, no incluye expresiones condicionales ni expresiones de bloque. Si tiene agregados.
  • Ada
  • Comandos y secuenciadores
  • Similar a Pascal, pero con el exit y return permite escapes de una sola entrada y posibles salidas.
  • Incluye una forma segura de manejo de excepciones.
  • Declaraciones
  • Permite la declaración de tipos y subtipos, constantes y variables, procedimientos y funcines, paquetes, tareas y excepciones. Las declaraciones se pueden situar en bloques de comandos.
  • Ada
  • Abstracciones
  • Soporta abstracciones procedurales y funcionales. Las abstracciones no son valores de primera clase y de hecho no pueden ser pasados como argumentos a otras abstracciones.
  • Paso de parámetros: in, out, in out.

Programación modular

  • with ...
  • procedure Some_Main is
  • begin
  • ….
  • end Some_Main;
  • with ...
  • with ...
  • with ...
  • Ada Library
  • with ...
  • Ada Library
  • with Hello;
  • with Fact;
  • procedure Main is
  • begin
  • for I in 1 .. Fact (4) loop
  • Hello;
  • end loop;
  • end Main;
  • main.adb
  • with Text_IO; use Text_IO;
  • procedure Hello is
  • begin
  • Put_Line (“Hello”);
  • end Hello;
  • hello.adb
  • function Fact (N : Integer) return Integer is
  • begin
  • if N <= 1 then
  • return 1;
  • else
  • return N * Fact (N-1);
  • end if;
  • end Fact;
  • fact.adb

Tipos Escalares

  • Escalares
    • Discretos
      • integer (Integer)
      • enumeration (Boolean, Character)
    • Reales
      • floating point (Float)
  • Access (punteros)

Enteros

  • function Compute (P, Q : Integer) return Integer is
  • R : Integer;
  • M : Integer := 2 * P;
  • begin
  • R := Q / M;
  • return R;
  • end Compute;
  • function Compute (P, Q : Integer) return Integer is
  • type My_Int is range -100 .. 1_000_000;
  • T : My_Int;
  • begin
  • T := P + 1;
  • T := My_Int (P) + 1;
  • return Integer (T) + Q;
  • end Compute;
  • Error de compilación
  • Creación de nuevos tipos
  • Conversión
  • explícita

Tipos Enumerados

  • procedure Compute (A : Character; B : Boolean) is
  • type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
  • D : Day := Wed;
  • C : Character := ‘W’;
  • Week_Day : Boolean := D in Mon .. Fri;
  • Lower_Case : Boolean := A in ‘a’ .. ‘z’;
  • begin
  • Week_Day := Week_Day or B;
  • end Compute;

Reales

  • procedure Compute (M : Integer) is
  • Pi : constant := 3.141;
  • F : constant Float := Float (M);
  • R : Float := F * Pi;
  • A : Integer := Integer (R);
  • begin
  • null;
  • end Compute;
  • Conversiones
  • explícitas

Desbordamiento in C

  • #include <limits>
  • void main
  • {
  • int k = INT_MAX;
  • k = k + 1;
  • }

Desbordamiento & controles

  • procedure Checks is
  • K : Integer := Integer Last;
  • begin
  • K := K + 1;
  • end Checks;
  • % gnatmake -q checks
  • % checks
  • raised CONSTRAINT_ERROR
  • %
  • Constraint Error

Subtipos

  • type Day_Of_A_Month is range 1 .. 31;
  • type Day_Of_February is range 1 .. 28;
  • D1 : Day_Of_February := 25;
  • D2 : Day_Of_A_Month := D1;
  • D2 : Day_Of_A_Month := Day_Of_A_Month (D1);
  • Error de compilación
  • OK
  • type Day_Of_A_Month is range 1 .. 31;
  • subtype Day_Of_February is Day_Of_A_Month range 1 .. 28;
  • D1 : Day_Of_February := 25;
  • D2 : Day_Of_A_Month := D1;
  • OK
  • D3 : Day_Of_A_Month;
  • D4 : Day_Of_February := D3;
  • Que ocurre aquí ?

Excepciones

  • procedure Checks is
  • A : Integer := Integer ’ First;
  • begin
  • A := A - 1;
  • end Checks;
  • % gnatmake -q checks
  • % checks
  • raised CONSTRAINT_ERROR
  • %
  • Que ocurre aquí ?

Excepciones predefinidas

  • Constraint_Error: overflow, computation error (divide by zero), array index out of range, …
  • Storage_Error: no more memory available
  • Program_Error: fundamental program error (e.g. end of function with no return statement)

Captura de excepciones

  • with Text_IO; use Text_IO;
  • procedure Checks is
  • A : Integer := Integer ’ First;
  • begin
  • A := A - 1;
  • exception
  • when Constraint_Error =>
  • Put_Line (“Overflow occurred”);
  • end Checks;
  • % gnatmake -q checks
  • % checks
  • Overflow occurred
  • %

Creación de Excepciones

  • procedure Checks is
  • Internal_Error : exception;
  • procedure Foo is
  • begin
  • raise Internal_Error;
  • end Foo;
  • procedure Bar is
  • begin
  • Foo;
  • end Bar;
  • begin
  • Bar;
  • exception
  • ...
  • end Checks;
  • Exception Handler
  • procedure Foo is
  • begin
  • raise Internal_Error;
  • end Foo;
  • procedure Bar is
  • begin
  • Foo;
  • end Bar;
  • begin
  • Bar;
  • exception
  • when Internal_Error =>
  • Put_Line (“problem occurred”);
  • when others =>
  • Put_Line (“some other exception”);
  • end Checks;
  • Exception Handler
  • procedure Foo is
  • begin
  • raise Internal_Error;
  • end Foo;
  • procedure Bar is
  • begin
  • Foo;
  • end Bar;
  • begin
  • Bar;
  • exception
  • when Internal_Error =>
  • Put_Line (“problem occurred”);
  • when others =>
  • Put_Line (“some other exception”);
  • end Checks;
  • Exception Handler
  • 1
  • 2
  • 4
  • 5
  • 3
  • procedure Foo is
  • begin
  • raise Internal_Error;
  • end Foo;
  • procedure Bar is
  • begin
  • Foo;
  • end Bar;
  • begin
  • Bar;
  • exception
  • when Internal_Error =>
  • Put_Line (“problem occurred”);
  • when others =>
  • Put_Line (“some other exception”);
  • end Checks;
  • 1
  • 2
  • 4
  • 5
  • 3

Tipos Access

  • type Int_Ptr is access Integer;
  • P : Int_Ptr;

Tipos compuestos

  • array (String)
  • record
  • tagged record
  • protected types
  • tasks

Arrays

  • procedure Compute (N : Integer) is
  • A : array (1 .. N) of Float;
  • begin
  • for I in 1 .. N loop
  • A (I) := 3.141;
  • end loop;
  • end Compute;
  • Arrays pueden tener
  • - límites dinámicos
  • - tamaño dinámico

Arrays tipados

  • procedure Compute (N : Integer) is
  • type Arr is array (Integer range <>) of Float;
  • A : Arr (1 .. N);
  • B : Arr := A;
  • B toma sus limites de A
  • Constraint_Error
  • Si C’Length /= A’Length
  • Constraint_Error
  • Si A’Last < 8
  • C : Arr (11 .. 20);
  • begin
  • C := A
  • C (15 .. 18) := A (5 .. 8);

Atributos de Array

  • ARRAY ’ First : menor índice en ARRAY
  • ARRAY ’ Last : mayor índice en ARRAY
  • ARRAY ’ Length : número de elementos ARRAY
  • ARRAY ’ range : ARRAY ’ First .. ARRAY ’ Last
  • type Vector is array (Natural range <>) of Float;
  • function Max (V : Vector) return Float is
  • M : Float := Float First;
  • begin
  • for I in V range loop
  • if V (I) > M then
  • M := V (I);
  • end if;
  • end loop;
  • return M;
  • end Max;
  • type Vector is array (Natural range <>) of Float;
  • function Max (V : Vector) return Float;
  • V1 : Vector := (0.0, 1.0, 2.0, 3.0, 4.0, 5.0);
  • V2 : Vector (1 .. 100) := (1.0, 2.0, others => 99.0);
  • X : Float := Max (V1);
  • Y : Float := Max (V2);
  • V1’First = 0
  • V1’Last = 6
  • V1’Length = 7
  • V2’First = 1
  • V2’Last = 100
  • V2’Length = 100

Array predefinido

  • type String is array (Positive range <>) of Character;
  • R : String (1 .. 10);
  • S : String := (‘H’, ‘e’, ‘l’, ‘l’, ‘o’);
  • T : String := “Hello”;
  • Q : String := S & “ “ &T “ you”;
  • Q = “Hello Hello You”

Tipos Record

  • type Date is record
  • Day : Positive range 1 .. 31;
  • Month : Positive range 1 .. 12;
  • Year : Integer;
  • end record;
  • D : Date := (3, 9, 1975);
  • A : Date := (Day => 31, Month => 12, Year => 1999);
  • B : Date := A;
  • Y : Integer := B . Year;
  • type Node;
  • type Node_Ptr is access Node;
  • type Node is record
  • D : Date := (1, 1, 1900);
  • Next : Node_Ptr;
  • end record;
  • P1 : Node_Ptr := new Node;
  • Memoria
  • P1
  • 1
  • 1
  • 1900
  • null
  • 3
  • 9
  • 1975
  • P2
  • P2 : Node_Ptr := new Node ((3, 9, 1975), P1);

Paso de Parámetros

  • in (functions & procedures)
  • in out (solo procedures)
  • out (solo procedures)

Estructuras de control

  • if-then-else
  • case
  • Iteradores
    • for
    • while

Programación modular

    • Especificación & Implementación
    • Tipos Abstractos de datos
    • Paquetes jerárquicos

Compilación separada

  • THE
  • PROBLEM
  • Compiler
  • object
  • CODE
  • Compiler
  • object
  • CODE
  • Compiler
  • object
  • CODE
  • Linker
  • executable
  • libraries

Problemas

  • CODE
  • CODE
  • CODE
  • Sin estructura
  • Para escribir código debes conocer TODO el código que utilices
  • CODE
  • CODE

Idea

  • Especificar
  • que debería hacer
  • cada módulo
  • ESPECIFICACION
  • Módulo
  • ?
  • Implementación

Una especificación es ...

  • CONTRATO
  • Desarrollador
  • Del módulo
  • Cliente del
  • Módulo
  • Sobre los SERVICIOS que ofrece el módulo

SPEC = lista de servicios

  • SPEC = lista de servicios
  • BODY = implementación de los servicios (oculta)
  • Módulo Software
  • Service_1
  • Service_2
  • Service_3
  • Service_1
  • implementation
  • Service_2
  • implementation
  • Service_3
  • implementation
  • SPECIFICATION
  • ?
  • BODY

Ejemplo

  • Crear un módulo Cola que permita:
    • Añadir un Integer a la Cola
    • Ver el primer integer de la cola
    • Obtener el primer integer de la cola
    • Ver si la cola está vacia
  • package Queue is
  • procedure Add (Element : Integer);
  • function First return Integer;
  • function Get return Integer;
  • function Empty return Boolean;
  • end Queue;
  • queue.ads
  • package Queue
  • ?
  • BODY
  • package Queue is
  • procedure Add (Element : Integer);
  • function First return Integer;
  • function Get return Integer;
  • function Empty return Boolean;
  • end Queue;
  • queue.ads

Utilizando Queue

  • with Queue;
  • procedure Client is
  • Queue_Error : exception;
  • X : Integer;
  • begin
  • Queue.Add (3);
  • Queue.Add (4);
  • if not Queue.Empty then
  • X := Queue.Get;
  • else
  • raise Queue_Error;
  • end if;
  • end Client;
  • client.adb

Las especifications reducen la complejidad

  • SPEC
  • SPEC
  • SPEC
  • SPEC
  • Para escribir tu propio código:
    • Solo es necesario entender la especificación de los servicios utilizados

Use

  • with Queue; use Queue;
  • procedure Client is
  • Queue_Error : exception;
  • X : Integer;
  • begin
  • Queue. Add (3);
  • Queue. Add (4);
  • if not Queue. Empty then
  • X := Queue. Get;
  • else
  • raise Queue_Error;
  • end if;
  • end Client;

Una posible implementación del package Queue

Buffer Circular

  • Q
  • 0
  • 1
  • Max_Size - 1
  • Q_Last
  • Q_First
  • package body Queue is
  • Max_Size : constant := 100;
  • type Q_Index is mod Max_Size;
  • Q : array (Q_Index range 0 .. Max_Size - 1) of Integer;
  • Q_First : Q_Index := Q First;
  • Q_Last : Q_Index := Q_First;
  • Size : Natural range 0 .. Max_Size;
  • procedure Add (Element : Integer) is
  • begin
  • Q (Q_Last) := Element;
  • Q_Last := Q_Last + 1;
  • Size := Size + 1;
  • end Add;
  • ...
  • end Queue;
  • queue.adb
  • package body Queue is
  • ...
  • function First return Integer is
  • begin
  • return Q (Q_First);
  • end First;
  • function Get return Integer is
  • begin
  • Q_First := Q_First + 1;
  • Size := Size - 1;
  • return Q (Q_First - 1);
  • end Get;
  • function Empty return Boolean is
  • begin
  • return Size = 0;
  • end Empty;
  • end Queue;
  • queue.adb

Otra posible implementación del package Queue

Lista enlazada

  • Q_Last
  • Q_First
  • Free
  • package body Queue is
  • type Queue_Element;
  • type Element_Ptr is access Queue_Element;
  • type Queue_Element is record
  • Val : Integer;
  • Next : Element_Ptr;
  • end record;
  • Q_First : Element_Ptr;
  • Q_Last : Element_Ptr;
  • Free : Element_Ptr := new Queue_Element;
  • ...
  • end Queue;
  • queue.adb
  • package body Queue is
  • ...
  • procedure Add (Element : Integer) is
  • begin
  • if Q_First = null then
  • Q_First := Free;
  • else
  • Q_Last.Next := Free;
  • end if;
  • Q_Last := Free;
  • Free := Free.Next;
  • Q_Last.all := (Element, null);
  • if Free = null then
  • Free := new Queue_Element;
  • end if;
  • end Add;
  • ...
  • end Queue;
  • queue.adb
  • package body Queue is
  • ...
  • function Get return Integer is
  • Tmp : Element_Ptr := Q_First;
  • begin
  • Q_First := Q_First.Next;
  • if Q_First = null then
  • Q_Last := null;
  • end if;
  • Tmp.Next := Free;
  • Free := Tmp;
  • return Tmp.Val;
  • end Get;
  • ...
  • end Queue;
  • queue.adb
  • package body Queue is
  • ...
  • function First return Integer is
  • begin
  • return Q_First;
  • end First;
  • function Empty return Boolean is
  • begin
  • return Q_First = null;
  • end Empty;
  • end Queue;
  • queue.adb

Una Especificación puede tener varias implementaciones

  • Podemos cambiar la implementación
  • SIN cambiar el código cliente
  • package Queue is
  • procedure Add (Element : Integer);
  • function First return Integer;
  • function Get return Integer;
  • function Empty return Boolean;
  • end Queue;
  • queue.ads
  • A
  • B

En Ada

  • La Spec siempre se chequea con su implementación
  • Obligatorio incluir with de las specs que vayas a usar (no como en C)
  • Multiples espacios de nombres

Spec se chequea con el cuerpo

  • package Queue is
  • procedure Add (Element : Integer);
  • ...
  • end Queue;
  • package body Queue is
  • ...
  • procedure Add (Element : Integer; X : Float) is
  • ...
  • end Add;
  • ...
  • end Queue;
  • Que ocurre aquí ?

Múltiples espacios de nómbres

  • package Queue is
  • procedure Add (E : Integer);
  • ...
  • end Queue;
  • package Set is
  • procedure Add (E : Integer);
  • ...
  • end Set;
  • with Queue;
  • with Set;
  • procedure Client is
  • begin
  • Queue.Add (3);
  • Set.Add (99);
  • end Client;

Privacidad y ocultación de información

  • Exponer las estructuras de datos es peligroso
    • El código cliente puede manipular directamente las estructuras sin utilizar los servicios del módulo
    • El código cliente es dificil de modificar

Tipos privados

  • package Queues is
  • type Queue is private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue is …;
  • end Queues;

En cualquier implementación

  • package Queues is
  • type Queue is private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue_Element;
  • type Element_Ptr is access Queue_Element;
  • type Queue_Element is record
  • Val : Integer;
  • Next : Element_Ptr;
  • end record;
  • type Queue is record
  • First : Element_Ptr;
  • Last : Element_Ptr;
  • end record;
  • end Queues;

… los tipos privados son PRIVADOS

  • with Queues; use Queues;
  • procedure Client is
  • Q1 : Queue;
  • Q2 : Queue;
  • begin
  • Add (Q1, 123);
  • Add (Q2, 3);
  • Q2.Last := null;
  • end Client;
  • ¿ Que ocurre aquí ?

Ventajas de los tipos privados

  • Refuerzan el contrato de la especificación
  • El código cliente no puede corromper tus estrucuras de datos
  • Podemos cambiar la implementación sin modificar el código cliente

¿Por qué lo privado está en el ADS?

  • package Queues is
  • type Queue is private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue_Element;
  • type Element_Ptr is access Queue_Element;
  • type Queue_Element is record
  • Val : Integer;
  • Next : Element_Ptr;
  • end record;
  • type Queue is record
  • First : Element_Ptr;
  • Last : Element_Ptr;
  • end record;
  • end Queues;

… porque necesitamos compilar el código cliente

  • with Queues; use Queues;
  • procedure Client is
  • Q1 : Queue;
  • begin
  • Add (Q1, 123);
  • end Client;

… aunque todavía podemos ocultar más el tipo

  • package Queues is
  • type Queue is private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue_Info;
  • type Queue is access Queue_Info;
  • end Queues;
  • package body Queues is
  • type Queue_Element;
  • type Element_Ptr is access Queue_Element;
  • type Queue_Element is record
  • Val : Integer;
  • Next : Element_Ptr;
  • end record;
  • type Queue_Info is record
  • First : Element_Ptr;
  • Last : Element_Ptr;
  • end record;
  • ...
  • end Queues;

Tipos privados limitados

  • NO asignación :=
  • NO comparación =
  • package Queues is
  • type Queue is limited private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue is …;
  • end Queues;
  • with Queues; use Queues;
  • procedure Client is
  • Q1 : Queue;
  • Q2 : Queue;
  • X : Integer;
  • begin
  • Add (Q1, 123);
  • Add (Q1, 3);
  • Q2 := Q1;
  • end Client;
  • ¿ Que ocurre aquí ?

Tipos Abstractos de Datos (TAD)

  • Conjunto de valores (datos del dominio)
  • Colección de operaciónes (turinas que manipulan los valores)
  • TAD =

Queue es un TDA

  • package Queues is
  • type Queue is limited private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue is …;
  • end Queues;
  • operaciones
  • valores

Objetos & Variables

  • My_Q : Queue;
  • Memory
  • Queue
  • object
  • Un objeto
  • Nombre del obeto
  • CLASE = TDA
  • + herencia
  • operacion
  • Datos
  • Privados
  • operacion
  • operacion
  • ENCAPSULACION
  • Invocación de los servicios del TDA

Modelo de Objetos

Modelo Procedural (C)

  • C module
  • C module
  • C module
  • DATOS GLOBALES

Para extender un paquete ...

  • package Queues is
  • type Queue is private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue is …;
  • end Queues;
  • function Last (Q : Queue) return Integer;
  • function Last (Q : Queue) return Integer;
  • Queue is a private type

Pero ...

  • Cada cambio en el ADS obliga a recompilar todos los clientes
  • Cada cambio en el módulo implica el test de toda la funcionalidad del módulo.

Solución: Paquetes hijos

  • package Queues is
  • type Queue is private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue is …;
  • end Queues;
  • queues.ads
  • function Queues . Last (Q : Queue) return Integer;
  • queues-last.ads

Utilización:

  • with Queues; use Queues;
  • with Queues.Last;
  • procedure Client is
  • Q : Queue;
  • X : Integer;
  • begin
  • Add (Q, 123);
  • Add (Q, 3);
  • X := Queues.Last (Q);
  • end Client;
  • package Queues is
  • type Queue is private;
  • procedure Add (Q : Queue; Element : Integer);
  • function First (Q : Queue) return Integer;
  • function Get (Q : Queue) return Integer;
  • function Empty (Q : Queue) return Boolean;
  • private
  • type Queue is …;
  • end Queues;
  • queues.ads
  • package Queues . New_Functionality is
  • function Last (Q : Queue) return Integer;
  • end Queues . New_Functionality
  • queues-new_functionality.ads
  • Package hijo
  • with Queues; use Queues;
  • with Queues.New_Functionality;
  • procedure Client is
  • Q : Queue;
  • X : Integer;
  • begin
  • Add (Q, 123);
  • Add (Q, 3);
  • X := Queues.New_Functionality.Last (Q);
  • end Client;

Polimorfismo aparente: Sobrecarga

  • package Queue is
  • procedure Add (E : Integer);
  • procedure Add (E : Float);
  • ...
  • end Queue;
  • with Queue; use Queue;
  • procedure Client is
  • begin
  • Add (123);
  • Add (3.141);
  • end Client;

Polimorfismo paramétrico: Genericidad

Repetición de código...

  • procedure Swap (X, Y : in out Integer) is
  • Tmp : Integer := X;
  • begin
  • X := Y;
  • Y := Tmp;
  • end
  • procedure Swap (X, Y : in out Float) is
  • Tmp : Float := X;
  • begin
  • X := Y;
  • Y := Tmp;
  • end

Esto...

  • Implica coste de tiempo
  • Susceptible a errores (Cortar & Pegar)
  • Díficil de mantener

La genericidad permite parametrizar código

  • generic
  • type Some_Type is private;
  • procedure Gen_Swap (X, Y : in out Some_Type);
  • gen_swap.ads
  • procedure Gen_Swap (X, Y : in out Some_Type) is
  • Tmp : Some_Type := X;
  • begin
  • X := Y;
  • Y := Tmp;
  • end Gen_Swap;
  • gen_swap.adb

Instanciación

  • with Gen_Swap;
  • procedure Client is
  • procedure Swap is new Gen_Swap (Some_Type => Integer);
  • procedure Swap is new Gen_Swap (Some_Type => Float);
  • A, B : Integer := …;
  • P, Q : Float := …;
  • begin
  • Swap (A, B);
  • Swap (P, Q);
  • end Swap;

Tipos de unidades genéricas

  • generic
  • … formal parameters ...
  • procedure Proc ();
  • generic
  • … formal parameters ...
  • function Func () return …;
  • generic
  • … formal parameters ...
  • package Pack is
  • end Pack;

… parámetros formales ...

  • Types
  • Objects
  • Subprograms
  • Packages

Ejemplo

  • Escribir una función genérica que calcule
  • donde
    • L & H son límites enteros
    • F es una función que devuelve un valor
    • Una operación de suma está disponible para ese valor

Spec ...

  • generic
  • type Res_Type is private;
  • Zero : in Res_Type;
  • with function Add (X, Y : Res_Type) return Res_Type;
  • with function F (I : Integer) return Res_Type;
  • function Sum (L, H : Integer) return Res_Type;

Body ...

  • function Sum (L, H : Integer) return Res_Type is
  • Result : Res_Type := Zero;
  • begin
  • for I in L .. H loop
  • Result := Add (Result, F (I));
  • end loop;
  • return Result;
  • end Sum;

Instanciación

  • with Sum;
  • procedure Client is
  • function Compute (X : Integer) return Integer is … end;
  • function Compute (X : Integer) return Float is … end;
  • function New_Sum is new Sum (Res_Type => Integer,
  • Zero => 0,
  • Add => “+”,
  • F => Compute);
  • function New_Sum is new Sum (Res_Type => Float,
  • Zero => 0.0,
  • Add => “+”,
  • F => Compute);

Genericidad y paquetes

Genericidad y paquetes

Instanciación



La base de datos está protegida por derechos de autor ©absta.info 2016
enviar mensaje

    Página principal