New Proposal: EasyMacros

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

New Proposal: EasyMacros

Anton Felix Lorenzen
Hello list,

I want to propose a new way of writing template-haskell macros.
It is based on the idea, that syntax like this:
do {
    x <- getLine;
    putStrLn x;
}
should be parsed into:
$( do
    [ [| x <- getLine |]
    , [| putStrLn x   |]
    ] )
Then a function (do :: NonEmpty ExpQ -> ExpQ) will be called
and executed.

This would allow for a couple of useful macros:
   - do
   - case
   - fold -- fold the ExpQs into one, see below for details
   - eval -- evaluate ExpQs at compile-time
   - (maybe even) hamlet -- evaluate hamlet QQ
   - CPP replacements?

Nothing will be added which isn't possible today.
Nonetheless it will allow for a much cleaner syntax
and by this make things usable which weren't usable before.

Also it might be easier to implement new features.
For example ApplicativeDo and RecursiveDo
could have been implemented by a hackage package.
MultiWayIf could be a function, too.

apply
   [1..(10*365)]
   map (replicate 3)
   concat

conc
   "Hello World! \n"
   "How are you? \n"

Greetings,
Anton

===== Example Macros =====

see in context: https://github.com/anfelor/EasyMacros

conc = fold [| (++) |]
apply = fold [|flip ($)|]

fold :: ExpQ -- (a -> b -> c)
    -> NonEmpty (Q Exp) -> Q Exp
fold _ (a :| []) = a
fold fn (a :| b : xs) = fold fn (([| fn $a $b |]) :| xs)

do_ :: NonEmpty (Q Stmt) -> Q Exp
do_ (x :| []) = x >>= \case
      BindS _ _ -> fail "The last statement in a 'do' block must be an
expression"
      NoBindS e -> return e
do_ (x :| xs) = x >>= \case
      BindS pat exp -> [| $(return exp) >>= \ $(return pat) -> $(do_
(fromList xs)) |]
      NoBindS   exp -> [| $(return exp) >> $(do_ (fromList xs)) |]
_______________________________________________
Haskell-prime mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: EasyMacros

Richard Eisenberg-2
This strikes me as a more powerful form of RebindableSyntax, blazing new territory. (Existing RebindableSyntax never use Template Haskell.)

I assume you've emailed the Haskell Prime list because you wish this to be considered for inclusion in the next version of the standard. However, an extension this large would need to be vetted by implementation in a compiler (assumedly, GHC) before we can consider inclusion in a standard. If you wish to pursue this, I recommend generating a groundswell of interest from the community and writing a more formal proposal detailing exactly how such macros should be desugared into Template Haskell. You give an example below, and that is helpful, but we would need a more formal description.

This is, certainly, an interesting idea and would allow for yet more flexible extensions to the language, all without changing the compiler.

Thanks,
Richard

On May 18, 2016, at 3:10 PM, Anton Felix Lorenzen <[hidden email]> wrote:

> Hello list,
>
> I want to propose a new way of writing template-haskell macros.
> It is based on the idea, that syntax like this:
> do {
>   x <- getLine;
>   putStrLn x;
> }
> should be parsed into:
> $( do
>   [ [| x <- getLine |]
>   , [| putStrLn x   |]
>   ] )
> Then a function (do :: NonEmpty ExpQ -> ExpQ) will be called
> and executed.
>
> This would allow for a couple of useful macros:
>  - do
>  - case
>  - fold -- fold the ExpQs into one, see below for details
>  - eval -- evaluate ExpQs at compile-time
>  - (maybe even) hamlet -- evaluate hamlet QQ
>  - CPP replacements?
>
> Nothing will be added which isn't possible today.
> Nonetheless it will allow for a much cleaner syntax
> and by this make things usable which weren't usable before.
>
> Also it might be easier to implement new features.
> For example ApplicativeDo and RecursiveDo
> could have been implemented by a hackage package.
> MultiWayIf could be a function, too.
>
> apply
>  [1..(10*365)]
>  map (replicate 3)
>  concat
>
> conc
>  "Hello World! \n"
>  "How are you? \n"
>
> Greetings,
> Anton
>
> ===== Example Macros =====
>
> see in context: https://github.com/anfelor/EasyMacros
>
> conc = fold [| (++) |]
> apply = fold [|flip ($)|]
>
> fold :: ExpQ -- (a -> b -> c)
>   -> NonEmpty (Q Exp) -> Q Exp
> fold _ (a :| []) = a
> fold fn (a :| b : xs) = fold fn (([| fn $a $b |]) :| xs)
>
> do_ :: NonEmpty (Q Stmt) -> Q Exp
> do_ (x :| []) = x >>= \case
>     BindS _ _ -> fail "The last statement in a 'do' block must be an expression"
>     NoBindS e -> return e
> do_ (x :| xs) = x >>= \case
>     BindS pat exp -> [| $(return exp) >>= \ $(return pat) -> $(do_ (fromList xs)) |]
>     NoBindS   exp -> [| $(return exp) >> $(do_ (fromList xs)) |]
> _______________________________________________
> Haskell-prime mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime

_______________________________________________
Haskell-prime mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: EasyMacros

Anton Felix Lorenzen
In reply to this post by Anton Felix Lorenzen
I am glad you like the idea. I fully understand
that it should be an extension first, I simply followed the
https://prime.haskell.org/wiki/Process

I am think I am not able to make a prime wiki page
(at least I wasn't able to find a button for this).

Should I create a ghc wiki page?
Email the Haskell-cafe list?

This is my first proposal and I m a bit lost here.

Thanks,
Anton
_______________________________________________
Haskell-prime mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime
Reply | Threaded
Open this post in threaded view
|

Re: New Proposal: EasyMacros

Richard Eisenberg-2
Eek. Just realized that this went unanswered! Sorry!

Yes, a good next step is to email the Haskell-cafe list or to post on reddit.com/r/haskell. For the wiki page, I meant at the GHC developers' wiki, here: https://ghc.haskell.org/trac/ghc   But it might be best to get feedback first.

Richard

On May 19, 2016, at 5:20 AM, Anton Felix Lorenzen <[hidden email]> wrote:

> I am glad you like the idea. I fully understand
> that it should be an extension first, I simply followed the https://prime.haskell.org/wiki/Process
>
> I am think I am not able to make a prime wiki page
> (at least I wasn't able to find a button for this).
>
> Should I create a ghc wiki page?
> Email the Haskell-cafe list?
>
> This is my first proposal and I m a bit lost here.
>
> Thanks,
> Anton
> _______________________________________________
> Haskell-prime mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime

_______________________________________________
Haskell-prime mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime