[GHC] #13608: Expose the type of quasiquotes
GHC
ghc-devs at haskell.org
Wed May 31 18:42:53 UTC 2017
#13608: Expose the type of quasiquotes
-------------------------------------+-------------------------------------
Reporter: | Owner:
facundo.dominguez | facundo.dominguez
Type: bug | Status: patch
Priority: normal | Milestone:
Component: Template Haskell | Version: 8.0.1
Resolution: | Keywords: QuasiQuotes
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: 12778 | Differential Rev(s): Phab:D3610
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by facundo.dominguez):
I don't submit a GHC proposal yet because we don't have yet a good
solution to propose, we only have a problem and a couple of leads to
investigate.
I state the problem here in a general form. An account that Mathieu did a
while ago can be found in ticket:12778#comment:8.
Template Haskell quasiquotes allow to embed other languages in Haskell
programs.
One can use this ability to generate and compile code in a foreign
language and
then have the result invoked from Haskell.
For quasiquotations to be typesafe though, the implementation of the
quasiquoter
needs to tell the foreign compiler which types are expected of the
antiquoted
variables and of the returned value. Quasiquoters currently have no way to
find
the expected return type if the programmer does not supply it explicitly.
Let's consider the following example using inline-java. The package
`inline-java`
implements a quasiquote which allows to embed fragments of Java programs
in
Haskell modules.
{{{
jappendWorld :: Text -> IO Text
jappendWorld = [java| $x + " World!" |]
}}}
This generates some Java code that is compiled by a Java compiler. It also
generates some Haskell code which marshals values between Java and Haskell
and
invokes the result of compiling the Java code.
The java code that is generated looks like
{{{
class ClassFreshName {
public static Object freshName(String x) {
return x + " World!";
}
}
}}}
The quasiquoter knows that the antiquote `x` has type `String` in Java,
because
it knows that `x` has the type `Text` in Haskell and it can marshal the
values
between the two types. The quasiquoter can find the Haskell type of `x`
via the
Template Haskell function `reify` as implemented in ticket:11832.
However, the quasiquoter has currently no way to find the expected return
type.
Therefore, it assumes that any return value is of the catch-all Java type
`java.lang.Object`. This is problematic, because it is up to the
programmer
to use the return value in a way appropriate to its type. If the value
returned
by the quasiquote does not match the type expected by the programmer on
the
Haskell side, the program has undefined behavior.
Solutions:
1. Have the programmer supply the return type, this is how the package
`inline-c`
works to embed `C` programs in Haskell. This involves effort on the part
of the user to write the return type in every quasiquotation.
2. Use typed splices instead of quasiquotes. e.g.
{{{
$$(java [string| $x + " World!" |])
}}}
Typed splices do expose the expected type to the implementation, and
the generated code
could be tailored by using type classes. This is rather clumsy to write
while
quasiquotes are the best fit.
3. Implement typed quasiquotes, so we can write
{{{
[java|| $x + " World!" ||]
}}}
which desugars to
{{{
$$(typedQuoteExp java " $x + \" World!\")
}}}
4. What this ticket proposed.
5. Similar to (4), but avoid introducing a name with a hash of the
location.
For this, we extend the type checker so when it finds a splice, it adds
a
binding to the typing environment which has the type of the splice and
an
identifier uniquely associated to the splice. Calls to `reify` can then
find this binding and yield the type in the same fashion that it is
done
with antiquoted variables.
Let me know if this should still be sent to GHC proposals. Besides that,
any thoughts or advice?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13608#comment:12>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list