1 hsp(haskell server pages) alejandro del real chicharro josé emilio villena irigoyen
TRANSCRIPT
1
HSP(Haskell Server Pages)
Alejandro del Real ChicharroJosé Emilio Villena Irigoyen
2
Índice Introducción La función page La sintaxis de HSP HJavaScript HSP Foro Web Conclusiones Futuros Trabajos Bibliografía
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.
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.
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.
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 %>
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
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
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>
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>
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.
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>
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.
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
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
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
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.
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>
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>
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!!!
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
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!
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”
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
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/>
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 %>
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
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
29
Sintaxis HSP – Entorno
Entorno de Petición
ASP Request (“hello”)
PHP $_REQUEST[“hello”]
HSP getParameter “hello”
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&…¶mn = 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)
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>
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
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
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
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
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
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>
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
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
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
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
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
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
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)
45
HJavaScript Usar métodos de objetos en JavaScript
Math.abs(n)
d.getYear()
En HJavaScript sería
Math#abs$$(n)
d#getYear()
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, …
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
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ó
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
50
Foro en HSP
Definición de registros
data Hilo = Hilo {tema :: String,mensajes :: [Mensaje]
}
data Mensaje = Mensaje {autor, contenido :: String,fecha :: CalenderTime
}
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
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>
53
Foro en HSPSe mostraría algo así
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
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.
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 = ...
57
Foro en HSP Quedaría algo así
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
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
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>
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
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
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
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.
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 }
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
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
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)
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>
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]
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>
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>
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.
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.
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.
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
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.