Funktionale Programmierung und das Web Alice Server Pages Funktionale Programmierung und das Web Simon Georg Pinkel, Betreuer: Guido Tack & Thorsten Brunklaus
Gliederung Anforderungen Entwurf Beispiel Implementierung Architektur Syntax Cookies Beispiel Implementierung Compileserver Word Sequences verwandte Projekte Zusammenfassung Fazit Ausblick Demo
Anforderungen Compiler zur Bearbeitung/Interpretation von HTML-seiten mit eingebetteten Programmfragmenten Handhabung von dynamischem Input wie Formularvariablen oder Cookies Datenbankschnittstelle Niedrige Reaktionszeiten
Architektur Datenbank Compiler index.asp Http Server
Architektur : ML Server Pages Datenbank Msp-Compiler index.msp Http Server Cache index.cgi CGI
Architektur : Alice Server Pages Http Server CGI Cache Interfaceclient (C) index.stc Datenbank Compileserver (Alice) index.amsp
Syntax Alice lässt sich folgendermassen einbetten: <?AMSP [alice-programm] ?> <?AMSP= [alice-ausdruck beliebigen typs] ?> <?AMSP$ [wordsequence] ?>
Syntax Alice lässt sich folgendermassen einbetten: <?AMSP [alice-programm] ?> <?AMSP= [alice-ausdruck beliebigen typs] ?> <?AMSP$ [wordsequence] ?> Um auf Formularvariablen/Cookies zuzugreifen, muss ein Skript einen speziellen Typ „formvar“ bzw. „cookies“ nach dieser Grammatik deklarieren: start ::= recordTy ty | primTy option | primTy eoption recordTy | ty * ... * ty ( ty ) ty list | ty vector (*) { tyrow } tyrow lab : ty [, tyrow] primTy int | real | char | string | bool | file (*) nicht erlaubt bei cookies
Cookies Lokal(beim Browser) gespeicherte Datenpakete verteilter Zustand der Server Page Programmierer muss Typ „cookies“ definieren Wert „cookies:cookies“ enthält eingehende Cookiedaten können über folgende Funktionen gesendet/gelöscht werden: val setCookies : cookies -> unit val deleteCookie : string -> unit
Beispiel ../index.amsp?n=6 <?AMSP type formvar = { n : int option } ?> ../index.amsp?n=6 <html><head>...</head> <body> <ul> </ul></body></html> val _ = List.app (fn x=> print("<li>" ^ Int.toString x) List.tabulate(#n formvar,fak)
Beispiel ../index.amsp?n=6 ../amspcache/<md5>.aml type formvar = { n : int option } ?> ../index.amsp?n=6 <html><head>...</head> <body> <ul> </ul></body></html> val _ = List.app (fn x=> print("<li>" ^ Int.toString x) List.tabulate(#n formvar,fak) type formvar = { n : int option } val _ = print („ ") val _ = List.app ... ../amspcache/<md5>.aml </ul> </body></html> val formvar = ... <html><head>...</head> <body> <ul>
Beispiel ../index.amsp?n=6 ../amspcache/<md5>.aml type formvar = { n : int option } ?> ../index.amsp?n=6 <html><head>...</head> <body> <ul> </ul></body></html> val _ = List.app (fn x=> print("<li>" ^ Int.toString x) List.tabulate(#n formvar,fak) type formvar = { n : int option } val _ = print („ ") val _ = List.app ... ../amspcache/<md5>.aml </ul> </body></html> val formvar = ... <html><head>...</head> <body> <ul> <html><head>...</head> <body> <ul> <li>1 <li>2 <li>6 <li>24 <li>120 </ul> </body></html> HTML-output
Implementierung: Compileserver Anfrage auf index.amsp: mit .amsp assoziiertes CGI-Programm(Interfaceclient) wird aufgerufen CGI Cache Interfaceclient (C) <md5sum>.stc Compileserver (Alice) index.amsp
Implementierung: Compileserver Anfrage auf index.amsp: mit .amsp assoziiertes CGI-Programm(Interfaceclient) wird aufgerufen Interfaceclient sammelt Daten und sendet sie an Compileserver CGI Cache Interfaceclient (C) <md5sum>.stc Socket - Kommunikation Compileserver (Alice) index.amsp
Implementierung: Compileserver Anfrage auf index.amsp: mit .amsp assoziiertes CGI-Programm(Interfaceclient) wird aufgerufen Interfaceclient sammelt Daten und sendet sie an Compileserver Compileserver checkt, ob Cache Eintrag (MD5-summe vom lokalen Pfad der Source) vorhanden bzw. up-to-date und kompiliert gegebenenfalls CGI Cache Interfaceclient (C) <md5sum>.stc Socket - Kommunikation Compileserver (Alice) index.amsp
Implementierung: Compileserver Anfrage auf index.amsp: mit .amsp assoziiertes CGI-Programm(Interfaceclient) wird aufgerufen Interfaceclient sammelt Daten und sendet sie an Compileserver Compileserver checkt, ob Cache Eintrag (MD5-summe vom lokalen Pfad der Source) vorhanden bzw. up-to-date und kompiliert gegebenenfalls Compileserver ruft über ComponentManager.Eval das Kompilat auf CGI Cache Interfaceclient (C) <md5sum>.stc Socket - Kommunikation Struktur mit Zustand Compileserver (Alice) index.amsp
Implementierung: Compileserver Anfrage auf index.amsp: mit .amsp assoziiertes CGI-Programm(Interfaceclient) wird aufgerufen Interfaceclient sammelt Daten und sendet sie an Compileserver Compileserver checkt, ob Cache Eintrag (MD5-summe vom lokalen Pfad der Source) vorhanden bzw. up-to-date und kompiliert gegebenenfalls Compileserver ruft über ComponentManager.Eval das Kompilat auf gesammeltes HTML/Cookiedaten werden an Interfaceclient geschickt CGI Cache Interfaceclient (C) <md5sum>.stc Socket - Kommunikation Struktur mit Zustand Compileserver (Alice) index.amsp
Implementierung: Compileserver Anfrage auf index.amsp: mit .amsp assoziiertes CGI-Programm(Interfaceclient) wird aufgerufen Interfaceclient sammelt Daten und sendet sie an Compileserver Compileserver checkt, ob Cache Eintrag (MD5-summe vom lokalen Pfad der Source) vorhanden bzw. up-to-date und kompiliert gegebenenfalls Compileserver ruft über ComponentManager.Eval das Kompilat auf gesammeltes HTML/Cookiedaten werden an Interfaceclient geschickt Interfaceclient sendet Daten an http Server CGI Cache Interfaceclient (C) <md5sum>.stc Socket - Kommunikation Struktur mit Zustand Compileserver (Alice) index.amsp
Implementierung: Word Sequences Von den ML Server Pages übernommen: datatype wseq = $ of string | && of wseq * wseq | ...
Implementierung: Word Sequences Von den ML Server Pages übernommen: datatype wseq = $ of string | && of wseq * wseq | ... Einsparung von string-Konkatenationen: Konkatenation ist Baumkonstruktion Projektion des Baums ist der dargestellte string Bei Versendung wird der Baum traversiert und die Blätter sequenziell versendet
verwandte Projekte Alice Server Pages ML Server Pages + High-level Interface zum Zugriff auf Formulardaten/Cookies mit statischer Typprüfung - low-level Interface - Cookies müssen im Header deklariert werden - Effizienz erkauft durch Tricks(Compileserver, Caching) + auch ohne Tricks schnell + Architektur portabel bezüglich Http Server-Interface - nur CGI
verwandte Projekte Alice Server Pages PHP + High-level Interface zum Zugriff auf Formulardaten/Cookies mit statischer Typprüfung + dynamische Daten werden in PHP-Datenstrukturen konvertiert - setzt Kenntnis von HTTP voraus - Effizienz erkauft durch Tricks(Compileserver, Caching) + auch ohne Tricks schnell - nur MySQL-API + reiche Bibliothek mit vielen Datenbank-APIs + Typsystem mit statischer Typprüfung - keine Typen
Zusammenfassung Compileserver kompiliert Skripte Formulardaten/Cookies werden geparst und in Alice-record konvertiert Niedrige Reaktionszeiten dank: Compile Server Umgehung der Startup-zeiten von Alice Von Skripten importierte Komponenten werden im Arbeitsspeicher gecacht Kann unabhängig vom Http Server betrieben werden Caching MySQL-API Aufwand: z4500 Zeilen Kern + z2000 Zeilen Beispielanwendung & Demos
Fazit Alice bietet einige Features, die sich zur Erstellung von Server Pages nutzen lassen: Statische Typprüfung für Formulardaten/Cookies frühe Fehlerlokalisierung Höherstufige Funktionen bei der Erzeugung der Formulardaten/Cookies First-class compiler zur Skriptkompilierung Component Manager zur Ausführung von Skripten und Caching importierter Komponenten
Ausblick Compile Server noch nicht nebenläufig Anzeige von Kompilierungsfehlern im Browser High-level Bibliothek für Sitzungs-management Mehr Datenbank-schnittstellen (ODBC?)