using template haskell to implement pads for haskell?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

using template haskell to implement pads for haskell?

David Walker-11
hi,

I am new to Haskell and even more so to Haskell templates -- if there
is an obvious answer to my question, please just point me at the
relevant URL.  Thanks! (If you think I should email this query to
a broader Haskell mailing list let me know too.)

My friends and I are thinking about adding an extension to Haskell to
implement a variant of the PADS domain-specific language.  PADS is a
convenient syntax to describe a file format and generate a bunch of
tools for it such as parser, printer, xml translator, semi-structured
query engine, statistical profiler, etc.  (We also have tools to
automatically infer descriptions from example data but that's not
quite the point here.)  See www.padsproj.org/ for lots more info and
examples of PADS for C and PADS for O'Caml.

The bottom line question is I'm wondering if I can or should implement
my PADS extension using Template Haskell to support the syntactic
extensions.  If not Template Haskell, is there another Haskell toolkit
I should know about?  If Template Haskell isn't powerful enough, I'll
probably just write a standalone compiler that parses my special
syntax and spits out a file full of Haskell declarations (this would
be a slight shame because then I would probably not support writing
PADS declarations in the midst of other Haskell code).  I've looked at
simple Template Haskell examples from the Haskell wiki, such as the
printf example, but I need to introduce a lot more syntax than that ...

What do I need from Template Haskell?  Well what I would like to do is
add a bit of syntax to Haskell that allows users to define what looks
like non-standard type declarations.  The "compiler" for these
non-standard type declarations will generate a collection of ordinary
Haskell declarations that can be used by a programmer.  The
non-standard typing declarations will be a mixture of what looks like
Haskell type declarations, Haskell code, perl-style syntax for regular
expressions and perhaps some other stuff I'm not thinking of right
now.  For example, suppose I want to write a program that converts a
file that contains a list of friends into XML (it's a bit of an
artificial example so I can illustrate several features):

3
Simon;Peyton Jones
John;Launchbury
#Phil;Wadler

The format starts with a number on the first line to indicate the number
of entries
in the file.  Each line contains one entry which is a first name then a
';' then
a last name.  Some lines begin with a # -- they are commented out
because I'm
no longer friends with them.  Naturally, Phil Wadler falls into that
category. :-) !

The Haskell program I want to write to do this would look something like:

-------------------------

{|
pdata Line =
  Comment /#.*/      
| Name    {first::Pstr /;/,
           last ::Pstr /\n/}

ptype Friends = (x::Pint, |{ x > 0 }|, /\n/, PlistFW x)
|}

friendsToXML :: String -> XML
friendsToXML s = PADSTools.toXML Friends s

-------------------------

Notice the following syntactic features:

-- {| and |} are delimiters that begin/end pads code (I don't really
care what the delimiters are as long as they are relatively
concise. For instance, if the delimiters were $( ... ), for instance,
that would be fine.

-- inside {| and |}, we can jump back into Haskell by using the delimiters
|{ and |}

-- there are some built-in, pre-defined base types like Pstr (for
parsing and
printing strings) and Pint (for parsing and printing integers), PlistFW
(which
takes an argument x to specify the number of elements in the list)

-- regular expressions /..../ show up in the middle of what would
otherwise be
Haskell type declarations

-- there is syntax for declaring datatype-like things (introduced by
pdata keyword)

-- the declarations are dependent types in that there is
binding (eg: the x::Pint in the "Friends" type -- the x is bound here)

-- variables bound in pads code can then be used in Haskell code nested
inside the declaration (eg: the Haskell expression x > 0 refers to the
variable x, defined in the outer pads code).
 
-- the outer Haskell code refers to declarations made inside the PADS
code.  (eg: the Haskell function "friendsToXML s = PADS.Tools.toXML
Friends s" refers to Friends, where Friends would be bound to a
datastructure generated by the compiler for the pads code.  PADSTools
is a module defined a priori that contains a number of functions such
as toXML, parse, print, query, etc.)

Anyway, if you have any comments on how I should handle the syntactic
extensions,
let me know.

Thanks again,
Dave
_______________________________________________
template-haskell mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/template-haskell
Reply | Threaded
Open this post in threaded view
|

Re: using template haskell to implement pads for haskell?

Ian Lynagh

Hi David,

On Sun, Jun 29, 2008 at 03:25:47PM -0400, David Walker wrote:
>
> {|
> pdata Line =
>  Comment /#.*/      
> | Name    {first::Pstr /;/,
>           last ::Pstr /\n/}
>
> ptype Friends = (x::Pint, |{ x > 0 }|, /\n/, PlistFW x)
> |}

You can't create new syntax with TH; it's just Haskell (plus the TH
syntactic extensions themselves, i.e. $( e ), and a few variants of
[| e |]).

You'd have to encode the info into Haskell syntax somehow, e.g.
something like

$(
    pdata "Line" [C "Comment" [], C "Name" [ ("first", ["Pstr", "/;"]),
        ...
 )

or parse them from strings (which isn't nice either, as Haskell doesn't
have nice multi-line strings).


Thanks
Ian

_______________________________________________
template-haskell mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/template-haskell
Reply | Threaded
Open this post in threaded view
|

Re: using template haskell to implement pads for haskell?

Marc Weber
In reply to this post by David Walker-11
Hi Dave,

I think I don't have to tell you much about template-haskell because
there is a small wiki page.

To get started try:
ghci -fth
:m +Language.Haskell.TH
:m +Language.Haskell.TH.Syntax
pprint <<= runQ [| (\a -> a +7 ) |]
[d|  |] top level declarations
[t|  |] types
[| |] code you can use in the middle anywhere

The cool thing now is that you can use pprint as shown above to pretty
print the automatically generated human readable haskell code and ouput
it using
$( runIO $ do putStrLn "test" >> hFlush stdout )
With some simple substitutions you can make compilable code out of that
(Eg removing GHC.Base.  and so on)
So you get both: Generated code, but you can also directly read the
description from file and generate your code on the fly while compiling.

The ghci approach works nicely, however in you propably want to use the
helper functions found in Langauge.Haskell.TH.Lib.

There is an alternative: DrIft which derives some instances
automatically. Get the source and have a look at those examples.

Looking at hackage there is another alternative:
        # haskell-src library: Manipulating Haskell source code
        # haskell-src-exts library: Manipulating Haskell source: abstract syntax, lexer, parser, and pretty-printer

On Sun, Jun 29, 2008 at 03:25:47PM -0400, David Walker wrote:

>  hi,
>
>  I am new to Haskell and even more so to Haskell templates -- if there
>  is an obvious answer to my question, please just point me at the
>  relevant URL.  Thanks! (If you think I should email this query to
>  a broader Haskell mailing list let me know too.)
>
>  My friends and I are thinking about adding an extension to Haskell to
>  implement a variant of the PADS domain-specific language.  PADS is a
>  convenient syntax to describe a file format and generate a bunch of
>  tools for it such as parser, printer, xml translator, semi-structured
>  query engine, statistical profiler, etc.  (We also have tools to
Query enginge ? is this xml only?
I'm asking because I'm working on a very small RDBM replacement holding
data in memory only which can be used with HAppS state easily. I've
nearly finished modeling inserting/ updating rows but I'm still unsure
how to write a good (dynamic) query engine for it because some queries
are know at run time only (eg when unsing different filters within web
applications)..

>From hackage this might be interesting as well:
HXQ library and program: A Compiler from XQuery to Haskell

Sincerly
Marc Weber
_______________________________________________
template-haskell mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/template-haskell
Reply | Threaded
Open this post in threaded view
|

Re: using template haskell to implement pads forhaskell?

Claus Reinke
In reply to this post by Ian Lynagh
> (which isn't nice either, as Haskell doesn't have nice multi-line strings).

well, how about using the new quasiquoting to get HereDocs:-)

    {-# LANGUAGE TemplateHaskell #-}
    module Here where

    import Language.Haskell.TH
    import Language.Haskell.TH.Quote

    here :: QuasiQuoter
    here = QuasiQuoter (litE . stringL) (litP . stringL)

then

    {-# LANGUAGE QuasiQuotes #-}
    {-# LANGUAGE TemplateHaskell #-}

    import Here

    s = [$here|
      hello
      multiline
      world
      |]

    test = lines s

gives us

    *Main> test
    [" \r","  hello\r","  multiline\r","  world\r","  "]

Claus


_______________________________________________
template-haskell mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/template-haskell
Reply | Threaded
Open this post in threaded view
|

Re: using template haskell to implement pads for haskell?

David Walker-12
In reply to this post by Marc Weber
> Query enginge ? is this xml only?

PADS can describe pretty much any ascii or binary data file.  Given a
PADS description, it's possible to interpret data matching the
description as if it were xml.  The PADX tool (implemented by
primarily by Mary Fernandez, Kathleen Fisher and Yitzhak Mandelbaum)
makes it possible to write Xquery programs and evaluate them against
the data.  PADX uses Galax, the xquery query engine implemented by
Mary and Jerome Simeon.

> >From hackage this might be interesting as well:
> HXQ library and program: A Compiler from XQuery to Haskell

Thanks, this might be very useful in the future.

Dave
_______________________________________________
template-haskell mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/template-haskell
Reply | Threaded
Open this post in threaded view
|

RE: using template haskell to implement pads for haskell?

Simon Peyton Jones
In reply to this post by David Walker-11
Dave

It's not clear to me

a) whether or not you want new syntax (requires writing a parser)
b) whether you want a single description to generate multiple different Haskell programs, or just one

Concerning (a), as Claus says if you want special purpose syntax (ie not Haskell) then you need quasiquotation. This is only in the HEAD, not a released GHC, but it works reliably as far as I know.
http://www.haskell.org/ghc/dist/current/docs/users_guide/template-haskell.html#th-quasiquotation

Concerning (b), if you want to write a program that generates one or more Haskell programs, then Template Haskell is good.  But if you can get away with just one program, then you may not need that extra complexity.  Many domain-specific languages embedded in Haskell use just Haskell (e.g. Parsec, Fran, Yampa...), not TH nor quasiquotation.

You'd get a 30x wider audience on the Haskell Cafe mailing list, so yes, I'd try there too.  Even jumping to Template Haskell as a solution may be premature; I'm not sure.

Meanwhile perhaps other TH folk would like to join in?

Simon

| -----Original Message-----
| From: [hidden email] [mailto:[hidden email]] On Behalf Of
| David Walker
| Sent: 29 June 2008 20:26
| To: [hidden email]
| Cc: [hidden email] >> David Walker; [hidden email]
| Subject: [Template-haskell] using template haskell to implement pads for haskell?
|
| hi,
|
| I am new to Haskell and even more so to Haskell templates -- if there
| is an obvious answer to my question, please just point me at the
| relevant URL.  Thanks! (If you think I should email this query to
| a broader Haskell mailing list let me know too.)
_______________________________________________
template-haskell mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/template-haskell
Reply | Threaded
Open this post in threaded view
|

Re: using template haskell to implement pads for haskell?

David Walker-11
As simon suggests I'll transfer to the haskell-cafe mailing list and
respond there...

Dave

Simon Peyton-Jones wrote:

> Dave
>
> It's not clear to me
>
> a) whether or not you want new syntax (requires writing a parser)
> b) whether you want a single description to generate multiple different Haskell programs, or just one
>
> Concerning (a), as Claus says if you want special purpose syntax (ie not Haskell) then you need quasiquotation. This is only in the HEAD, not a released GHC, but it works reliably as far as I know.
> http://www.haskell.org/ghc/dist/current/docs/users_guide/template-haskell.html#th-quasiquotation
>
> Concerning (b), if you want to write a program that generates one or more Haskell programs, then Template Haskell is good.  But if you can get away with just one program, then you may not need that extra complexity.  Many domain-specific languages embedded in Haskell use just Haskell (e.g. Parsec, Fran, Yampa...), not TH nor quasiquotation.
>
> You'd get a 30x wider audience on the Haskell Cafe mailing list, so yes, I'd try there too.  Even jumping to Template Haskell as a solution may be premature; I'm not sure.
>
> Meanwhile perhaps other TH folk would like to join in?
>
> Simon
>
> | -----Original Message-----
> | From: [hidden email] [mailto:[hidden email]] On Behalf Of
> | David Walker
> | Sent: 29 June 2008 20:26
> | To: [hidden email]
> | Cc: [hidden email] >> David Walker; [hidden email]
> | Subject: [Template-haskell] using template haskell to implement pads for haskell?
> |
> | hi,
> |
> | I am new to Haskell and even more so to Haskell templates -- if there
> | is an obvious answer to my question, please just point me at the
> | relevant URL.  Thanks! (If you think I should email this query to
> | a broader Haskell mailing list let me know too.)
> _______________________________________________
> template-haskell mailing list
> [hidden email]
> http://www.haskell.org/mailman/listinfo/template-haskell
>  

_______________________________________________
template-haskell mailing list
[hidden email]
http://www.haskell.org/mailman/listinfo/template-haskell