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

Dhall.TH functions should call addDependentFile #2518

Open
gelisam opened this issue May 8, 2023 · 1 comment
Open

Dhall.TH functions should call addDependentFile #2518

gelisam opened this issue May 8, 2023 · 1 comment

Comments

@gelisam
Copy link

gelisam commented May 8, 2023

As previously recommended by @sellout here, when dhall code is loaded via TemplateHaskell, it is important to call addDependentFile on the dhall file. Otherwise, changes to that dhall file will appear to be ignored!

The problem

Here is a small example demonstrating the problem.

$ cat ./Main.hs
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Main where

import Dhall.Core
import Dhall.TH

config :: Expr () ()
config = $(staticDhallExpression "./example.dhall")

main :: IO ()
main = do
  print config

$ echo 42 > example.dhall
$ ghc ./Main.hs
$ ./Main
NaturalLit 42

So far so good. Let's try changing the configuration:

$ echo 43 > example.dhall
$ ghc ./Main.hs
$ ./Main
NaturalLit 42

Oh no, the configuration change was ignored!

The workaround

One unappealing workaround is to clear away the build artifacts in order to force ghc to rebuild:

$ rm ./Main.o
$ ghc ./Main.hs
$ ./Main
NaturalLit 43

Towards a solution

A better fix is to use addDependentFile to tell ghc that if example.dhall changes, it needs to recompile the TemplateHaskell code which reads that file:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Main where

import Dhall.Core
import Dhall.TH
import Language.Haskell.TH.Syntax

config :: Expr () ()
config = $(do
  addDependentFile "./example.dhall"
  staticDhallExpression "./example.dhall")

main :: IO ()
main = do
  print config

ghc now rebuilds when the dhall file changes.

$ echo 42 > example.dhall
$ ghc ./Main.hs
$ ./Main
NaturalLit 42

$ echo 43 > example.dhall
$ ghc ./Main.hs
$ ./Main
NaturalLit 43

Not quite there

Alas, the above does not work in all cases. dhall is a language which supports imports, and thus it is possible for example.dhall to in turn depend on another dhall file:

$ echo "./other.dhall" > example.dhall

Now our addDependentFile "./example.dhall" is insufficient; we should also have included addDependentFile "./other.dhall"!

$ echo 42 > other.dhall
$ ghc ./Main.hs
$ ./Main
42

$ echo 43 > other.dhall
$ ghc ./Main.hs
$ ./Main
42

Proposed solution

Rather than putting the onus on the user of Dhall.TH to maintain a list of the dependencies of their dhall files, it would make a lot more sense if it was the responsibility of the Dhall.TH functions to call addDependentFile on all the imports they encounter in the process of evaluating a dhall expression.

@Gabriella439
Copy link
Collaborator

I'd accept a PR for this but I probably won't get around to implementing this myself

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants