Fwd: Re[2]: [Template-haskell] new TH tutorial (request for comments)

Bulat Ziganshin bulatz at HotPOP.com
Wed Jan 25 11:57:26 EST 2006


you are not answered, may be because my private message not reached
you?

This is a forwarded message
From: Bulat Ziganshin <bulatz at HotPOP.com>
To: Johannes Ahlmann <softpro at gmx.net>
Date: Monday, January 23, 2006, 8:24:34 PM
Subject: [Template-haskell] new TH tutorial (request for comments)

===8<==============Original message text===============
Hello Johannes,

Monday, January 23, 2006, 2:14:13 AM, you wrote:

i hope that you don't crosspost your answer to maillist by accident :)
at least i want to check my imhos with other TH users

JA> first off, thanks a lot for your criticism! after sitting hours and
JA> hours learning TH and writing this tutorial, obviously some pretty
JA> visible quirks got into the "tutorial". and i'll try to fix those ASAP.
JA> but with the little documentation/tutorials/readable examples of TH i
JA> could find, i thought my attempt at a tutorial would be better than not
JA> having it at all.

you are absolutely true. i don't against any possible TH titorial, and
yours contains some things that i really like, especially examples and
ease in introducing rather complex concepts

JA> the "tutorial" tries to teach by example because that's how i learn
JA> best. obviously this won't convey the many intricate details of TH but
JA> it gives you a nice overview of whether TH is something you would want
JA> to get involved in.

i agree that "one example worth thousand explanatios". but i'm disagree with
the second sentence - if you just give overview of TH then it's not
tutorial any more, it's just like an excursion, but before real using
of TH one must read some other papers. does this make much meaning?

i started (and not finished) writing my own TH tutorial. its first
version is at http://freearc.narod.ru/th.htm and current version is at
http://freearc.narod.ru/th3.htm

may be my approach too boring and verbose, but i tried to eliminate
problem of original TH paper - what it introduces pretty-looking but
absolutely bottomless code for printf on the first page and going to
really explain it only on the last pages. instead i selected a rather
complex but clear way of teaching how to use low-level TH constructs
and then advertize high-level constructs just as shortcuts which helps
to write code easier, but in fact does the same work

TH is very novel and unusual tool and i think that just this makes its
learning and usage so difficult. sometimes i think that my problems in
mastering TH is like problems of engineer which is used calculator and
then goes to write programs in typeful language. are he ever thinks
about difference between floating and integer values? :) are we ever
thinks that 'x' in pattern and expression is so different beasts?

quasi-quotation is the mechanism which should hide much of this
complexity for the real user. but does it accomplish this goal? i
think no - any rather complex TH work can't be written without
knowledge about Exp, Q and other low-level stuff. so we anyway should
explain to the user both low-level and high-level things, and i think
it's better to go in my way rather than start from high-level stuff
and then break conception already builded in user's mind by talking
about all these low-level things. so imho starting from the low-level
stuff really goes to the economy of reader's time and mind. with
current state of TH it's better to study it as the AST-generation tool
with some help in creating some ASTs rather than macro-generation tool
which has some advanced low-level additions. imho, as usual

JA> Bulat Ziganshin wrote:
>> you
>> describe ASTs without prior giving reader knowledge about how they
>> will be used. i think that prior information about splicing and that a
>> spliced expression must return AST representing list of declarations
>> or expression, would help here.

JA> yes, a little more introductory text might be needed here.

i have even more radical offer - just join our tutorials so that my
part explains low-level stuff and quasi-quotation mechanism while you
say about 'Name/''Name/reification and give all these neat examples of
TH usage. plus join our explanations of low-level stuff

even together these two tutorials don't cover all the TH intrinsics,
but at least we can start with it. imho, the final goal of this
project must be to give one enough explanations that he don't need to
read anything more on TH to use all its features and understand all
what he does. of course, that is the long-standing goal, but at least
i try to explain im my tutorial as much as i can

>> 2. actually, splicing is reverse
>> operation for the quasi-quotation, which don't get your speciall
>> attention. and that is another tutorial leak - quasi-quotation is not
>> so simple and obvious operation, as seems at the first look. 

JA> i'm not trying to explain how TH works, but how to use it. and from a
JA> users perspective quasi-quotes do a lot of background work (which IMHO
JA> the user doesn't necessarily have to be aware of as a TH novice)

i think that TH papers contains only the information essential to
using TH (and we both don't read anything else ;). another question is
that some explanations can be divided - in order to start using q.q.
one don't need to know all about them. but i think that any deliberate
using of q.q. requires knowledge that it generates ExpQ, i.e. it's
some computation in Q monad that returns Exp; and that spliced
subexpressions should also have this type.


>> later you call quasi-quotation as "reification" and that's farther
>> complicates the terminology - in TH, reification, i.e. call to "reify"
>> function, retrieves information about given Name from Q monad
>> environment, while quasi-quotation is a syntax sugar what allows to
>> write AST expression in the form of literal Haskell code

JA> hmm, maybe i just got the nomenclature wrong, but as far as i understood
JA> it, everywhere in metaprogramming what quasi-quotes do is called
JA> "reification". but that might be a mixup on my part. and even more
JA> gravely, i might have presented the terms in a confusing fashion.

i can't say about other metaprogramming tools because i don't know any
other than CPP and TH :)  but at least TH docs use this term only in
respect to "reify" function

>> 4. your tutorial does not mention many non-trivial details of TH,
>> [... for] example, difference between mkName and newName.

JA> yes, i should add that. but the many forms of "dyn", quoted symbols,
JA> mkName, newName are very confusing even to me; but maybe that's the
JA> problem :)

see at the Name definition. newName and its equivalent - introducing
new variable inside of q.q. - produces a "unique name" with NameU
flavour. Q monad provides sequential numbering of all these "unique
names", so that names generated by different invocations of newName
cannot coincide. mkName/dyn just wraps the String with identifier in
the Name constructor with NameS/NameQ flavour so that the resulting
code will use just exact identifier you specified. that allows to bind
names dynamically - if you use (mkName "x") in different parts of your
TH code, this "x" name nevertheless will refer to the same "x"
variable - of course, if it is accessble in the generated code. you
can see it as unsafe trick to significantly easify building of AST;
moreover, in many cases generated code will be safe because there is
no other "x" variables and no possibility that this variable will be
redefined in some inner code. but in overall it's unsafe technique and
i selected just avoiding saying to novices about it instead of saying
and then explaining why it should not be used and then explaining
where is still may be used :)))

quoted symbols is like local ones generated by mkName/dyn, but they
use NameG flavour because they are statically bounded at the context
where '/'' was used. that allows to pass references to the global
identifiers between modules even if identifier you use don't imported
by the module where your code is spliced. afaik, implicit importing
performed in such case. for example:

module MyTHLibrary:

import Binary
deriveBinary t = let binaryType = ''Binary
                 in .... (some code that generates derived Binary
                 instance for the given type)

module Application:

import MyTHLibrary
type Binary = String
$(deriveBinary ''Int)


in this case, spliced code will contain reference to the Binary class
available in the MyTHLibrary module. second module don'y import this
definition, moreover it defines another symbol with the same name.
nevertheless, TH successfully uses the appropriate definition of
Binary when it splices generated code. in another words, reference to
Binary resolved statically, at the place of using '/'', while for
mkName (which also can define qualified names), this reference is
resolved dynamically, according to the context where the top-level
SPLICING occurs

                 
>> a "Restrictions"
>> chapter is non-readable in some parts - a least, i understand "In its
>> current implementation reificiation of non-quasi-quoted code seems
>> very restricted" after heavy thinking and only because i already know
>> that. and i don't understand the "Easily pattern matching the tree based
>> on its nodes' types seems limited."

JA> yes, it's too much work in progress; i'll clean that up.
JA> about the node types: i was alluding to the fact that when you want to
JA> dispatch on some cases of an overloaded function, figuring out which
JA> version you were dealing with and which types the operands had could be
JA> tricky...

now i understands more, but not all. really, i never tried to reify
expressions and so don't understand problems in this area :)


-- 
Best regards,
 Bulat                            mailto:bulatz at HotPOP.com

===8<===========End of original message text===========



-- 
Best regards,
 Bulat                            mailto:bulatz at HotPOP.com





More information about the template-haskell mailing list