Permalink
Browse files

Merge branch 'master' of git@github.com:johang88/haskellinjavascript

  • Loading branch information...
2 parents 69510f7 + d175d13 commit d27689dfc14536e0a9a7b394e6da251cedefb03e Johan Gustafsson committed May 17, 2010
Showing with 55 additions and 42 deletions.
  1. +14 −2 rapport/kallor.bib
  2. +1 −2 rapport/kapitel/diskussion.tex
  3. +40 −38 rapport/kapitel/resultat.tex
View
@@ -98,12 +98,24 @@ @conference{fang01
}
@INPROCEEDINGS{jones99,
- author = {Mark P. Jones},
+ author = {Jones, M. P.},
title = {Typing Haskell in Haskell},
booktitle = {Haskell Workshop},
year = {1999},
publisher = {}
}
+@inbook{dragonbookchap6,
+ title = "Compilers: Principles, Techniques, and Tools (2nd Edition)",
+ author = {Aho, A. V. and Lam, M. S. and Sethi, R and Ullman, J. D.},
+ year = 2006,
+ publisher = "Addison Wesley",
+ chapter = 6
+}
-
+@book{pierce02,
+ author = "Pierce, B. C.",
+ year = 2002,
+ title = "Types and Programming Languages",
+ publisher = "MIT Press",
+}
@@ -1,6 +1,5 @@
\section{Diskussion}
-Vi har skapat en javascriptapplikation som kan parsa, typchecka och interpretera stora delar av Haskell 98. Det som saknas är fullständigt stöd för typklasser där
-stödet endast finns i typcheckaren men fortfarande behöver implementeras i interpretatorn.
+Vi har skapat en javascriptapplikation som kan parsa, typchecka och interpretera stora delar av Haskell 98. Det som saknas är fullständigt stöd för typklasser där stödet endast finns i typcheckaren men fortfarande behöver implementeras i interpretatorn. Detta handlar främst om förmågan att välja rätt instanser av typklasser vid applicering av överlagrade funktioner.
Sett till planeringen har vi lyckats uppfylla alla milstolpar utom typklasser, dock inte enligt den ordning och tidsplan som ursprungligen planerades.
Vi insåg att det var enklast att utveckla parsern, typcheckaren och interpertatorn parallelt och bestämma individuellt vad som skulle implementeras och i
@@ -304,6 +304,8 @@ \subsection{Typcheckare}
andra beståndsdelar är konsekvent. Om så inte är fallet sägs programmet ha
typfel.
+Vår implementation av typcheckaren är starkt influerad av den implementation i Haskell som beskrivs i \citep{jones99} men är omdesignad för att göra sig bättre i JavaScript. Det följande avsnittet förutsätter viss förkunskap om typinferens och polymorfiska typer. För en bra introduktion till detta referera till \citep{dragonbookchap6} och för en djupare genomgång \citep{pierce02}.
+
\subsubsection{Haskells typsystem}
Jämfört med mer konventionella språk (C, C++, Java etc) skiljer sig Haskell
och övriga statiskt typade funktionella språk på flera sätt. I de senare
@@ -320,23 +322,20 @@ \subsubsection{Haskells typsystem}
specifik typ hos något av sina argument kan data av alla typer användas som
argumentet.
-Utöver polymorfiska typer stödjer Haskell typklasser som gör överlagring av
-funktioner möjligt. Typklasser är väldigt centralt i Haskell och ändrar
-typcheckarens arbetssätt markant jämfört med liknande språk.
+Typklasser är en form av ad-hoc polymorfism som används flitigt i
+Haskell. Faktum är att de är så fundamentala i Haskell att de får en central
+roll i typcheckningsprocessen. Deras främsta funktion är att möjliggöra funktionsöverlagring beroende på typer på argument och förväntad returtyp.
+
+\subsubsection{Representation av kinds, typer, typscheman och typklasser}
+För att representera typsystemets olika beståndsdelar använder typcheckaren ett antal olika datastrukturer. Här ger vi en snabb genomgång av dessa för att sedan kunna fokusera på själva typcheckningsprocessen i de sedan följande avsnitten.
-\subsubsection{Kinds}
-Kinds kan liknas vid en motsvarighet till typer för typkonstruktorer. * (uttalas ``stjärna'', eng. ``star'') representerar enkla (nullary) typer som Integer och Integer -> Bool medan komplexa typer som tar argument representeras med applicering av kinds k1 -> k1, exempelvis Maybe Bool.
+Kinds kan liknas vid en motsvarighet till typer för typkonstruktorer. \emph{*} (uttalas ``stjärna'', eng. ``star'') representerar enkla (nullary) typer som Integer och \emph{Integer -> Bool} medan komplexa typer som tar argument representeras med applicering av kinds \emph{k1 -> k2}. Exempelvis har \emph{Maybe} kind \emph{*->*} medan \emph{Maybe Bool} har kind \emph{*}.
\begin{lstlisting}
data Kind = Star
| Kfun Kind Kind
\end{lstlisting}
-\subsubsection{Typer}
-De datastrukturer som typcheckaren använder internt för att representera typer kan delas in i typvariabler som representerar
-
-För att kunna arbeta på en hög abstraktionsnivå har typcheckaren sin egen
-interna representation av typer.
\begin{lstlisting}
data Type = TVar Id Kind
@@ -357,23 +356,10 @@ \subsubsection{Typer}
(TCon "(->)" (Kfun Star (Kfun Star Star)))
(TAp
(TCon "[]" (Kfun Star Star))
- (TVar "a" Star)))
+ (TVar "a" Star)))
(TCon "Integer" Star))
\end{lstlisting}
-\subsubsection{Substitueringar}
-Substitueringar är mappningar \emph{typvariabel -> typ} och används av typcheckaren
-för att hålla typer uppdaterade efterhand som den får ny
-information. Typcheckaren innehåller flera funktioner som opererar på
-substitutioner, bland annat komponering och sammanfogning av
-substitutioner. \emph{Unifiering} är processen att finna en substituering som gör två typer ekvivalenta. Om unifiering inte är möjligt
-betyder det att det finns typfel.
-
-\subsubsection{Typklasser}
-Typklasser är en form av ad-hoc polymorfism som används flitigt i
-Haskell. Faktum är att de är så fundamentala i Haskell att de får en central
-roll i typcheckningsprocessen. Deras främsta funktion är att möjliggöra funktionsöverlagring beroende på typer på argument och förväntad returtyp.
-
För att hålla reda på vilka typklasser en typ tillhör används predikat:
\begin{lstlisting}
data Pred = Pred Id Type
@@ -394,7 +380,7 @@ \subsubsection{Typklasser}
(TVar "a" Star)))
\end{lstlisting}
-För att modellera de hela typscheman som typcheckaren får in från användaren används datatypen \emph{Scheme}.
+För att representera de hela typscheman som typcheckaren får in från användaren används datatypen \emph{Scheme}.
\begin{lstlisting}
data Scheme = Scheme [Kind] Qual
\end{lstlisting}
@@ -413,6 +399,16 @@ \subsubsection{Typklasser}
För att hålla reda på vilka typklasser och instanser som finns används datatypen \emph{Klass} (\emph{class} är ett reserverat ord i JavaScript) som representerar enskilda typklasser och deras instanser samt datatypen \emph{KlassEnvironment} som representerar den totala klassmiljön.
+
+\subsubsection{Substitueringar}
+Substitueringar är mappningar \emph{typvariabel -> typ} och används av typcheckaren
+för att hålla typer uppdaterade efterhand som den får ny
+information. Typcheckaren innehåller flera funktioner som opererar på
+substitutioner, bland annat komponering och sammanfogning av
+substitutioner.
+
+\emph{Unifiering} är processen att finna en substituering som gör två typer ekvivalenta. Detta är viktigt exempelvis i uttryck {\bf if} \emph{e1} {\bf then} \emph{e2} {\bf else} \emph{e3}. Här måste typen för \emph{e1} gå att unifiera med typen \emph{Bool} och \emph{e2} och \emph{e3} måste gå att unifiera till en och samma typ. Om någon av dessa unifieringar inte är möjliga betyder det att typfel finns.
+
\subsubsection{Typinferens}
Typinferens är den sammanfogande delen av typcheckningsprocessen och går ut på att typcheckaren traverserar abstrakta syntaxträdet och samlar de kriterier som måste vara uppfyllda för att programmet ska vara korrekt.
@@ -429,7 +425,7 @@ \subsubsection{Typinferens}
var b = this.condExpr.infer(env);
env.unify(
b.type,
- new typechecker.TCon(``Bool'', new typechecker.Star()));
+ new typechecker.TCon("Bool", new typechecker.Star()));
var te = this.thenExpr.infer(env);
val ee = this.elseExpr.infer(env);
env.unify(te.type, ee.type);
@@ -439,7 +435,7 @@ \subsubsection{Typinferens}
};
};
\end{lstlisting}
-Först infereras typen på vilkoret. Detta unifieras med typen \emph{Bool} på raden under. Sedan infereras typerna på \emph{then}- respektive \emph{else}-delarna och då dessa måste vara va samma typ unifieras deras typer. Till sist returneras de insamlade predikaten från både \emph{then}- och \emph{else}-delarna tillsammans med den unifierade typen.
+Först infereras typen på vilkoret. Detta unifieras med typen \emph{Bool} på raden under. Sedan infereras typerna på \emph{then}- respektive \emph{else}-delarna och då dessa måste vara va samma typ unifieras deras typer. Om typerna inte går att unifiera innebär det att dess returtyper är distinkta och att det därför finns typfel. Till sist returneras de insamlade predikaten från både \emph{then}- och \emph{else}-delarna tillsammans med den unifierade typen.
Av detta exempel kan ett antal slutsatser dras. Typinfereringen sker rekursivt från sammansatta uttryck ner till de alla enklaste literalerna. Att misslyckande av unifiering betyder typfel innebär att inferera-unifiera-cykeln har en roll liknande den infer-check har vid typcheckning i exempelvis C.
@@ -468,25 +464,31 @@ \subsection{HIJi}
HIJi är skapat för att likna GHCi i så stor utsträckning som möjligt.
Genom att efterlikna GHCi kommer användare känna igen sig när de tar steget från HIJi till GHCi. Det blir för dem ett naturligt steg och kortar inlärningströskeln. Även för haskellprogrammerare som är vana användare av GHCi blir det lättare att använda sig av HIJi, de behöver inte fundera hur verktyget ska användas.
-\subsection{Language feutoeeras}
+\subsection{Prelude}
+I våra avgränsningar angav vi vilka delar av haskellspecifikationen vi skulle fokusera på. De delar som vi har fullt stöd för är lambda-funktioner, namngivna funktioner, algebraiska datatyper, pattern matching och guards.
+I HIJis förladdade modul, Prelude, har vi definerat upp ett antal funktioner som visar på att vi har implementerat dessa egenskaper från specifikationen.
+Alla funktioner som är definerade i Prelude är namngivna funktioner. Ett exempel på en namngiven funktion är \emph{id}.
+Algebraiska datatyper stöds och i Prelude har vi definerat upp datatypen Bool och ett par funktioner, däribland (||), som använder sig utav den här datatypen. Funktionen (||) använder sig av pattern matching. Resultatet av \emph{case x of} kommer matcha antingen mot \emph{True} eller \emph{False}.
+Funktionen \emph{filter} från Prelude är ett exempel på att guards fungerar. Filter är också ett exempel på att pattern matching och rekursiva funktioner är implementerade.
-I våra avgränsningar angav vi vilka delar av haskellspecifikationen vi valde att fokusera på.
-I vår modul Prelude har vi definerat upp en rad funktioner som visar på exempel på att vi lyckats implemetera det vi fokuserat på.
-
-Vi har stöd för namngivna funktioner och lambda-funktioner. Ett exempel på en namngiven funktion är id.
\begin{lstlisting}
+-- Utdrag ur Prelude.hs
+
+-- en namngiven funktion
id x = x
-\end{lstlisting}
-Algebraiska datatyper stöds också. I Prelude har vi definerat upp datatypen Bool och ett par exempel på när vi använder den. I funktionen \emph{(||) x y} har vi också ett exempel på pattern matching. Resultatet av x \emph{case x of} kommer matcha antingen mot \emph{True} eller \emph{False}.
-\begin{lstlisting}
+-- datatypen Bool
data Bool = True | False
+-- exempel av pattern match
(||) x y = case x of
True -> True
False -> y
-\end{lstlisting}
-
-Guards %TODO filter från johan
+-- exempel av pattern match,
+-- guards och rekursiva funktioner
+filter _ [] = []
+filter f (x:xs ) | f x = x : filter f xs
+ | otherwise = filter f xs
+\end{lstlisting}

0 comments on commit d27689d

Please sign in to comment.