diff --git a/doc/gf-modules.html b/doc/gf-modules.html index 2ca52d598..74cabe654 100644 --- a/doc/gf-modules.html +++ b/doc/gf-modules.html @@ -46,6 +46,8 @@ module system related to the already familiar uses of GF grammars. +
+ cat C ; ===> oper C : Type = T ; + lincat C = T ; + + fun f : A ; ===> oper f : A = t ; + lin f = t ; ++Due to this translation, a concrete module +can be opened in the same way as a +resource module; the translation is done +on the fly (it is computationally very cheap). + +
+ +Modular grammar engineering often means that some grammarians +focus on the semantics of the domain whereas others take care +of linguistic details. Thus a typical reuse opens a +linguistically oriented resource grammar, +
+ abstract Resource = {
+ cat S ; NP ; A ;
+ fun PredA : NP -> A -> S ;
+ }
+ concrete ResourceEng of Resource = {
+ lincat S = ... ;
+ lin PredA = ... ;
+ }
+
+The application grammar, instead of giving linearizations
+explicitly, just reduces them to categories and functions in the
+resource grammar:
+
+ concrete ArithmeticEng of Arithmetic = LogicEng ** open ResourceEng in {
+ lincat Nat = NP ;
+ lin Even x = PredA x (regA "even") ;
+ }
+
+If the resource grammar is only capable of generating grammatically
+correct expressions, then the grammaticality of the application
+grammar is also guaranteed: the type checker of GF is used as
+grammar checker.
+To guarantee distinctions between categories that have
+the same linearization type, the actual translation used
+in GF adds to every linearization type and linearization
+a lock field,
+
+ cat C ; ===> oper C : Type = T ** {lock_C : {}} ;
+ lincat C = T ;
+
+ fun f : ... -> C ; ===> oper f : A = t ** {lock_C = <>};
+ lin f = t ;
+
+(Notice that the latter translation is type-correct because of
+record subtyping, which means that t can ignore the
+lock fields of its arguments.) An application grammarian who
+only uses resource grammar categories and functions never
+needs to write these lock fields herself. Having to do so
+serves as a warning that the grammaticality guarantee given
+by the resource grammar no longer holds.
+
+
++ +However, the separation of declarations and definitions is so +useful a notion that GF also has specific modules types that +resource modules into two parts. In this splitting, +an interface module corresponds to an abstract syntax, +in giving the declarations of operations (and parameter types). +For instance, a generic markup interface would look as follows: +
+ interface Markup = open Util in {
+ oper Boldface : Str -> Str ;
+ oper Heading : Str -> Str ;
+ oper markupSS : (Str -> Str) -> SS -> SS = \f,r ->
+ ss (f r.s) ;
+ }
+
+The definitions of the constants declared in an interface
+are given in an instance module (which is always of
+an interface, in the same way as a concrete is always
+of an abstract). The following instances
+define markup in HTML and latex.
+
+ instance MarkupHTML of Markup = open Util in {
+ oper Boldface s = "<b>" ++ s ++ "</b>" ;
+ oper Heading s = "<h2>" ++ s ++ "</h2>" ;
+ }
+
+ instance MarkupLatex of Markup = open Util in {
+ oper Boldface s = "\\textbf{" ++ s ++ "}" ;
+ oper Heading s = "\\section{" ++ s ++ "}" ;
+ }
+
+Notice that both interfaces and instances may
+open resources (and also reused top-level grammars).
+An interface may moreover define some of the operations it
+declares; these definitions are inherited by all instances and cannot
+be changed in them. Inheritance by module extension
+is possible, as always, between modules of the same type.
+
+
+