Allow me to clarify what I meant by type errors and antiquotations. Here is a very simple program that contains the parser, type checker, and quotation generator: --------------------------------------- #load "pa_extend.cmo";; #load "q_MLast.cmo";; (* Parser *) type palg= | PApp of string*palg list | PInt of string | PFlo of string;; let g=Grammar.gcreate (Plexer.gmake ());; let exp_eoi = Grammar.Entry.create g "exp_eoi";; EXTEND GLOBAL: exp_eoi; exp_eoi: [[ x = exp; EOI -> x ]] ; exp: [[x=INT -> PInt x | x=FLOAT -> PFlo x | f = LIDENT; "("; xs=LIST1 SELF SEP ","; ")"-> PApp (f,xs)]]; END;; let parse s = Grammar.Entry.parse exp_eoi (Stream.of_string s);; (* Type Checker *) exception TypeError;; type integer=[`Int];; type real=[integer | `Real];; let rec type_expr=function | PApp (f,args) -> (match f with | "add" -> if List.length args != 2 then raise TypeError else let args=List.map type_expr args in (match (List.nth args 0,List.nth args 1) with | #integer,#integer -> `Int | #real,#real -> `Real) | _ -> raise TypeError) | PInt _ -> `Int | PFlo _ -> `Real ;; (* Quotations *) type alg= | App of string*alg list | Int of int | Flo of float;; let loc=Ploc.dummy;; let rec to_expr=function | PInt x-> <:expr< Int $int:x$ >> | PFlo x-> <:expr< Flo $flo:x$ >> | PApp (f,el)-> let rec make_el=function | x::xs -> <:expr< [$x$::$make_el xs$] >> | [] -> <:expr< [] >> in let el=List.map to_expr el in let el=make_el el in <:expr< App ($str:f$,$el$) >> ;; let rec to_patt=function | PInt x-> <:patt< Int $int:x$ >> | PFlo x-> <:patt< Flo $flo:x$ >> | PApp (f,el)-> let rec make_el=function | x::xs -> <:patt< [$x$::$make_el xs$] >> | [] -> <:patt< [] >> in let el=List.map to_patt el in let el=make_el el in <:patt< App ($str:f$,$el$) >> ;; let expand_expr s= let p=parse s in let t=type_expr p in to_expr p ;; let expand_patt s= let p=parse s in let t=type_expr p in to_patt p ;; Quotation.add "exp" (Quotation.ExAst (expand_expr,expand_patt));; --------------------------------------- Thus, by type check, I mean actually verifying the typing rules of the DSL. In this case, it means that the only function allowed is "add" and that this function requires two arguments. Now, imagine the above language where antiquotations are allowed. The parsed AST would have datatype type palg= | PApp of string*palg list | PInt of string | PFlo of string | PQuote of Ploc.t*string and it becomes impossible to type check in the above sense since we can not ascertain the type of PQuote. Now, we can still type check the resulting AST of type alg (not palg). But, this must occur at runtime rather than during the preprocessing step at compile time. Therein lies the problem. If we discover a type error during runtime, it would be nice to give the user some indication of where the error occurs short of saying, "Add expects two arguments." Since the location information provided is relative to the quote, it can still be challenging to determine exactly where the type error occurs. Thus, I'm either trying to obtain better location information or perhaps learn that there's a better place or method to type check than what I'm using. --------------------------------- Never miss a thing. Make Yahoo your homepage.