How to turn LHExpr GhcPs into CoreExpr

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

How to turn LHExpr GhcPs into CoreExpr

Yiyun Liu

Hi ghc-devs,

I've been trying to implementing a function with the signature:

elaborateExpr :: GhcMonad m => String -> m CoreExpr

It should take a string of the form:

"\x y -> x <> y :: Semigroup a => a -> a -> a"

and give back a core expression with the dictionaries filled in:

\ ($dSem :: Semigroup a) (x :: a) (y :: a) -> (<>) $dSem x y


The goal is to use the function to add elaboration support for liquidhaskell.

I looked into the implementation of exprType and defined my own elaborateExpr similarly by calling desugarExpr on the expression (which has type LHsExpr GhcTcId) returned by tcInferSigma.

GhcTcId is a synonym of GhcTc so the program I wrote typechecks, but it's definitely not right. The elaborateExpr function I defined would return something even when the expression doesn't typecheck, or occasionally give a runtime exception:

ghc-elaboration-test: panic! (the 'impossible' happened)
  (GHC version 8.6.5 for x86_64-unknown-linux):
    dsEvBinds

I must have broken some invariants somehow.

What is the correct way of defining such a function (takes a string and returns a CoreExpr)? It appears to me that I should convert LHsExpr GhcPs into LHsExpr GhcTc first before calling deSugarExpr, but I don't know how.

Thank you,

- Yiyun


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

Re: How to turn LHExpr GhcPs into CoreExpr

Richard Eisenberg-5
You'll need to run the expression through the whole pipeline.

1. Parsing
2. Renaming
3. Type-checking
  3a. Constraint generation
  3b. Constraint solving
  3c. Zonking
4. Desugaring

I don't have the exact calls you should use for these steps, but I can give you some pointers.

1. parseExpression
2. rnLExpr
3a. tcInferSigma
3b. simplifyInfer
3c. zonkTopLExpr
4. dsLExpr

You may want to examine tcRnExpr for a template on how to do steps 2 and 3. Note that this function drops the expression and continues only with the type, but the setup around constraint solving is likely what you want.

Another place to look for inspiration is in the pipeline that GHCi uses to process user-written expressions. hscParsedStmt and its caller, hscStmtWithLocation may also be helpful. These functions also compile the statement (which you don't want to do), but you can see where the desugared statement comes out.

I hope this helps move you in the right direction!
Richard

On Jan 21, 2020, at 7:21 PM, Yiyun Liu <[hidden email]> wrote:

Hi ghc-devs,

I've been trying to implementing a function with the signature:

elaborateExpr :: GhcMonad m => String -> m CoreExpr

It should take a string of the form:

"\x y -> x <> y :: Semigroup a => a -> a -> a"

and give back a core expression with the dictionaries filled in:

\ ($dSem :: Semigroup a) (x :: a) (y :: a) -> (<>) $dSem x y


The goal is to use the function to add elaboration support for liquidhaskell.

I looked into the implementation of exprType and defined my own elaborateExpr similarly by calling desugarExpr on the expression (which has type LHsExpr GhcTcId) returned by tcInferSigma.

GhcTcId is a synonym of GhcTc so the program I wrote typechecks, but it's definitely not right. The elaborateExpr function I defined would return something even when the expression doesn't typecheck, or occasionally give a runtime exception:

ghc-elaboration-test: panic! (the 'impossible' happened)
  (GHC version 8.6.5 for x86_64-unknown-linux):
    dsEvBinds

I must have broken some invariants somehow.

What is the correct way of defining such a function (takes a string and returns a CoreExpr)? It appears to me that I should convert LHsExpr GhcPs into LHsExpr GhcTc first before calling deSugarExpr, but I don't know how.

Thank you,

- Yiyun

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


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

Re: How to turn LHExpr GhcPs into CoreExpr

Andreas Klebinger
I tried this for fun a while ago and ran into the issue of needing to provide a type environment containing Prelude and so on.
I gave up on that when some of the calls failed because I must have missed to set up some implicit state properly.
I didn't have an actual use case (only curiosity) so I didn't look further into it. If you do find a way please let me know.

I would also support adding any missing functions to GHC-the-library to make this possible if any turn out to be required.

As an alternative you could also use the GHCi approach of using a fake Module. This would allow you to copy whatever GHCi is doing.
But I expect that to be slower if you expect to process many such strings,

Richard Eisenberg schrieb am 22.01.2020 um 10:36:
You'll need to run the expression through the whole pipeline.

1. Parsing
2. Renaming
3. Type-checking
  3a. Constraint generation
  3b. Constraint solving
  3c. Zonking
4. Desugaring


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

Re: How to turn LHExpr GhcPs into CoreExpr

Yiyun Liu

Thank you all for your help! It turns out that I was missing the constraint solving and zonking step by desugaring the result of tcInferSigma directly.

I have the implementation of the function here. Not sure if it's 100% correct but at least it works for all the examples I can come up with so far.

- Yiyun

On 1/22/20 7:09 AM, Andreas Klebinger wrote:
I tried this for fun a while ago and ran into the issue of needing to provide a type environment containing Prelude and so on.
I gave up on that when some of the calls failed because I must have missed to set up some implicit state properly.
I didn't have an actual use case (only curiosity) so I didn't look further into it. If you do find a way please let me know.

I would also support adding any missing functions to GHC-the-library to make this possible if any turn out to be required.

As an alternative you could also use the GHCi approach of using a fake Module. This would allow you to copy whatever GHCi is doing.
But I expect that to be slower if you expect to process many such strings,

Richard Eisenberg schrieb am 22.01.2020 um 10:36:
You'll need to run the expression through the whole pipeline.

1. Parsing
2. Renaming
3. Type-checking
  3a. Constraint generation
  3b. Constraint solving
  3c. Zonking
4. Desugaring


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

Re: How to turn LHExpr GhcPs into CoreExpr

Richard Eisenberg-5
I don't know the exact semantics of the interactive context, etc., but that looks plausible. It won't give the *wrong* answer. :)

Thanks for sharing!
Richard

On Jan 23, 2020, at 4:52 AM, Yiyun Liu <[hidden email]> wrote:

Thank you all for your help! It turns out that I was missing the constraint solving and zonking step by desugaring the result of tcInferSigma directly.

I have the implementation of the function here. Not sure if it's 100% correct but at least it works for all the examples I can come up with so far.

- Yiyun

On 1/22/20 7:09 AM, Andreas Klebinger wrote:
I tried this for fun a while ago and ran into the issue of needing to provide a type environment containing Prelude and so on.
I gave up on that when some of the calls failed because I must have missed to set up some implicit state properly.
I didn't have an actual use case (only curiosity) so I didn't look further into it. If you do find a way please let me know.

I would also support adding any missing functions to GHC-the-library to make this possible if any turn out to be required.

As an alternative you could also use the GHCi approach of using a fake Module. This would allow you to copy whatever GHCi is doing.
But I expect that to be slower if you expect to process many such strings,

Richard Eisenberg schrieb am 22.01.2020 um 10:36:
You'll need to run the expression through the whole pipeline.

1. Parsing
2. Renaming
3. Type-checking
  3a. Constraint generation
  3b. Constraint solving
  3c. Zonking
4. Desugaring



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

Re: How to turn LHExpr GhcPs into CoreExpr

Ben Gamari-3
It is slightly disheartening that this relatively simple use-case requires reaching so deeply into the typechecker.

If there really exusts no easier interface then perhaps we should consider adopting your elaborateExpr as part of the GHC API.

Cheers,

- Ben

On January 23, 2020 4:04:03 AM EST, Richard Eisenberg <[hidden email]> wrote:
I don't know the exact semantics of the interactive context, etc., but that looks plausible. It won't give the *wrong* answer. :)

Thanks for sharing!
Richard

On Jan 23, 2020, at 4:52 AM, Yiyun Liu <[hidden email]> wrote:

Thank you all for your help! It turns out that I was missing the constraint solving and zonking step by desugaring the result of tcInferSigma directly.

I have the implementation of the function here. Not sure if it's 100% correct but at least it works for all the examples I can come up with so far.

- Yiyun

On 1/22/20 7:09 AM, Andreas Klebinger wrote:
I tried this for fun a while ago and ran into the issue of needing to provide a type environment containing Prelude and so on.
I gave up on that when some of the calls failed because I must have missed to set up some implicit state properly.
I didn't have an actual use case (only curiosity) so I didn't look further into it. If you do find a way please let me know.

I would also support adding any missing functions to GHC-the-library to make this possible if any turn out to be required.

As an alternative you could also use the GHCi approach of using a fake Module. This would allow you to copy whatever GHCi is doing.
But I expect that to be slower if you expect to process many such strings,

Richard Eisenberg schrieb am 22.01.2020 um 10:36:
You'll need to run the expression through the whole pipeline.

1. Parsing
2. Renaming
3. Type-checking
  3a. Constraint generation
  3b. Constraint solving
  3c. Zonking
4. Desugaring



--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: How to turn LHExpr GhcPs into CoreExpr

Shao, Cheng
How about using `hscCompileCoreExprHook` to intercept the `CoreExpr`
from the ghci pipeline? There exist GHC API to evaluate a String to a
ForeignHValue iirc; we are not interested in the final ForeignHValue
in this case, we just want the CoreExpr, and the logic of generating
and linking BCO can be discarded.

Cheers,
Cheng

On Thu, Jan 23, 2020 at 1:55 PM Ben Gamari <[hidden email]> wrote:

>
> It is slightly disheartening that this relatively simple use-case requires reaching so deeply into the typechecker.
>
> If there really exusts no easier interface then perhaps we should consider adopting your elaborateExpr as part of the GHC API.
>
> Cheers,
>
> - Ben
>
> On January 23, 2020 4:04:03 AM EST, Richard Eisenberg <[hidden email]> wrote:
>>
>> I don't know the exact semantics of the interactive context, etc., but that looks plausible. It won't give the *wrong* answer. :)
>>
>> Thanks for sharing!
>> Richard
>>
>> On Jan 23, 2020, at 4:52 AM, Yiyun Liu <[hidden email]> wrote:
>>
>> Thank you all for your help! It turns out that I was missing the constraint solving and zonking step by desugaring the result of tcInferSigma directly.
>>
>> I have the implementation of the function here. Not sure if it's 100% correct but at least it works for all the examples I can come up with so far.
>>
>> - Yiyun
>>
>> On 1/22/20 7:09 AM, Andreas Klebinger wrote:
>>
>> I tried this for fun a while ago and ran into the issue of needing to provide a type environment containing Prelude and so on.
>> I gave up on that when some of the calls failed because I must have missed to set up some implicit state properly.
>> I didn't have an actual use case (only curiosity) so I didn't look further into it. If you do find a way please let me know.
>>
>> I would also support adding any missing functions to GHC-the-library to make this possible if any turn out to be required.
>>
>> As an alternative you could also use the GHCi approach of using a fake Module. This would allow you to copy whatever GHCi is doing.
>> But I expect that to be slower if you expect to process many such strings,
>>
>> Richard Eisenberg schrieb am 22.01.2020 um 10:36:
>>
>> You'll need to run the expression through the whole pipeline.
>>
>> 1. Parsing
>> 2. Renaming
>> 3. Type-checking
>>   3a. Constraint generation
>>   3b. Constraint solving
>>   3c. Zonking
>> 4. Desugaring
>>
>>
>>
>
> --
> Sent from my Android device with K-9 Mail. Please excuse my brevity.
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs