TH - splicing with functions defined in the same source file

Clemens Fruhwirth clemens at
Tue Nov 28 10:54:43 EST 2006


Template Haskell has the restriction that I can not use a function in
splices which is defined in the same source file the splice is in. I
want to lift this restriction but at the moment I'm not sure which
way to go.

For simplicity, I'm not aiming at a dependency analysis approach
because of things like f = $(..g..); g = $(..f..). Sure  can be
caught, but I rather want to start slowly.

The idea is to introduce a special marker in HsDecl, that allows all
HsDecl after the marker to use functions defined before the
marker. Let's call this marker CodeCutDecl. It partitions the list of
decls right-associatively and is set explicitly by the programmer.

My approach is as follows: Look at the
TcRnDriver.lhs:tcRnSrcDecls. The tc_rn_src_decls cuts the code into
groups of SpliceDecls. We do something similar, namely we insert an
additional grouping step, partitioning groups of HsDecl
right-associatively separated by CodeCutDecl. These are in turn are
grouped by SpliceDecls as before. Let's call this new grouping
function tc_rn_cut_decls.

Let preceeeding_decls be the list of HsDecls before the CodeCutDecl
marker. We assume preceeding_decls to be renamed and type checked, and
initially empty. Whenever entering tc_rn_cut_decls, the
preceeding_decls list is compiled and linked. Similar to
tc_rn_src_decls, the remaining decls are partitioned into a
first_code_cut and remaining_decls group, separated by CodeCutDecl (or
exhausition of the list making the reamining_decls list
empty). first_code_cut is renamed/type checked. It becomes the
preceeding_decls list for the next invokation of tc_src_cut_decls.

Compiling preceeding_decls to interactive code should enable the
type-checker in the subsequent invocations to use this compiled code
in expression/decl splicing.

The compilation in detail should happen by a special variant of
hscCompileInteractive that does not have a file frontend, but one
that directly supplies the compiler with a renamed/type-check source
being the preceeding_decls list. The result goes through byteCodeGen
via the hscInteractive backend, ending up as an (InteractiveRecomp _
comp_bc, _, _). The comp_bc is transformed into Linkables with [BCOs
comp_bc] and linked with linkModules of ghci/Linker.lhs.

My question: Is this a sensible approach? Is it sufficient to remove
the stage checking in thLocalId to make the type checker use the
preceeding BCO-compiled code in its invokations of
HscMain.compileExpr? Do you think I have to unload the byte compiled
code for some reason I can't think of?

Thanks for any guidance,
Fruhwirth Clemens - 
for robots: sp4mtrap at

More information about the Glasgow-haskell-users mailing list