Está en la página 1de 8

LAS PROMESAS DE TIPADO,

PURÉ, Y PERTENTINO F P
PROGRAMACIÓN NO
OPCIONAL: Parte II
1 podemos crear una lista de algunos En el primer caso, el mensaje de
En la primera entrega de esta serie en
elementos y luego anteponer un errores el método add (int) es UN-
programación funcional, Kon-rad
elemento a esa lista:usuario => definido para el tipo Entero ,mientras
Hinsen introdujo la función
(contras 3 (lista 4))(3 4).Sin embargo, que en el segundo caso, es Tipo
paradigma de programación nacional,
no podemos anteponer un elemento desajuste: no se puede convertir de
que fomenta la recursividad y el
a otro elemento usuario => (contras 3 Integer to List <Integer> . Javael
orden superior abstracción funcional
4)java.lang. Argumento de excepción sistema de tipos detectó estos
en algoritmos .En esta segunda
ilegal:No sé cómo crear ISeq de: errores ,los reportamos mientras
entrega, exploramos varios otros
Entero porque la función de contras estábamos editan doing o
aspectos de lo funcional paradigma.
predefinida requiere que su segundo compilando el programa siguiendo
Usando ejemplos en el Clo-lenguajes
argumento sea de una tipo de lista este código, y se negó a dejar
jure, Java y Haskell, nosotros discutir
Sistema de tipos de Clojure detectó el nosotros lo corremos. Java usa
algunos de los beneficios de la
intento de invocar la funciónción escritura estática : tipo los errores se
estática escribiendo con inferencia de
sobre un argumento del tipo detectan en tiempo de compilación y
tipos y puro,programa funcional sin
incorrecto, informó un error de tipo y los programas con errores de tipo no
efectos secundariosming con
detuvo pro ejecución de gramo. lo harán Incluso compilar. Otros
evaluación perezosa. En particularLar,
Clojure utiliza dinámica escribiendo : idiomas que usar escritura estática
argumentamos que estas
los errores de tipo no se incluye Ada, C, C ++,C #, Fortran,
características hacen Haskell es una
detectanhasta que el programa se Haskell, Java, ML, Pas-cal y Scala.
opción convincente para la
ejecute. Otros lan-los indicadores con Entre esos, losque también admiten
generación Desarrollo de software
escritura dinámica incluyenGroovy, fea de orden superiorcaracterísticas
eral. La ciencia comunidad
JavaScript, Lisp, Object-C, Perl, tales como funciones de primera
informática específica, sin embargo,
Python, Ruby, Scheme yCharla.Ahora, clase (C #,Haskell, ML y Scala) o de
probablemente requerirá una mejor
veamos el comportamiento de primera clase los objetos (Ada, C #,
cantidad numérica apoyo brary y
Sistema de tipos de Java. Podemos Java y Scala) son llamado orden
funcional eficiente versiones de
crear una lista de algunos elementos superior escrito , o HOT.Suponiendo
algoritmos científicos antes
y luego anteponer un elemento de un sistema de tipo de sonido,la
aceptando a Haskell más
esa lista escritura estática representa un
ampliamente. Escritura dinámica y
conservadorenfoque: un programa
estáticaSistemas de tipo en lenguaje List <Integer> l = Matrices. podrá
de programación los indicadores asList (4)
aseguran que usamos ;l.add (3)
correctamentecada elemento del
programa de acuerdo con sutipo, es ;pero no podemos anteponer un
decir, de acuerdo con el resumención elemento a un-otro elemento
que representa el elemento del Entero i = nuevo entero (4)
programa.Típicamente, los valores ;i.add (3)
numéricos participan en operaciones ;oLista <Integer>
aritméticas y comparativas hijos, las l = nuevoEntero (4);l.add (3);
listas participan en el acceso a
elementos y concatenación, y así
sucesivamente .Primero, veamos el
sistema de tipos antes de
comportamiento en Clojure, un LISP
moderno dialecto que se ejecuta en
Java VirtualMáquina. Como Hinsen
mostró en el primera entrega,
O N T YPECASTADO YC ONVERSIONESE En este ejemplo, mezclamos cadenas y objetos reales de
UrLdentro de la misma colección. Luego iteramos a través del
VEN colección y hacer algo con las cuerdas. Usamos elinstancia de
operador para determinar qué objetos son cadenas, los
VEN en lenguajes con tipos como C ++, C #, y Java, quea veces convierte de tipo Objeto a los más específicos escriba String y
debe convertir un valor numérico de uno escriba a otro. Al haga algo específico de cadena, comocreando una URL a
pasar de un entero de 16 bits a un Entero de 32 bits, por partir de ella. Si no hubiéramos usado la instancia de
ejemplo, no hay pérdida de información ,y es seguro dejar que operador, el reparto habría fallado tan pronto como la
la conversión suceda implícitamente. En la otra dirección, sin iteración llegó a la instancia de UrL.Lanza desde un tipo más
embargo, parte del número original podría perderse y la general a un tipo más específico fallar en tiempo de ejecución,
conversión debería ocurrir solo si elEl programador asume la como, por ejemplo, cuando un objeto no es deel tipo
responsabilidad. el programador toma esta responsabilidad específico esperado o un tipo más específico. allí-Por lo tanto,
usando un tipo de letra, o simplemente, un el en coconstruir. notamos que solo los programas sin elenco son
En el siguiente fragmento de Java, por ejemplo, ella última garantizados.para estar libre de errores de tipo en tiempo de
línea provocaría un error en tiempo de compilación sin la ejecución. Por el contrario, los moldesen la dirección opuesta
conversión (de una específica a una más generalclase) nunca puede fallar,
por lo que no necesitan una verificación de tiempo de
ejecución.finalmente, conversiones entre clases no
relacionadas, como Stringa Integer, nunca puede tener éxito,
por lo que siempre causan unerror de tipo en tiempo de
compilación.Las funciones de conversión versus conversión
fueron un gran sub-Objeto de debate en la comunidad C ++
cuando los ciclos eran preciosos y cualquier "transformación"
de datos furtivos (nono importa cuán trivial) podría incurrir en
un rendimiento sustancial gastos generales. (esto se debió a la
construcción de copia cascad-efecto ing, que ya no es un
problema en la mayoría de los modernos lenguajes orientados
a objetos, ya que suelen copiar referencias hoy en vez de
valores.) hoy, sin embargo, el casting es a menudo un
responsabilidad que realmente causa errores de escritura en
tiempo de ejecución, incluso en lenguajes de programación
con sistemas de tipos bien fundados como Java Peor aún, es
bien conocido (especialmente entre los sazonados
Programadores de C / C ++ como nosotros) que no todos los
elencosDebería permitirse. por ejemplo, hay una promoción
naturalción de short -> int -> long -> long long (en C) quees sin
pérdidas ; sin embargo, la transformación inversa no es
naturalral, altamente propenso a errores y no portátil,
especialmente en unmundo informático heterogéneo que
todavía presenta 16-, 32-,y procesadores de 64 bits. Usar
funciones de conversión (en su lugarde conversiones) le
permite asegurarse de que todas las conversiones
significativas seanrealizado correctamente (hacia adelante y
hacia atrás, haciendo que todosconversiones hacia abajo
explícitas y precisas) con solo un ligeroinconveniente para el
programador (y la alineación puede ayudaraliviar la mayoría
de los problemas de rendimiento).

ejecutar solo si podemos garantizar que es libre de errores de tipo. Por lo tanto, un programaque pasa la verificación de tipo
es garantíano fallar en tiempo de ejecución debido a errores de tipo (con algunas restricciones, como discutimos en la barra
lateral "En Tipo-casting y conversiones "). Porque las condiciones no se evalúan hasta la ejecución tiempo, por ejemplo, el
tipo estático corrector todavía rechazaría el siguiente programa, aunque el error nuestro código siempre se omitirá: si (3> 4)
{Lista <Integer> l = nuevo Entero (4);l.add (3);}Eso puede parecer un poco restrictivo ;idiomas escritos dinámicamente No
tengo quejas al respecto. Pero sup-plantear la expresión condicional es mucho más complejo y evalúa acierto en algunas
raras ocasiones como parte de algún software de misión crítica, como como control de tráfico aéreo, enrutadores de
Internet, y cajeros automáticos, donde cada
sola línea de código, accesible o no
,debe verificarse antes de que esté
incrustado y desplegado a gran
escala. Conescritura dinámica, podría
Si y fuera un Flotador en lugar de
producirse un desastre si el
Entero , inferiríamos que z es un
condicional evaluado a verdadero. y que agrega x e y :Preludio> let
Flotador .Es importante distinguir
(Alabama-aunque este ejemplo makeAdder x =\ y -> x + y Dentro del
esto de que pasa en lenguajes como
puede parecer im-probable, el parche intérprete, usamos el palabra clave
Py-thon, donde el tipo estático de x ,
binario es rutinario se usa para permite definir nuevas variables(la
y , yz son todos los tipos de "objeto";
cambiar el código compilado en un palabra clave no es necesaria para
el tipo estático de cada uno es
sistema desplegado, como para top-definiciones de variables de nivel
desconocido. Solo el tiempo de
actualizar sistemas de destrucción y en la fuente archivos). Ahora
ejecución el tipo se conoce al
muchas industrias usar la técnica para apliquemos makeAdder a un
examinar el tipo ( x ),tipo ( y ) o tipo
parchar equipos, tales como argumento adecuado: Preludio>
( z ). El lenguaje C #(de la familia .NET
interruptores de telecomunicaciones, makeAdder 3No hay instancia para
de Microsoft) también admite
que requieren un tiempo de (Mostrar(t -> t))Dado que aplica
escritura automática de variables
inactividad cercano a cero).Con la makeAdder a unos resultados de un
.Entonces, podemos escribir lo
escritura estática, hubiéramos sabido solo argumento en una nueva función
anterior comovar x = nuevo entero
sobre el error dentro de la que espera otro argumento ,es
(4);var x = nuevo entero (5);var z = x +
declaración ifmucho antes de comprensible que la interpretación er
y; En el siguiente ejemplo típico de
desplegar el sistema .La escritura se queja de que no sabe cómo para
programación de orden superior,
estática también tiene un significado imprimir esta (o cualquier otra)
nosotros usar el patrón de estrategia
significativo beneficio de función. En su lugar, usemos el
para representar un estrategia de
rendimiento: porque el el compilador intérprete : t(una abreviatura de :
comparación personalizada como
garantiza el tipo de seguridad, tipo ) comando para Echa un vistazo a
funciónción (en Java, encapsulado
nosotros no necesita las la expresión precisatipo: Preludio>: t
dentro de un objeto) que pasamos al
comprobaciones de tiempo de makeAdder 3makeAdder 3 :: (Num t)
tipo real función:Lista <Integer> l
ejecución encontradas en idiomas =>t -> t Este tipo significa que la
= ...Comparador <Integer> c =nuevo
escritos dinámicamente y nuestro función toma un argumento de tipo
Comparador <Integer> () {public int
código corre más rápido ty reconvierte un resultado de tipo t ,
compare (Entero l, Entero r)
(especialmente cuando todo está suponiendo quet es un tipo
{...}};Collections.sort (l, c);En la
escrito en el mismo idioma).Pero los numérico. De hecho, podemos aplicar
siguiente sección, discutimos cómo
idiomas estáticamente escritos son esta función a otro argumento y
eliminar la mayor parte de este
seguros y tiene un precio: debemos obtenga el resultado numérico
tedio .Inferencia de tipo y
declarar El tipo de cada variable en el esperado:Preludio> (makeAdder 3) 4
cuantificación Universal ¿No sería
pro-gramo, incluidos los argumentos
bueno si pudiéramos tener nuestro
formales de métodos y variables de 77
pastel y comérselo también? Es
instancia. Esta puede volverse
decir ,no podríamos tener la
tedioso rápidamente a medida que el
seguridad de la estática escribiendo
código se pone más complejo,
sin su tedio? Sorpresa ingly, la
especialmente con mayor
respuesta es sí! Existen algunos
programación de pedidos. Hay,
lenguajes funcionales que tienen
como-alguna vez, varios idiomas
sistemas de tipo como o más
emergentes que Asigna
potentes que los de, digamos, Java,
automáticamente tipos a las variables
pero que son capaces de averiguar el
.Por ejemplo, en el lenguaje Boo
correcto, previsto tipos de variables y
(aversión segura de tipo de Python
funciones en todos La mayoría de
diseñada para la plataforma .NET),
todas las situaciones. Veamos cómo
podemos escribiresex = nuevo entero
funciona esto enHaskell (usando el
(4)y = nuevo entero (5)z = x + yAquí, x
Glasgow Haskell intérprete, ghci; ver
e y son asignados tanto a la tipo
www.haskell.org).Comenzamos con
estático de entero (en el primer uso)y
una versión escrita defunción de
z se le asigna el mismo tipo
sumador desde el primer entrega.
estático(deduciendo el resultado de
Como recordamos, makeAd-der toma
la expresióntipo).
un argumento numérico x ydevuelve
una nueva función en otro número
argumento merico
o simplemente uno después de la otro. Esto destaca 0Posible solución: agregue un
una diferencia clave entre más declaración de instancia para(Num
Preludio> makeAdder 3 47 7¿Por qué funcional y idiomas imperativos Char)Como arriba, no podemos
el intérprete simplemente noescriba Funcionallos idiomas fomentan el anteponer un elemento a otro
la función como, por ejemplo, Entero- orden superior funciones que cursan elemento:Preludio> 3: 4No hay
> Entero , especialmente dado que sus argumentos ments (después del instancia para (Num [t])derivado de
nosotrospasó una constante entera lógico HaskellB. Curry, quien lo literal'4' en <interactivo>: 1: 4
como la primera¿argumento? describió estotécnica). Es decir, las
Veamos ese enterotipo de constante funciones sonaplicado a algunos o
por sí mismo:Preludio>: t 33 :: (Núm. todos sus ar-guments uno tras otro,
T) => t¡Ajá! Lo que vemos es que 3 quesignifica que el resultado puede
latastener cualquier tipo numérico seruna función o un valorPor
requerido, entonces es mucho más ejemplo, podemos definir elfunción
general que un inte-valor ger. inc (incremento en 1) poraplicando
Típicamente, el tipo de Haskellel parcialmente el
sistema trata de forma bastante makeAdderfunciónPreludio> let inc =
natural con el sobrecarga de makeAdder 1Entonces podemos
constantes numéricas yo peradores, y incrementar cualquier valor
generalmente no tenemos pensar comosigue:Preludio> inc 45
mucho al respecto. 5Volviendo a nuestro ejemplo de
(Manejaroperador general y función lista,podemos crear una lista de
sobre-cargando de forma sistemática algunos elementosMents y luego
pero no observablede manera anteponer un elemento aesa lista
confiada, Haskell usa clases de (Similar a las secuencias de comandos
tipos :una clase de tipo Num incluye modernas lenguajes como Python,
Int paraenteros de precisión fija, funcional los idiomas suelen ofrecer
enteros paraenteros de precisión sintácticoso porte para estructuras de
arbitraria, y asíen. En consecuencia, datos comunescomo listas y
podemos restringir elvalor 3 a tuplas).Preludio> 3: [4][3,4]Más allá
cualquier tipo específico incluidoen la de diferencias sintácticas
clase de tipo:Preludio>: t (3 :: Int)(3 :: menoresEnces, esto se parece a la
Int) :: IntPreludio>: t (3 :: Entero)(3 :: Clojureejemplo anterior Pero una
Entero) :: EnteroLos detalles de la diferencia importante ...es que
sobrecarga sistemáticaing en Haskell Haskell sabe el tipo deel : operador,
están más allá de nuestro alcance equivalente a Clojurefunción contras.
aquí, pero ofrecemos un ejemplo (Haskell soporta sym-operadores de
específico más tarde.)¿Qué pasa con infijo bolic, que se convierten
el tipo de makeAdder?¿sí mismo? funciones de prefijo cuando está
Preludio>: t makeAddermakeAdder :: rodeado de paréntesis)Preludio>: t (:)
(Num a) => a ->a -> aProgramadores (:) :: a -> [a] -> [a]En otras palabras,
(como nosotros) que crecieron en el este operador toma un valor de tipo
imperativo lan-los indicadores ay una lista con elementos de tipo a ,
generalmente separan el y produce otra lista de escriba a .Los
parámetroeter tipos del tipo de elementos de la lista pueden ser de
retorno en undefinición de función cualquier escriba siempre que se use
típica Entonces elLa sintaxis de ese tipo sistemáticamente este
Haskell podría parecer inicialmenteun concepto se conoce
poco raro. Es decir, cuando ves comocuantificación universal:
unexpresión como a -> a -> a , funciona para todos tipos a . Estas
suprimera inclinación es pensar en el listas son homogéneas: todos los
primeros dos elementos entre elementos deben ser del mismo
flechas, a ya , como los argumentos tipo,así que no podemos anteponer,
de la función, y el tercer elemento, a , digamos, un número aUna lista de
como el tipo de resultado De hecho, personajes. (Discutimos tipo-listas
esto es correcto siaplicas la función a heterogéneas seguras más
ambos argumentos ments, pero adelante).Preludio> 3: ['a', 'b']No hay
como vimos, la función instancia para (Num Char)derivado de
puedeTambién tome sus argumentos lo literal'3' en <interactivo>: 1:
ing la cola de trabajo, y el segundo Mientras pasamos una cola
argumento es una función para representa-
agregar ción y una operación asociada
otra lista de elementos a la cola; abiertamente
esta función determina el orden en a la función traverseUsingList ,
que atravesamos los subárboles del en su lugar podríamos definir un ab-
ootValue :: Árbol a -> a árbol: adecuado
rootValue (Nodo x _) = x traverseUsingList [] _ = [] extraiga el tipo de datos para colas de
atravesar :: Árbol a -> [Árbol a] traverseUsingList (Vacío: dos maneras:
atravesar Vacío = [] resto) addAll = a través de una tupla de una o más
transversal (t @ (Nodo x ts)) = traverseUsingList rest funciones
t: concat (mapa transversal ts) añadir todo que comparten y operan con datos
En estas funciones, el mapa aplica un traverseUsingList ocultos
funcionar para cada elemento en una ((t @ (Nodo x ts)): resto) representación, o a través de un no-
lista (en addAll = Dard extensión que proporciona
este caso, se aplica de forma t: traverseUsingList existencial
recursiva el tamaño de (addAll rest ts) addAll cuantificación de variables de tipo (en
los niños, ts ), mientras Ahora tenemos una versión funcional con-
que concat flat- del algoritmo transversal habitual del en contra de la cuantificación
Decenas de una lista de listas a una árbol. universal).
lista simple. Árbol Inicialmente, el único subárbol en el En esta segunda entrega de funciones
transversal convierte un árbol (no trabajo programación nacional, hemos
lineal) en La cola es el árbol mismo. Entonces expandido
una secuencia lineal de referencias a re ed en la noción de idiomas HOT y
todos a propósito tomar el primer subárbol presentó un caso que tiene al menos
de los subárboles del árbol. Como de un conocimiento básico de tales
resultado, nosotros la cola de trabajo, agréguela al idiomas
ya no necesita una función resultado puede ser parte de una programación
de tamaño dedicada ing estructura lineal, y agregue el cur- saludable
ción porque el tamaño de un árbol es alquilar a los hijos de subtree al dieta. Incluso si no estás interesado en
simplemente el trabajo nosotros
longitud de su linealización: cola. Dado que nuestros árboles son programación funcional en cualquier
Preludio> rootValue t1 finitos, momento
1 este proceso continúa hasta que el pronto, el enfoque puede ayudarlo a
Preludio> tamaño t1 trabajo obtener
55 la cola está vacía Ahora podemos mejores resultados en cualquier
Preludio> transversal t1 invocar idioma, sea
[Nodo 1 [...], Nodo 2 esta función usando dos estratos causar mucha programación funcional
[...], Nodo 4 [...], diferentes Se utilizan ideas para implementar la
Nodo 3 [...], Nodo 5 [...]] egies para agregar elementos a la cola optimización
Preludio> map rootValue de trabajo: ing compiladores. Además, muchos
(atravesar t1) Preludio> map rootValue idiomas.
[1,2,4,3,5] (traverseUsingList [t1] de una forma u otra (como C #)
Preludio> (longitud. Transversal) (++)) están presentando las ideas, y Micro-
t1 [1,2,3,4,5] suave introdujo recientemente un
55 Preludio> map rootValue completamente
Una limitación de nuestro recorrido (traverseUsingList [t1] lenguaje de programación funcional,
la función es que el orden transversal (voltear (++))) F #, en su conjunto de idiomas. Dado
es [1,2,4,3,5] que
codificado: la función realiza En el primer caso, addAll es estándar Microsoft está en el negocio de
un recorrido de primer árbol en lista de concatenación, el sub- actual vender
profundidad, descender los hijos del árbol se agregan hasta el idiomas y herramientas, esto es un
ing tan lejos por el camino más a la final gran problema.
izquierda como de la cola, que asciende a una primera Estamos igualmente convencidos de
posible antes de visitar el resto de la entrada que claramente
árbol. Esto es típico para las imágenes disciplina de primera salida, y el comprender los sistemas de
recursivas. resultado es mecanografía puede ser
plementaciones del recorrido del un recorrido transversal del árbol en útil al escribir programas y
árbol, donde primer lugar. En evitando las trampas implicadas
la pila implícita de llamadas a el segundo caso, addAll es list concat- cuando el
funciones sirve enation con el orden de los la decisión se deja enteramente al
como una cola de trabajo de último en argumentos tiempo de ejecución.
entrar, primero en salir que volteado, para que los niños se Nuestra intención, sin embargo, no es
almacena a los niños aún por visitar. agreguen desarmar
Podemos hacer esta función al comienzo de la cola, y tenemos señorita idiomas que carecen de
más flexible al parametrizarlo nuestra disciplina de último en entrar, fundamento
diferentemente. En esta nueva primero en salir sistemas de tipo directamente. Todos
versión, el sulting en un recorrido de primer usamos una vari-
primer argumento es la lista árbol de profundidad. ety de lenguajes en nuestro trabajo
representa- (Java, C #
Me demás de www.haskell.org, la comunidad oficial wiki de Haskell,
encontramos Los siguientes recursos son bastante útiles:En 2008, la
programación orientada a objetos, sistemas, lenguajes y aplicaciones•
Conferencia de cationes (oopsla), Mark Dominus, un desarrollador líder de
Perl, diouna charla invitada sobre el sistema de tipos Haskell. Puedes leer sus
notas (y encontrar unenlace a sus diapositivas) en
http://blog.plover.com/talk/atypical-typing.html.el sitio Learn You a Haskell
for great good ofrece un sencillo tutorial de Haskell
en•http://learnyouahaskell.com/chapters.En noviembre de 2008, o'reilly
publicó la primera edición de•Haskell del mundo realpor Bryan o'Sullivan,
Don Stewart y John goerzen. desde entonces han creado un Sitio web con
contenido disponible gratuitamente en http://book.realworldhaskell.org

Convocatoria de trabajo/integral
I EEE Micro busca presentaciones de recientemente terminadas son las legibilidad y concisión. Póngase en
interés general para publicación en más bienvenido, como son los contacto con IEEE Micro en micro-ma
próximos números. Estas los trabajos tutoriales. Micro no acepta material @computer.org con cualquier
deben discutir el diseño, el publicado previamente.Consulte pregunta
rendimiento ,o aplicación de nuestro centro de autores
microordenador y (www.computer.org/mc/mi cro /
microprocesadorSistemas de author.htm) para palabra, figura y
evaluación. De especial interés son referencia límites Todos los envíos
los artículos sobreevaluación de pasan por revisión por
desempeño y carga de trabajo ización paresconsistente con otros técnicos
Resúmenes del trabajo en progreso y de nivel profesional publicaciones y
delas descripciones de obras edición para mayor claridad,

También podría gustarte