Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interpret TemplateHaskell's Exp and TExp #85

Open
clojurians-org opened this issue Aug 28, 2019 · 6 comments
Open

Interpret TemplateHaskell's Exp and TExp #85

clojurians-org opened this issue Aug 28, 2019 · 6 comments

Comments

@clojurians-org
Copy link

i need to concat some code from web ui .
the pain text process is unsafe for me.
as i know, the ghc compiler can compile the Quasi monad to haskell code.
so i want to know, is it feasible to run Quasi mond using the library?

@gelisam
Copy link
Contributor

gelisam commented Aug 28, 2019

There are many packages defining a type named Quasi, could you link to the one you mean?

@gelisam
Copy link
Contributor

gelisam commented Aug 28, 2019

I think you mean the Q Monad? TemplateHaskell's Quasi is a typeclass.

No, hint does not "run" Q programs. You don't need to: you can simply use the runQ function to run your Q program in IO.

Q programs often produce expressions of type Exp or TExp a, an AST which you can observe and manipulate. I am guessing that you want to examine that AST in order to e.g. filter out calls to unsafePerformIO and other unsafe functions. hint does not support interpreting Exp values, but I think it would be a very useful feature to add. In the meantime, you can use TemplateHaskell's pretty-printer to render your AST to a Doc and then to a string, and then use hint to interpret that string. ghc uses a different AST representation than Exp, so that's probably the route I would use if I wanted to add the feature to hint.

Finally, note that with hint, the code which calls the interpreter needs to specify which modules are imported, the interpreted code is not allowed to write import declarations. So you don't have to worry about interpreting code which calls unsafePerformIO unless you explicitly import a module which exports it. The main thing I would worry about are infinite loops, which I would thwart using the timeout function.

@gelisam gelisam closed this as completed Aug 28, 2019
@clojurians-org
Copy link
Author

@clojurians-org clojurians-org changed the title is it feasible to run Quasi mond using the library? is it feasible to run Q(Quasi) monad using the library? Sep 2, 2019
@gelisam
Copy link
Contributor

gelisam commented Sep 2, 2019

I must reiterate that the sensible task here is to interpret an AST, that is, a value of type Exp, not a computation of type Q Exp which produces an AST after performing a number of side-effects, e.g. allocating fresh variables.

Here's is my understanding of that wiki page. When ghc encounters a TH splice, it parses the splice's contents as an expression of type Q Exp, and it compiles that expression to bytecode. Then, if the -fexternal-interpreter flag is enabled, it sends that bytecode to iserv. During the execution of that bytecode, iserv may encounter actions from the Q Monad. If so, iserv sends that action back to ghc, who responds with the result. Eventually, iserv finishes with a value of type Exp, which it sends back to ghc so that it can be spliced into the surrounding code.

So iserv does not interprets Q actions nor the resulting Exp, ghc does. And ghc does not compile Exp into bytecode, it splices the Exp into the surrounding code, and then compiles the resulting code.

That makes me realize that if we want to extend hint to interpret Exps, it would probably be more sensible to use the ghc API to splice the Exp into some dummy code and to interpret that.

I will reopen the ticket in order to track that approach, but I won't have time to look into it for a while. So once again, I recommend manipulating the Exp values to make sure they look safe enough, then pretty-printing them to a string, then interpreting the string.

@gelisam gelisam reopened this Sep 2, 2019
@clojurians-org
Copy link
Author

thanks so much, pretty-printing is fine for me.
i just learn the intepreter mechanism a little.

myFunc :: Q Exp
myFunc = do
  x <- newName "x"
  return $ LamE
    [VarP x]
    (InfixE (Just (VarE x)) (VarE '(+)) (Just (LitE (IntegerL 1))))

-- repl
putStrLn $(X.myFunc >>= stringE . pprint)

@gelisam gelisam changed the title is it feasible to run Q(Quasi) monad using the library? Interpret TemplateHaskell's Exp and TExp Sep 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants