Fwd: Re[2]: new TH tutorial (request for comments)
Bulat Ziganshin <[email protected]> Wed, 25 Jan 2006 19:57:26 +0300
| Newsgroups | gmane.comp.lang.haskell.template |
|---|---|
| Message-ID | <[email protected]> |
you are not answered, may be because my private message not reached you? This is a forwarded message From: Bulat Ziganshin <[email protected]> To: Johannes Ahlmann <[email protected]> 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:[email protected] ===8<===========End of original message text=========== -- Best regards, Bulat mailto:[email protected]