1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

77
1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen

Transcript of 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

Page 1: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

1

HSP(Haskell Server Pages)

Alejandro del Real ChicharroJosé Emilio Villena Irigoyen

Page 2: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

2

Índice Introducción La función page La sintaxis de HSP HJavaScript HSP Foro Web Conclusiones Futuros Trabajos Bibliografía

Page 3: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

3

Introducción No hace mucho tiempo, la World Wide Web estaba formada casi exclusivamente de

páginas estáticas. Hoy, sin embargo, el uso de páginas dinámicas en la Web se ha incrementado hasta tal punto de necesitar mejores herramientas para la creación de éstas.

Los programadores comienzan a usar algunos lenguajes script especializados que permiten mezclar XML con código, p.e. PHP, ASP o también puedan usar CGI.

La mayoría de los lenguajes compartían los mismos defectos, y algunos hasta varios de estos. Ellos modelaban texto HTML como texto sin formato, y esto violaba uno de los principios de abstracción de Tennent.

Page 4: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

4

Introducción Se busca un lenguaje funcional que soporte un modelo de programación completo y la

facilidad de uso de un lenguaje script especializado, mientras aún mantenga el gran potencial de XML.

En el 2000, Erik Meijer y Danny van VelzenErik Meijer y Danny van Velzen presentaron lo que ellos llamaron como ‘Haskell Server PagesHaskell Server Pages’ (HSP), un lenguaje de programación Web de dominio específico, basado en la funcionalidad de la programación del lenguaje Haskell.

Introduciendo un nuevo tipo de datos data XML que garantizaba la correcta formación de páginas dinámicas y una mejor integración de XML con otros códigos.

Permitir a los programadores usar fragmentos de sintaxis XML en código Haskell, y viceversa, permitir embeber expresiones Haskell dentro de fragmentos XML.

Page 5: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

5

Introducción

Código ASPCódigo ASP::<TABLE border=”1”> <% For x = 1 To 16 %>

<TR> <% For y = 1 To 16 %>

<TD bicolor = <%= genColor(x,y) %>> (<%= x %>,<%= y %>)

</TD> <% Next %> </TR>

<% Next %></TABLE>

Sacamos el bucle para hacer la página más ordenada.

Page 6: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

6

IntroducciónCódigo ASPCódigo ASP::<TABLE border=”1”> <% For x = 1 To 16 %>

<TR> <% Call GenData (x) %> </TR>

<% Next %></TABLE>

El problema es que ASP no permite esto.

<% Sub GenData(x) %> <% For y = 1 To 16 %> <TD>

(<%= x %>,<%= y %>)

</TD> <% Next %><% End Sub%>

Tendríamos que ejecutarlo dentro de un módulo de Visual Basic.

<% Sub GenData(x) For y = 1 To 16 Response.Write “<TD bgcolor=“

Response.Write genColor(x,y) Response.Write “>”

Response.Write “(“& x &”,” & y & “)”Response.Write “</TD>”

Next End Sub %>

Page 7: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

7

IntroducciónCódigo en Haskell:Código en Haskell:table :: TABLEtable =

<TABLE border=”1”><% mkRows cells %>

</TABLE>cells ::[[(Int, Int)]]cells =

[ [(x,y) | x [1..16] ] | y [1..16] ]mkRows:: [[(Int, Int)]] [TR]mkRows = map $ \cs

<TR><% mkColumns cs %></TR>mkColums :: [[(Int,Int)]] —>[TD]mkColums = map $ \c

<TD bgcolor = (genColor c)><% c %>

</TD>

Está todo más estructurado.

$ Es una función asociativa por la derecha para la eliminación de paréntesis

Page 8: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

8

Introducción

A parte de las extensiones puramente sintácticas, HSP también facilita un modelo de programación con tipos de datos, clases y funciones que ayuden con algunas tareas de la programación Web.

Por ejemplo: Mantener el estado de los usuarios en transacciones usando sesiones. Mantener el estado de aplicaciones entre transacciones con diferentes

usuarios. Acceder a consultas de datos y variables de entorno

Page 9: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

9

La función page Para generar una completa aplicación de páginas HSP, necesitamos definir la

función pagepage. De forma análoga a la función mainmain de Haskell.

la función pagepage es llamada cuando una página HSP es requerida.

page = <HTML> <HEAD>

<TITLE>¡Hola Mundo!</TITLE>

</HEAD></HTML>

Page 10: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

10

La función page

Como un documento válido XML (o bien XHTML) es también una de las fuentes principales de los programas HSP, necesitamos construir páginas que nos permitan utilizar la potencia de XML junto con el lenguaje Haskell.

Por ejemplo un trozo de código en XML que muestra un reloj con la hora de cuando un página fue pedida sería:

Páginas XML y páginas HíbridasPáginas XML y páginas Híbridas

<HTML> <HEAD><TITLE>Página XML</TITLE></HEAD> <BODY>

<H1>¡Hola mundo!</H1><P>Página pedida con <% getSystemTimegetSystemTime %></P>

</BODY></HTML>

Page 11: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

11

La función page

Y el mismo código ya aplicado a una página HSP sería:

Páginas XML y páginas HíbridasPáginas XML y páginas Híbridas

page=<HTML> <HEAD><TITLE>Página XML</TITLE></HEAD> <BODY>

<H1>¡Hola mundo!</H1><P>Página pedida con <% getSystemTimegetSystemTime

%></P> </BODY></HTML>

Aunque hay un ligero problema con estas páginas. La función getSystemTime reside en el modulo System.Time, el cuál necesita ser importado para que la función sea usada.

Page 12: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

12

La función page

Con HSP no habría problemas pero con pero en páginas XML no hay ningún lugar donde poder añadir la importación.

Para salvar este problema se introducen las páginas híbridas que contienen una combinación de páginas XML con un nivel alto de declaraciones.

Páginas XML y páginas HíbridasPáginas XML y páginas Híbridas

<%import System.Time%> <HTML> <HEAD><TITLE>Página XML </TITLE></HEAD> <BODY>

<H1>¡Hola mundo!</H1><P>Página demandada <% getSystemTime %></P>

</BODY></HTML>

Page 13: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

13

La función page

Para poder crear páginas híbridas se añade una nueva función más elaborada de pagepage, especificando como una página correcta en HSP, puede parecerse a:

Sintaxis formal de una páginaSintaxis formal de una página

page : : = module | xml

| <% module %> xml

Podemos utilizar un módulo normal de HSP, un árbol completo XML, o bien una combinación de los dos.

Page 14: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

14

La función page

¿Cuál es el tipo de la función de nuestro ejemplo “hola mundo”?

Solución más simple: Dejar el tipo XML

Pero no es tan sencillo, porque permitimos cálculos impuros

cálculos con efectos laterales para ser embebidos dentro de los fragmentos de XML.

Ejemplo de computación embebida: getSystemTime con el tipo IO Time

Computación embebida y mónada HSPComputación embebida y mónada HSP

Page 15: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

15

La función page

HSP suspende la computación embebida hasta que es evaluada explícitamente

Parece que las funciones devuelven valores XML puros, pero pueden contener computaciones no evaluadas

No hay forma de distinguir entre valores XML puros y los que contienen computaciones no evaluadas

Computación embebida y mónada HSPComputación embebida y mónada HSP

Page 16: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

16

La función page

Para solucionar esto se introdujo una mónada HSP Encapsula los efectos laterales

Proporciona entorno E/S a las páginas Web

Todas las expresiones XML serán resueltas computando una mónada HSP.

Ejemplo

<p> ¡Hola mundo!</p> Tiene tipo HSP XML a pesar de no tener efectos laterales

No es algo perfecto, pero es preferible a no tener efectos laterales nunca

Computación embebida y mónada HSPComputación embebida y mónada HSP

Page 17: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

17

Sintaxis HSP

Encuentro entre XML y Haskell

HolaMundol = <p>¡Hola Mundo!</p>

Hay dos cosas interesantes que comentar No necesitamos usar ningún mecanismo de escape para dejar el

contexto del código cuando queremos escribir el fragmente XML, en HSP todos los fragmentos XML están garantizados para estar

siempre bien-formados.

Page 18: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

18

Sintaxis HSP Las expresiones malformadas darían error

helloWorld = <p>Hello World!</q>

Las etiquetas funcionan ellas solas cómo escapes boldHelloWorld = <p><b>Hello World!</b></p>

Siempre que queramos que el contenido interno sea evaluado por una expresión, deberemos usar caracteres de escape

hello name = <p>Hello <% name %>!</p>

Page 19: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

19

Sintaxis HSP Queremos también que nuestros elementos XML sean capaces de tener

atributos

RedHelloWorld :: HSP XML

redHelloWorld =

<p style="color:red">Hello World!</p> Al igual que los hijos, los valores de atributos pueden también ser computados

a partir de expresiones embebidas

hwColor :: String -> HSP XML

hwColor c =

<p style=("color:" ++ c)>Hello World!</p>

Page 20: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

20

Sintaxis HSP

Todas las páginas HSP deben definir y exportar una página de función definiendo el contenido de la página.

page = <html>

<head><title>Hello World!</title></head>

<% helloBody %>

</html>

¡¡¡Ya tenemos nuestra primera página HSP!!!

Page 21: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

21

Sintaxis HSP - Concordancia de patrones

Concordancia de Elementos Lo primero de todo lo que podemos comparar directamente en elementos,

cómo

isImg <img/> = TrueisImg _ = False

Nuestra interpretación intuitiva de lo de arriba es que implementa isImg devolverá True si un elemento img se da, y False en otro caso

Page 22: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

22

Sintaxis HSP - Concordancia de patrones

Concordancia de Atributos Para concordancia de patrones en atributos, primero necesitamos

considerar cómo queremos usarlos. Lo primero de todo, en XML el orden de atributos es irrelevante, por lo que para la instancia de dos elementos

<img src="img/myImg.jpg" alt="My image" />

y,

<img alt="My image" src="img/myImg.jpg" />

¡Son equivalentes!

Page 23: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

23

Sintaxis HSP - Concordancia de patrones

Concordancia de Hijos La concordancia de patrones en hijos se puede escribir cómo en este

ejemplo

getPText <p><% PCDATA t %></p> = t

Comparar un simple hijo es bastante simple, pero para ejemplos más complicados existe un problema

“comparar un número arbitrario de elementos <p>”

o “empezar por comparar un elemento <h1>, seguido por uno o más

ocurrencias de un elemento <h2> y un elemento <p> en la secuencia”

Page 24: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

24

Sintaxis HSP - Concordancia de patrones

Para esto hemos desarrollado HaRP (Haskell Regular Patterns). El sistema para patrones de expresiones regulares en Haskell

Ejemplo para obtener todo el texto de los párrafos de un documento

getText :: XML -> [String]

getText <body>[

<p><% PCDATA t %></p>*

]</body> = t

Denota que debería haber 0 o más p encerrados en el elemento body

Page 25: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

25

Sintaxis HSP – Sintaxis formal

Sintaxis formal Extendemos la gramática Haskell con nuevas producciones de

expresiones XML, las cuales añadimos al lenguaje cómo una expresión atómica posible

aexp ::= var| lit| ( exp )...| xml

La nueva manera de expresión, xml, puede ser también un elemento cerrado con hijos, o una etiqueta vacía auto-contenida

xml ::= <name attrs>child...child</name>| <name attrs/>

Page 26: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

26

Sintaxis HSP – Sintaxis formal

Los atributos son pares nombre-valor, seguidos opcionalmente por una expresión extra

attrs ::= attrs1 aexp| attrs1

attrs1 ::= name = aexp ... name = aexp

Un hijo puede ser un elemento jerarquizado, PCDATA o una expresión Haskell embebida

child ::= xml| PCDATA| <% exp %>

Page 27: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

27

Sintaxis HSP – Sintaxis formal

Un nombre en XML puede ser calificado opcionalmente por un espacio de nombres a cuyo elemento pertenece. Nuestra producción de nombre queda así

name ::= string : string| string

donde el espacio de nombres definido anteriormente está especificado

Page 28: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

28

Sintaxis HSP – Entorno Las páginas HSP tienen acceso a un entorno especial que contiene

información si tenemos en cuenta el contexto en el cual son evaluadas. Los componentes principales son:

Petición: Peticiones HTTP que iniciaron la llamada a la página Respuesta: Respuesta HTTP que ha sido generada, la cual se enviará con

los resultados de la llamada a la página Aplicación: Contiene datos con visibilidad de aplicación, por ejemplo

datos que persisten entre transacciones de páginas Sesión: Contiene datos que pertenecen a un cliente específico

Page 29: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

29

Sintaxis HSP – Entorno

Entorno de Petición

ASP Request (“hello”)

PHP $_REQUEST[“hello”]

HSP getParameter “hello”

Page 30: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

30

Sintaxis HSP – Entorno

En el entorno del programación lo más importante es consultar cadenas de caracteres (pares nombre-valor) de la forma

param1 = valor1&…&paramn = valorn

Los parámetros en la petición pueden ser accedidos usando las funciones getParameter :: String -> HSP (Maybe String) readParameter :: Read a => String -> HSP (Maybe a)

Page 31: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

31

Sintaxis HSP – Entorno Entorno de Respuesta

Los componentes de respuesta almacenan cabeceras que serán enviadas de vuelta al cliente receptor con los contenidos de los documentos. Estos son conjuntos que usan funciones especializadas cómo

setNoCache :: HSP ()

En HSP ninguna salida debería ser añadida a la respuesta manualmente, todos los contenidos deberían estar generados por la función de página, garantizando la correcta formación del XML generado

Por ejemplo, no sería correcto

<p>Hola <% Response.write(nombre) %></p>

miMensaje :: String-> HSP XML

miMensaje nombre = <p>Hola <% nombre %></p>

Page 32: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

32

Sintaxis HSP – Entorno Entorno de Aplicación

El componente de Aplicación contiene datos que están compartiendo entre todas las páginas de una aplicación, y que persiste entre peticiones simples a páginas

El tipo de Aplicación es por si mismo abstracto, por lo que la única manera de crear un valor del tipo que está usando la aplicación es

toApplication :: (Typeable a) => a -> Application

Page 33: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

33

Sintaxis HSP – Entorno El entorno de Aplicación es actualmente un tipo de envoltorio (Wrapper)

dinámico, el cual es usado para habilitar al componente de la Aplicación ser de cualquier tipo

newtype Application =MkApp {appContents :: Dynamic}toApplication = MkApp . toDynamic

Para acceder a los datos de aplicación de dentro de una página, un programador puede usar la función

getApplication :: (Typeable a) => HSP a

que devuelve un valor de su particular tipo de Aplicación

Page 34: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

34

Sintaxis HSP – Entorno Ejemplo (un contador)

Queremos actualizar los valores del contador necesitamos almacenarlo en una referencia

Type MyApplication = Mvar Int

Ponemos estas declaraciones en un módulo que llamamos MiAplicacion.hs y añadimos

toMyApplication :: MyApplication -> ApplicationtoMyApplication = toApplication

getMyApplication :: HSP MyApplicationgetMyApplication = getApplication

Page 35: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

35

Sintaxis HSP – Entorno

Función para incrementar el contadorincrContador :: HSP ()incrContador = do

ctr <- getMyApplicationdoIO $ modifyMVar ctr (+1)

Función para leer el valor actual del contadorleerContador :: HSP IntleerContador = do

ctr <- getMyApplicationdoIO $ readMVar ctr

Page 36: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

36

Sintaxis HSP – Entorno Ya sólo queda darle un valor inicial al contador

En el modulo Aplicación.hsp primeramente hemos de importar MiAplicacion.hs, y la definición

initApplication = do

ctr <- newMVar 0

return $ toMyApplication ctr

Page 37: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

37

Sintaxis HSP – Entorno La página

import MiAplicacionpage = do

incrementarContador<html>

<head><title>Hola visitante nr <%

leerContador %></title>

</head><body>

<h1>¡Hola!</h1><p>Eres el visitante nr <%

leerContador %> de esta página.</p>

</body></html>

Page 38: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

38

Sintaxis HSP – Entorno Entorno de Sesión

Los componentes de Sesión son un repositorio de datos que deja a las páginas mantener un estado entre transacciones

Acceso al repositorio getSessionVar :: String -> HSP (Maybe String) setSessionVar :: String -> String -> HSP ()

Configurar tiempo de vida setSessionExpires :: ClockTime -> HSP ()

Forzando su terminación abandon :: HSP () almacenados en el lado

del cliente usando cookies

Page 39: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

39

HJavaScript Surgen la necesidad de un lenguaje script que pueda dar funcionalidad a

nuestras páginas del lado del cliente

HJScript se ha desarrollado con dos metas: Proveer al programador una sintaxis lo más abstracta posible

Proveer una sintaxis cómo la original (JavaScript)

Obviamente esto no es posible

Page 40: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

40

HJavaScript

Para modelar un lenguaje imperativo vamos a trabajar con una mónada

La mónada será escritora-estado

Parte escritora: Usada para el código JavaScript a la salida

Parte estado: Usada para la gestión del gensym

Page 41: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

41

HJavaScript

Las 2 funciones básicas en la mónada, aparte de devolver y registrar son

newVarName :: HJScript StringnewVarName = do s <- get

put $ s+1return $ “var” ++ show s

outputCode :: JsStmt () -> HJScript ()outputCode = tell

Page 42: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

42

HJavaScript También necesitamos una función evaluadora que genere el código de salida

hjscript :: HJScript t -> HJState -> (t, JSBlock ())hjscript script s = runWriter $ runStateT script s

y una función que nos deja evaluar una computación dentro de otra:

hjsInside :: HJScript t -> HJScript (t, JSBlock ())hjsInside script = censor (const EmptyBlock) $ listen script

Page 43: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

43

HJavaScript Sintaxis

Para declarar una variable nombreVar <- var nombreVar <- varWith valorInicial

Para declarar una función

function (a,b) {return a+b

}

function \(a,b) ->return (a+:b)

En JavaScript

En HJavaScript

Page 44: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

44

HJavaScript Elección de un símbolo operador $$

Así para invocar funciones en HJavaScript podremos hacerlo así

call myFunction (a,b)

O bien así

myFunction$$(a,b)

Page 45: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

45

HJavaScript Usar métodos de objetos en JavaScript

Math.abs(n)

d.getYear()

En HJavaScript sería

Math#abs$$(n)

d#getYear()

Page 46: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

46

HJavaScript Para integrar HJavaScript con el resto de HSP necesitamos escribir instancias

para IsXML y IsAttrValue

IsXML es necesario para Ejecutar un script cuando la página se carga Definir funciones en la sección de cabecera

IsAttrValue es necesario para Atributos de eventos: onClick, onEvent, …

Page 47: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

47

HJavaScript Instancia isXML

instance IsXML (JsBlock ()) wheretoXML b =

<script language=”JavaScript”><% pprBlock b %></script>

Instancia isAttrValue

instance IsAttrValue (JsBlock ()) wheretoAttrValue b = toAttrValue $ pprBlock b

Page 48: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

48

Foro en HSP Diseño del foro:

Foro organizado en hilos

Cada hilo consta de uno o más mensajes

Cada mensaje consta de: Texto Quién lo escribió Cuándo lo escribió

Page 49: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

49

Foro en HSP

Configuraremos una base de datos

Inicialmente suponemos que podemos acceder a la base de datos

Empezaremos desarrollando un foro muy simple en el que sólo se muestre un mensaje, y lo iremos ampliando gradualmente

Page 50: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

50

Foro en HSP

Definición de registros

data Hilo = Hilo {tema :: String,mensajes :: [Mensaje]

}

data Mensaje = Mensaje {autor, contenido :: String,fecha :: CalenderTime

}

Page 51: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

51

Foro en HSP

Para mostrar un mensaje:

mostrarMensaje :: Mensaje -> XMLInformación del mensaje grabado en si mismo

o bien

mostrarMensaje :: Mensaje -> HSP XMLInformación extra de otras fuentes

Page 52: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

52

Foro en HSP Nos quedamos con la segunda opción

mostrarMensaje :: Mensaje-> HSP XML

mostrarMensaje mensaje =<fieldset>

<legend><b><% mensaje#autor %></b><i><% mensaje#fecha %></i>

</legend><% nl2br $ mensaje#contenido %>

</fieldset>

Page 53: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

53

Foro en HSPSe mostraría algo así

Page 54: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

54

Foro en HSP Para simplificar el foro, esta será la manera por defecto de mostrar un mensaje

instance IsXML Mensaje where

toXML = mostrarMensaje

Ahora vamos a definir una función para mostrar un hilo entero Asumimos que todos los hilos contienen al menos un mensaje Colocamos cada mensaje debajo del siguiente

Page 55: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

55

Foro en HSP Función que muestra un hilo

mostrarHilo :: Hilo -> HSP XMLmostrarHilo hilo = do

let disposicionMensajes = foldl1 (^^) $ map block $ hilo#mensajes enlacePrincipal = aLink “indice.hsp” “Volver al índice”toXML $ h1 (hilo#tema) ^^ enlacePrincipal ^^

disposicionMensajes ^^ enlacePrincipal

^^ Es un combinador que coloca cualquier objeto en disposición vertical.

Page 56: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

56

Foro en HSP Código de: mostrarHilo.hsp

import HSP Forum.Databases (getThread)import HSP.Layoutpagina = do mthid <- getParameter “threaded”

case mthid ofNothing -> redirect “indice.hsp”Just thId -> do

mthread <- darHilo thIdcase mthread of

Nothing -> redirect “indice.hsp”Just hilo -> paginaHilo hilo

paginaHilo hilo =<html>

<head><title><% hilo#tema %></title><body><% mostrarHilo hilo %></body>

</html>

mostrarHilo hilo = ...mostrarMensaje mensaje = ...

Page 57: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

57

Foro en HSP Quedaría algo así

Page 58: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

58

Foro en HSP

Ahora vamos a definir la página índice de los hilos

Necesitamos recuperar la id de los hilos y la línea del tema para todos los mensajes

Dar formato a los pares <id,tema> en un enlace que nos llevará al hilo.

Listar todos los enlaces

Page 59: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

59

Foro en HSP Función para crear un enlace a un tema

enlaceHilo :: Int -> String -> HSP XML

enlaceHilo threaded =

aLink (“mostrarHilo.hsp?idHilo=” ++ show threaded)

Función para listar los hilos

listaHilos :: [(Int, String)] -> HSP XML

listaHilos hilos = ul $ map (uncurry enlaceHilo) hilos

Page 60: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

60

Foro en HSP

La página dinámica resultante

page = do mthinfo <- darInformacionHilolet thinfo = maybe [] id mthinfo<html>

<head><title><% nombreForo %></title></head><body>

<% h1 nombreForo %><% listaHilos thinfo %>

</body></html>

Page 61: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

61

Foro en HSP Conexiones a la base de datos

HaskellDB

Hay problemas con accesos concurrentes

Asegurar que sólo hay un recurso de conexión

Implementar un mecanismo para controlar quién y cuándo lo usa

Page 62: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

62

Foro en HSP Creamos un módulo llamado MiAplicacion.hs

donde definimos

type ConexionBD = (Database -> IO a) -> IO a

type MiAplicacion = (Mvar (),ConexionBD)

myToApplication :: MyApplication -> ApplicationmyToApplication = toApplication

myGetApplication :: HSP MyApplicationmyGetApplication = toApplication

Page 63: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

63

Foro en HSP Definimos dos funciones para trabajar sobre las conexiones

conexionBD :: (Database -> IO a) -> HSP aconexionBD q = do (_, conn) <- myGetApplication

doIO $ conn q

conexionBDsegura :: (Database -> IO a) -> HSP aconexionBDsegura q = do (lock, conn) <- myGetApplication

doIO $ bracket_(takeMVar lock)(putMVar lock ())(conn q)

Asegura que el programa no se pare si se produce una excepción

Page 64: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

64

Foro en HSP

Nos queda instalar el fichero Aplicacion.hs

initApplication = do lock <- newMVar ()

return $ myToApplication (lock, conn)

Asumimos que conn está definido en otra parte, no lo veremos en el futuro dado que HaskellDB es muy dependiente del sistema de bases de datos usado.

Page 65: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

65

Foro en HSP Para obtener todos los mensajes de un hilo particular

darHilo :: Int -> HSP (Maybe Hilo)darHilo idHilo = do

r1 <- conexionBD $ \db -> query db consultaHiloscase r1 of

[] -> return Nothing -- No existe el hilo[rec] -> do

r2 <- conexionBD $ \db -> query db consultaMensajesreturn $ Hilo { tema = rec!Th.tema, mensajes = map hacerMensaje r2 }

where consultaHilos = dot <- table Th.hilosrestrict (t!Th. idHilo.==. constant idHilo)return t

consultaMensajes = dot <- table Th.mensajesrestrict (t!Th. idHilo.==. constant idHilo)order [asc t Th.mensajeNr]return t

hacerMensaje rec = Mensaje {autor = rec!Th.autor,time = rec!Th.fecha,contenidos = rec!Th.contenido }

Page 66: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

66

Foro en HSP Función para almacenar hilos en su tabla correspondiente

darInformacionHilo :: HSP [(Int, String)]darInformacionHilo = do

r1 <- conexionBD $ \db -> query db (table Th.hilo)return $ map (\rec -> (rec!Th.idHilo, rec!Th.tema)) r1

Creando/Enviando nuevos mensajes Comenzar un nuevo hilo o responder a un hilo existente Responder a un hilo se hará en una página aparte Visualizar mensajes tras enviarlos Introducimos una página intermedia entre la página de envío y la página

que muestra los datos

Page 67: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

67

Foro en HSP Página intermedia

page = do[thId, autor, contenidos, tema] <-

mapM getParameter [“idHilo”, “autor”,“contenidos”, “tema”]

ti <- case thId ofJust thId -> do

conexionBDsegura $ insertPost autor contenidos thId

return thIdNothing -> do

conexionBDsegura $ insertarHiloDeMensajes tema autor mensaje

redirect $ “mostrarHilo.hsp?idHilo=” ++ show tiwhere insertarMensaje autor conts thid = \db -> do

let (Just aut, Just txt) = (autor, conts)time <- getCurrentTime

Page 68: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

68

Foro en HSPinsert db Th.posts (Th.idHilo << thId #

Th.autor << autor #Th.fecha << time #Th.contenido << txt )

insertarHiloDeMensajes tema autor conts = \db -> dolet (Just aut, Just txt) = (autor, conts)time <- getCurrentTimeinsert db Th.hilos (Th.tema << tema)[rThId] <- query db maxThidConsultalet thId = rThId!Th.idHiloinsert db Th.mensajes (Th.idHilo << thId #

Th.autor << autor #Th.fecha << fecha #Th.contenido << txt )

maxThidConsulta = dot <- table Th.hilospreoject (Th.idHilo << max t!Th.idHilo)

Page 69: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

69

Foro en HSP Formulario para enviar Mensaje

formularioMensaje :: (Maybe Int) -> HSP XMLformularioMensaje mthreadId =

<form method=Post action=“handledata.hsp”><% borderTable 0 $

filaDelTema ++[filaAutor, filaContenido, [idHiloOculto, botonEnvio]]

%></form>

Page 70: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

70

Foro en HSPwhere filaDelTema =

case mthreadId ofJust _ -> []Nothing -> [withLabel textField “tema”]

filaAutor = withLabel textField “autor”filaContenido = withLabel textArea “contenido”idHiloOculto = fmap (hidden “idHilo”) mthreadIdbotonEnvio = submit “Enviar” `set`

[“value” := “Submit post”]

Definimos la función withLabelwithLabel :: (String -> HSP XML) -> String -> [HSP XML]withLabel f n@(c:cs) =

[label n (toUpper c : cs ++ “:”) , f n]

Page 71: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

71

Foro en HSP Para incluir el formulario con hilos, necesitamos retocar ligeramente el

código para asegurar que tenemos acceso al id del hilo

paginaHilo hilo idHilo =<html><head><title><% hilo#tema %></title></head><body>

<% mostrarHilo hilo^^ formularioMensaje (Just idHilo) %>

</body></html>

Page 72: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

72

Foro en HSP

La página dedicada a comenzar los hilos, comenzarHilo.hsp, será

import formularioMensaje

page = <html>

<head><title>Nuevo Hilo</title></head>

<body><% formularioMensaje Nothing %></body>

</html>

Page 73: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

73

Conclusiones La utilización de la potencia de un lenguaje funcional como es Haskell junto

con la simplicidad de la utilización de un lenguaje script han hecho de HSP un lenguaje tan bueno como sus iguales.

El área donde debemos realizar mayores esfuerzos para mejorar el lenguaje es en la construcción de librerías, donde los otros lenguajes tienen mayor ventaja.

La meta inicial en la construcción del diseño del lenguaje HSP era que tuviera el mismo poder expresivo que Haskell para atraer al programador funcional experto, y además fuera muy intuitivo para el programador Web novato.

El problema de que no esté muy extendido es que necesita de una comunidad activa que ayude con extensiones y mejoras, como librerías, manuales y programas de ejemplos.

Page 74: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

74

Futuros trabajos El modelo de programación presentado define la sintaxis y la semántica de la

extensión XML a Haskell. Pero hay algunas extensiones que podrían introducirse para simplificar la forma de expresar con certeza algunos modismos.

Una extensión que vendría conveniente cuando los patrones enlacen elementos es permitir resumir el nombre del elemento en la sintaxis XML concreta.

Otra posible extensión es permitir una forma de búsqueda de atributo que tendrá éxito independientemente de la existencia del atributo o no.

Page 75: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

75

Futuros trabajos Otra cosa a tener en cuenta, es la implementación, ya que ésta proporciona una

completa funcionalidad al sistema HSP.

Una solución al horrible mensaje de error que aparece en el pre-procesador sintáctico puro, antes de comprobar los tipos es extender el pre-proceso con un analizador de tiposanalizador de tipos que pueda manejar nuestra sintaxis XML tan bien como el código Haskell incluido en todas las extensiones que HSP usa.

Crear numerosos documentos de ayuda en pdf, y conseguir desarrollar un gran número de librerías para conexiones a bases de datos.

Page 76: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

76

Bibliografía Erik Meijer. Server-side Web Scripting in Haskell. Journal of Functional

Programming, 1(1), 1998.

Erik Meijer and Mark Shields. XMλ: A Functional Language for Constructing and Manipulating XML Documents. (Draft), 1999.

Paul Graunke, Shriram Krishnamurthi, Steve Van der Hoeven and Matthias Felleisen. Programming the Web with High-level Programming Languages. In Proceedings of the European Symposium On Programming, 2001.

Erik Meijer and Danny van Velzen. Haskell Server Pages: Functional Programming and the Battle for the Middle Tier. In Proceedings of the Haskell Workshop, 2000.

Ruiz, B.C., Gutierrez, F., Guerrero, P., Gallardo, J.E. Razonando con Haskell. Una introducción a la Programación Funcional. Los autores. 2000

Broberg, Niklas. Thesis for the Degree of Master of Science.Haskell Server Pages (DRAFT) Chalmers University of Technology 2005

Documentos y librosDocumentos y libros

Page 77: 1 HSP(Haskell Server Pages) Alejandro del Real Chicharro José Emilio Villena Irigoyen.

77

Bibliografía ASP.NET home. http://msdn.microsoft.com/asp.net/.

PHP: Hypertext Processor home. http://www.php.net/.

WASH home.http://www.informatik.uni-freiburg.de/~thiemann/haskell/WASH/.

Extensible Markup Language. http://www.w3c.org/XML.

Buscadores científicosBuscadores científicos

GOOGLE Scholar. http://scholar.google.com/

SCIRUS. Buscador de ciencia. http://www.scirus.com/srsapp/Buscador de publicaciones científicas y de páginas Web de contenido

científico.