Building against precompiled dependencies · Issue #2477 · purescript/purescript · GitHub
Skip to content

Building against precompiled dependencies #2477

Open

Description

@ElvishJerricco

You can see an example of this in this Nix setup I'm experimenting with. The problem is that psc doesn't provide any means for depending on code you've already compiled. If you want to use precompiled code, you have to copy it into the output directory, and include the sources for that code in the list of sources for psc. This is at best clumsy, and is prone to issues with timestamps changing on copy. It'd be nice if there were some intermediate representation (corefn?) that preserved the necessary information for compiling against.

Activity

  1. paf31 commented on Dec 12, 2016

    @paf31
    Contributor

    The data format you want is the externs.json format, but there is no command line API for building against a set of externs files right now. We could add one though. The closest thing right now is psc-ide's rebuild command.

  2. modified the milestones: Approved, Ideas on Dec 12, 2016
  3. ElvishJerricco commented on Dec 12, 2016

    @ElvishJerricco
    Author

    Ah cool. Yea having a CLI for building against externs.json sounds like the perfect solution. Are you saying that psc-ide is already doing this sort of thing? Meaning that would be a good place to look if I wanted to try implementing this?

  4. paf31 commented on Dec 12, 2016

    @paf31
    Contributor

    Yes, psc-ide, PSCi and Try PureScript all use this method. It's handled by the rebuild function in Make.hs.

  5. ElvishJerricco commented on Dec 12, 2016

    @ElvishJerricco
    Author

    Cool. I'll take a look at it and let you know if I have the time to work on a PR for this.

  6. paf31 commented on Dec 12, 2016

    @paf31
    Contributor

    Great, thanks! If you do, let's make sure to hash out a basic plan for the command line interface here so that others can review it too.

  7. ElvishJerricco commented on Dec 12, 2016

    @ElvishJerricco
    Author

    Sure. My first thoughts are to make it similar to the classical C compiler flags for external libraries.

    psc -L/path/to/somelib/output/ $mysources

    This would tell psc that it can find the externs.json files for modules in somelib at /path/to/somelib/output/ModuleName/externs.json.

  8. ElvishJerricco commented on Dec 17, 2016

    @ElvishJerricco
    Author

    So I've been looking at this today. I think there needs to be more than just a flag for psc. With ghc in Nix, you can use haskellPackages.ghcWithPackages (self: [ self.async self.transformers ... ]) to get a ghc that automatically compiles against whatever packages you need. So when you enter a nix-shell with such a ghc, you can use ghc Main.hs, or ghci, or even cabal configure, and they all just automatically include the packages you specified from Nix. I'm not sure, but I believe this is accomplished by replacing ghc with a script that calls ghc with the correct arguments (and the same goes for ghci).

    To get the same behavior with the psc toolchain, there would have to be a flag not just in psc, but also in psci, psc-bundle, etc. etc.. Does this sound too broad-scoped?

  9. ElvishJerricco commented on Dec 23, 2016

    @ElvishJerricco
    Author

    To do what I suggested in that last comment, a number of things would have to be refactored to work with ExternsFile instead of Module, since there's no way to recover a Module from ExternsFile AFAIK. So for now I'm just going to see if I can get make to build against a list of (ModuleName, ExternsFile), and pass an empty list everywhere but psc.

  10. paf31 commented on Dec 23, 2016

    @paf31
    Contributor

    @ElvishJerricco You shouldn't need full modules for dependencies to just compile a single module. You just need an Environment which contains their type definitions. The ExternsFile structures can be used to create an Environment.

  11. ElvishJerricco commented on Dec 23, 2016

    @ElvishJerricco
    Author

    Ah, I think I see my mistake. I thought this field was the only way the psci got a hold of any definitions. I see now that this field provides an Environment. Does completion work with definitions in the Environment? Looking through Completion.hs, it seems to use Module a lot.

  12. paf31 commented on Dec 23, 2016

    @paf31
    Contributor

    I would expect it to use the Environment, but I'm not sure to be honest.

  13. ElvishJerricco commented on Dec 23, 2016

    @ElvishJerricco
    Author

    At the very least, I'd expect it to be possible with the current Environment format. So worst case scenario, completion just needs a bit of a refactor.

  14. ElvishJerricco commented on Jul 14, 2017

    @ElvishJerricco
    Author

    In case it's not clear by now, I will not be completing this feature myself, should anyone else want to give it a shot.

  15. denibertovic commented on Sep 10, 2019

    @denibertovic

    I was wondering what the current state of this issue is. @paf31 I know I probably shouldn't ping you but perhaps you would know who to ask instead?

  16. hdgarrood commented on Sep 10, 2019

    @hdgarrood
    Contributor

    I think work on this issue specifically should wait until there has been progress on #3493.

  17. joneshf commented on Mar 22, 2020

    @joneshf
    Member

    @hdgarrood While I understand that #3493 and this issue are related, and I believe I understand what you explained here, it's not clear why this work cannot happen until #3493 gets moving. Can you explain more what is blocking work from progressing here?

    I'd like to make a PR to allow compiling against pre-compiled artifacts, but I don't want to do that if it would be rejected for doing things out of order. If it would, I'll refrain from making the PR.

  18. hdgarrood commented on Mar 22, 2020

    @hdgarrood
    Contributor

    We could start on this before #3493 gets moving, but the reason I’m a bit hesitant is basically that I think we are likely to end up with a better API if we address it via #3493 (as that would solve the need here and quite a few others besides). Various other tools in the ecosystem (pursuit, spago, even the way docs are handled inside the compiler) have had to come up with their own separate ways of dealing with packages, causing a few awkward corners, and this feels to me like it would take us further down that path. There’s also the issue that if we were to do this first and later came back and did #3493 (which I do want to do pretty soon, especially as we are starting to move away from Bower and to our own registry in purescript/registry) we would end up with more compiler API surface area, which means more potential places for bugs, more stuff that users need to get their head around, etc.

  19. joneshf commented on Mar 23, 2020

    @joneshf
    Member

    Thanks for explaining. That makes sense. That also makes it clearer that there's at least two different ideas spurred on by this issue:

    1. Providing a way to compile against pre-compiled dependencies.
    2. Providing a better interface to incremental compilation.

    The two sound similar, but the former is inter-package focused, while the latter is intra-package focused. The former is what the title of this issue and the initial comment are about; the latter is what the first response and most of the conversation changed to. As you mention, the former can be solved by making more progress on packages. The latter can be solved by providing a better UX for the behavior in purs which already exists. The former is what people using the language care more about; the latter is what people writing tooling care more about.

    Neither solution (or any other ideas) can truly solve the other issue. But either solution kind of gives a way to solve the other. It seems like we need a solution to both of these if we're going to introduce the idea of packages. Which is to say, I think the only way to have one solution is to not have the idea of both modules and packages.

    I understand the concern for the purs API, but there's also the very real problem of trying to use PureScript for non-trivial things right now. If you'd prefer there not to be a PR, I won't make one. But, if you're okay with it, I'll send one. I won't be offended either way you decide, but it's largely up to you.

  20. hdgarrood commented on Mar 23, 2020

    @hdgarrood
    Contributor

    I’m not sure I agree with this distinction. Specifically I am not so certain that this proposal, if implemented, would provide a better interface to incremental compilation. It would of course give you more powerful interface, but, say, if in practice this leads to people getting errors at runtime because the API is too easy to use incorrectly, that’s maybe not such a good step. The behaviour that already exists has a fairly clear boundary between what is the responsibility of the user and what is the responsibility of the compiler: the user just has to supply all the source files and not fiddle with the output directory, and the compiler takes care of everything else.

    I also don’t follow your reasoning for why we shouldn’t have both modules and packages. Partially it’s that I disagree with the premises (see above), but also it’s not clear why we need a solution to both if we are going to introduce the concept of packages.

    I’m not saying I want to rule out doing this entirely, but I would prefer not to have a PR at this stage.

  21. joneshf commented on Mar 24, 2020

    @joneshf
    Member

    I’m not saying I want to rule out doing this entirely, but I would prefer not to have a PR at this stage.

    Fair enough.

  22. joneshf commented on Mar 30, 2021

    @joneshf
    Member

    If anybody else is still blocked by this issue and would like to try a drop-in replacement for purs compile that builds against pre-compiled dependencies, I'm working on a purs-compile binary that does just that.

    Caveats:

    • I'm currently only providing artifacts for Linux and macOS. Would like to setup Windows as well, but haven't found the time for it yet.
    • There's no npm package yet. Would like to make it so you could npm install @joneshf/purs-compile or something. Will come later.
    • It's currently still based on the 0.13.8 compiler (while waiting for everything to settle). The move to 0.14.0 should happen soon.

    More than happy to field questions over in that repo so as not to clutter up this Issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions