How to load `stack ghci` without compiling & linking the whole project? - haskell

Does for anyone else stack compile & link the whole project when only stack ghci is asked for?
Shouldn't it skip the former and jump into ghci right away to load sources? I've observed it to do both for me on most of my projects and therefore it's doing seemingly superfluous work. Is this by design, or might have I misconfigured some of my stack projects?
Perhaps is this done by cabal underneath without stack asking for it?
And at any rate, is there something I could do to skip the compilation + linking when I just want to enter stack ghci?

From the Haskell Tool Stack Documentation:
Speeding up initial load
There are two ways to speed up the initial startup of ghci:
--no-build, to skip an initial build step. This only works if the dependencies have already been built.
You can also have stack ghci skip loading sources (if you know you only want one file loaded in, and can do it by hand) by using:
--no-load, to skip loading all defined modules into ghci. You can then directly use :load MyModule to load a specific module in your project.

I've just realized that -fobject-code may also play a part in this. I'm unsure where it is being set (not on the command line, not in the .cabal/package.yaml file and not in ~/.ghci either).
Nevertheless when I negate it with --ghci-options=-fbyte-code the recompilation doesn't seem to be taking place.
I still hope to hear others' responses as I'd like to understand more thoroughly why the -fobject-code may require minutes for full recompilation on initial load, since :reloading only takes about a second after a file has changed. (E.g. with ghcid too.)

Related

Haskell stack build FLTKHS after changes

Busy discovering Haskell libs. Found FLTKHS for GUI building. Its example fltks-hello-world works great as a skeleton for discovering the all the lib has to offer. However: when changing anything in the source file (fltkhs-hello-world.hs), does one need to stack build it all over? GHCi doesn't seem to grasp the FLTKHS imports, so the REPL is IMO no viable option. Interested in your way of working to learn....
Found out that future builds are way quicker. Not as fast as GHCi though...

re-running Setup.hs and change detection

I took the habit of managing my post-install setup things in the Setup.hs. The advantages are clear: it's coded in haskell, and it has access to the app data directory, where the binary will get installed.
I'm using it now for instance, to copy the QML data files and icons that a haskell QML application needs to the installation folder.
This all worked well until recently, but now stack started optimizing the build a lot, and if it detects that no haskell files changed, it won't re-trigger the Setup.hs. That obviously doesn't work for me, because I'd like my QML files and icons to get copied every time I run stack install during development.
I can't find a flag for stack that would trigger just the Setup.hs and nothing else (or little else -- certainly clean and --reconfigure force rebuilding too many things). How are people doing that? Should I write a shell script? But it'll have trouble finding the target directory for the installation, plus it's less portable that the haskell in my Setup.hs?
I feel stack are probably right in their reasoning and if my current way was really correct they would have enabled this scenario by now. So either there's a stack flag that I don't see, either I'm doing it wrong I think.
NOTE: stack is so smart that not even touch Setup.hs or of another .hs file helps to re-trigger its execution. I must physically change the contents of one file.
NOTE2: Ah, I re-discovered stack path to find out target path information. I could use that from a shell script to install the files. Still feels like a shame to write that in shell when I have haskell...
NOTE3: posted the question on the stack mailing list now...
NOTE4: actually opened a stack bug now

Haskell: Debugging Long Compilation Times on Stack Projects

I'm currently using Stack to build a project, which totals about 80 modules and 13,000 lines of code. Currently, compilation takes about 3 minutes for a minor change in my types files, which is unacceptable -- it prevents me from rapidly testing my code via stack ghci. It also significantly slows down a number of things: for instance, pair programming with peers or consulting with experts.
I would like to be able to figure out why compilation is taking so long, and what I can do to speed it up. Is there some way to profile compilation times?
Additionally, how can I tell whether it is stack or ghc that is slow?
I know about setting -O0, though this does not seem to help compilation times. I also know that TemplateHaskell and Typeclass Resolution can take a while -- is there any way I can get better resolution on how long these are taking?
Note: i have seen Speed up compilation in GHC, but that was from 2013, and hdevtools currently does not work on my setup.
In case this question is still relevant, you could try this:
stack ghci --fast --no-build --ghc-options="-fbyte-code"
IIRC using this got me the quickest results with stack ghci.
If this doesn't help enough, you could look in the direction of --ghc-options="-dshow-passes". I myself am also looking in this direction currently to try to speed up a build/ghci-reload.

Using the GHC API to do a "dry run" of code compilation

I'm working on a fairly simple text-editor for Haskell, and I'd like to be able to highlight static errors in code when the user hits "check."
Is there a way to use the GHC-API to do a "dry-run" of compiling a haskell file without actually compiling it? I'd like to be able to take a string and do all the checks of normal compilation, but without the output. The GHC-API would be ideal because then I wouldn't have to parse command-line output from GHC to highlight errors and such.
In addition, is it possible to do this check on a string, instead of on a file? (If not, I can just write it to a temp file, which isn't terribly efficient, but would work).
If this is possible, could you provide or point me to an example how how to do this?
This question ask the same thing, but it is from three years ago, at which time the answer was "GHC-API is new and there isn't good documentation yet." So my hope is that the status has changed.
EDIT: the "dry-run" restriction is because I'm doing this in a web-based setting where compilation happens server side, so I'd like to avoid unnecessary disk reads/write every time the user hits "check". The executable would just get thrown away anyways, until they had a version ready to run.
Just to move this to an answer, this already exists as ghc-mod, here's the homepage. This already has frontends for Emacs, Sublime, and Vim so if you need examples of how to use it, there are plenty. In essence ghc-mod is just what you want, a wrapper around the GHC API designed for editors.

Monitoring GHC activity

If GHC takes a long time to compile something, is there a way to find out what it's doing?
Firstly, it would be nice to know if I've actually crashed the compiler (i.e., put it into some sort of infinite loop somehow), or whether it's actually making progress, but just very slowly.
Secondly, it would be nice to know exactly what part of the compilation process GHC is having trouble with. Is it the parsing, or desugaring, or type-checking, or Core optimisation, or code generation, or...?
Is there some way to monitor what's going on? (Bearing in mind that if GHC is taking a long time, that probably means it's doing a lot of work, so if you ask for too much output it's going to be huge!)
GHC already tells you which modules it's trying to (re)compile. In my case, the problem is a single self-contained module. I'd like to know where GHC is getting stuck.
Following Daniel Fischer's comment, I tried running GHC with different verbosity options.
-v1: Produced a bit more output, but nothing during the main compilation step.
-v2: Tells you what step GHC is currently doing (parser, desugar, type check, simplifier, etc). This is pretty much what I actually wanted.
-v3: Appears to make the simplifier actually dump what it's doing to the console - bad idea while compiling 8MB of source code!
So it seems that -v2 is the place to start.
(In the specific case of the program that prompted this question, it seems GHC is spending forever in the type checking phase.)

Resources