On Fri, Mar 14, 2003 at 12:33:36AM +0600, Max Kirillov wrote: > Talking about the single thigs: at the beginning of my way into ocaml, I > did some camlp4 hacks. For example, that was "where" keyword support > (much more powerful than in revised syntax) and some support for "from > top to bottom" style of sources. If you interested, I could post them. I'm sending the changes. Note that, though they are quite stable, I picked them from an environment, so something may broke. A little comment what is it. file test_where.ml -- obvious. Very little, more to demonstrate, than to cover all possible (and really seen) dangers. file lazyX.ml -- misc functions to handle lazy values (see later) note that it is already uses the extension file where.ml -- the main thing There are several things: 1) 'where' notation: ::= where { [rec] } | where [begin] [rec] end the two version are the same (some like {..}, some begin..end). there are some unresolved quastions with prioriries, so, in practice, I often had to use brackets. However, I think that the level I choose is quite reasonable. 2) reorder srt_items there are keyword 'WHERE' (uppercase) in place of structure item. At the point, the structure (or the whole file if at toplevel) is cut, then pieces swapped and concated again. this allows writing: ------- file.ml main ();; WHERE let main () = do_this (); do_that ();; WHERE let do_this () = <.......> and do_that () = <........> ------ 3) lazy values predeclaration ::= [let] [lazy] [rec] this allows define lazy value, which is seen to the whole structure, and not only to the following items. Every value that is binded is lazy value, that, when forced, computes the definition. It uses the LazyX module: nondef () produces the value, set dest src replaces the unforced lazy value dest by the unforced lazy expression src, if any of then is already forced (it is at module initialization time, so it's easy to catch), the exception is raised. I used it in plays with "functional GUI", where needed to declare many inter-depended values and, for various reasons, didn't want to use "let rec <...> and <...>" chain. There is one trouble. When you define a type, and then a lazy value of the type, the compiler complains "the type xxx would escape its scope". this berore it comes to need to infer the type for the initial declaration "let x = LazyX.nondef ()", where it is not yet defined. To solve the problem, I added "HEADER" keyword. It explicitly says that the forward declataions must be placed here instead of beginning of the file. You place it after the type declaration. Of course the lazy values definitions must itself follow the type declarations. The lazy stuff is intended to work only in toplevel, it is not for "struct..end". I used the (1) very much, and would say it quite workable. The (2) is also quite stable, but, now, I would say the realization needs to be changed. The (3) are more a toy than real thing. There could be problems with that. -- Max