Martin,

Appreciate your feedback. Some comments in-line (no need to reply).

Martin Jambon wrote:
> On Fri, 16 Mar 2007, Hugo Ferreira wrote:
> 
snip...
>>
>> My questions are:
>>
>> 1. Is this feasible?
> 
> I think the real question is "how hard is it?".
> Camlp4 provides different things and you don't have to use all its
> arsenal.
> 
> Let me give you my personal opinion on the difficulty of different things:
> 
> * emitting OCaml code from an OCaml program: easy; if you don't want to
> use the revised syntax, you may want to try ocamlp4, which I haven't.
> 
> * writing a syntax extension that does only inline substitution: very
> convenient using EXTEND statements.
> 

I would like to minor extensions, so this seems appropriate. I guess in 
this case I can use ocamlp4 (save me the trouble of learning a new 
syntax subset).

> * writing a syntax extension by defining a quotation expander: difficult
> if you want to handle error locations properly. This is however convenient
> if you really need a lexer which is different from the OCaml one. The
> other solution is to use strings, preceded by some keyword. Quotations can
> only expand to a single expression or to a single pattern (no toplevel
> declaration like types or groups of declarations).
> 

Ok. The original tutorial gave me this impression, so I will avoid this.

> * writing a syntax extension that requires some code to be inserted in
> other places of the program: tricky and somewhat dirty but feasible using
> the declare_once module from the regexp-pp package. I would not recommend
> doing this if you want your implementation to remain clear and simple.
> 

I guess the only time I will need this is for the "open" statements. 
Your tutorial has an example (version number) of this so I may use it.

> * writing a grammar for a DSL that is not an extension of the OCaml
> grammar: relatively easy if your grammar is LL(1) and once you figure out
> how to plug the lexer in and other annoying details. You could use menhir
> or ocamlyacc too. Using ocamlyacc may be difficult and it doesn't produce
> useful error messages automatically. I don't know about menhir, but it's
> supposed to be better than ocamlyacc.
> 
> 

I do have the lexing and parsing ready for what I want at this point. In 
fact all I want is to process a string (terms, term instances, horn 
clauses and queries) expression and to generate a data structure 
accordingly (terms and knowledge data source). From there it is simply a 
matter of having Ocaml functions using this data. Ok, seems like I am 
going in the right direction.

(Comment: I have used both ocamlyacc and menhir and menhir does indeed 
give better error reports.)

> 
>> 2. Does it require much effort (any one venture an estimate)?
> 
> If you are comfortable with functional programming in OCaml already, and
> if you like adventure, then you could obtain some good results within a
> few days. But there are pitfalls that you should avoid. See below for an
> incomplete list.
> 

Ok.

> 
>> 3. Is the syntax I show acceptable (any suggestions)?
> 
> For an easy integration into OCaml, here are a few rules of thumb:
> 
> * make the embedded language well-delimited from the rest. It means that
> all the information must be contained in the first two tokens. For
> special type definitions, I like to use a keyword (which is actually a
> LIDENT) just after the "type" keyword:
>   type special t = ...
> 
> For value definitions:
>   let special f = ...
> 
> Starting with an existing keyword lets you define your special keyword as
> a LIDENT (lowercase identifier) and use it as a regular identifier
> elsewhere. It helps not breaking existing code.
> 

Ok. Your "default values for record fields" example has made this clear 
to me.

> You should not use "let x = | ... |" if what you want to expand is the
> whole declaration rather than only the contents of | ... |.
> 

I am only interested in the expanding the contents of |...|. In fact I 
will have three basic groups of such cases. So I guess this is acceptable.


> * text editor modes are not ready for special syntax extensions and it
> results in bad automatic indentation. Using parentheses around the parts
> written in the special syntax helps when it's possible. Otherwise, you may
> want to choose a convention that forces the use of brackets ((), [] or {})
> combined with another symbol. Make sure other popular camlp4 extensions do
> not use the same convention (hard) or use this in addition to a preceding
> keyword (easy and safer):
> 
>   let special {| ... |}
> 
> where ... can be anything using existing ocaml keywords with your own
> rules, as long as brackets in your DSL are matched.
> 

For now I will stick to the simpler convention of brackets (one per 
group as stated above) for now. Seems easier to handle and my Vim editor 
handles this ok.

> * do not allow unmatched brackets in your DSL.
> 

Ok.

> 
> I don't know what your example should be expanded into so I can't tell
> you exactly what's wrong and what's right. A good startpoint for you would
> be to translate manually a complete example into plain OCaml.
> 

I have done this as a pencil and paper exercise. I am now trying to do a 
very simple example. See how it goes.

> 
> 
> Martin
> 
> --
> Martin Jambon
> http://martin.jambon.free.fr
> 
> 
>> --------------------------------------------
>> Examples
>> --------------------------------------------
>>
>>
>> (* Example of a query *)
>> let prog = |  f(a,b).
>>                f(b,c).
>>
>>                g(X,Y):- f(X,Z), f(Z,Y) |     in
>> let result = prog:|  g(X,Y), g(X,X)   |      (* conjunction, not a tuple *)
>> in
>>     result
>>
>>
>> (* Example of unification  *)
>> let    prog = | |                    in
>> let   inst1 = prog:|| h(a,X,Y,d) ||  in
>> let   inst2 = prog:|| h(X,b,c,Y) ||  in
>> let result1 = inst1 .= inst2                         (* [EMAIL PROTECTED], 
>> =:= *)
>> in
>>     result (* returns the unified instance and the mgu *)
>>
>> (* Example of list of terms  *)
>> let    prog = | |                            in (* empty *)
>> let   inst1 = prog:|[ h(a,X,Y,d); i(X,b) ]|  in
>> let   inst2 = prog:|[ h(X,b,c,Y); i(a,X) ]|  in
>>                             (* tuples use "|(", arrays "|[|" *)
>> let rec loop l1 l2 r =
>>      match l with
>>      | h1::t1, h2::l2 -> loop ( h1 .= h2 )::r
>>      | r
>> in
>>     loop inst1 inst2 []
>>
>>
>> (* Instantiating terms  *)
>> let    prog = | |                            in
>> let   expr1 = || [h(a,X,Y,d), i(X,b)] ||     in
>> let   expr2 = || [h(X,b,c,Y), i(a,X)] ||     in
>> let   inst1 = prog:| expr1 |                 in
>> let   inst2 = prog:| expr2 |                 in
>> let  result = inst1 .= inst2
>> in
>>     result
>>
>>
>>
>> (* Backtracking  *)
>> let      p0 = | |                    in
>> let   expr1 = || h(a,X,Y,d) ||               in
>> let   expr2 = || h(X,b,c,Y) ||               in
>> let   expr3 = || h(X,Y,c,d) ||               in
>> let (p0,i1) = p0:| expr1 |           in(* uses the result of previous 
>> processing *)
>> let (p1,i2) = p0:| expr2 |           in(* uses the result of previous 
>> processing *)
>> let  result = inst1 .= inst2         in
>> let  result = if .! result then (* try another option *)
>>                                  let inst1 = p0:| expr1 |    in
>>                                  let inst2 = p1:| expr1 |    in
>>                              in
>>                                    result
> 
> > 
> 


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"ocaml-developer" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/ocaml-developer?hl=en
For other OCaml forums, see http://caml.inria.fr/resources/forums.en.html
-~----------~----~----~----~------~----~------~--~---

Reply via email to