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

First class support for alternate backends #355

Closed
andyarvanitis opened this issue Aug 2, 2019 · 25 comments
Closed

First class support for alternate backends #355

andyarvanitis opened this issue Aug 2, 2019 · 25 comments

Comments

@andyarvanitis
Copy link

Has there been any discussion of being able to specify the options passed to purs in the config file? My particular use case (alternate backends) currently requires spago build -- -g corefn, which admittedly isn't bad, but it would be nice to just set it once for a project.

@f-f
Copy link
Member

f-f commented Aug 5, 2019

Hi @andyarvanitis! There has been no discussion about this yet, but so far the trend is that if there are commonly used compiler flags we try to take care of the more general use-case at the spago level rather than just passing them through (because the passthrough is not the best UX-wise and it introduces problems, e.g. see #353 or #216)

In this case I would be interested in investigating if we can have first-class support for alternate backends in spago, so e.g. in order to get the whole alternative build running you'd only have to add something like backend = "go" to your spago.dhall
I don't know what's the build workflow for the various backends, what are your thoughts on this?

@andyarvanitis
Copy link
Author

That sounds fine to me, and would make it even easier for people to use the alternate backends. The Go backend would probably be a better candidate (than C++) to start with, since its tooling is simpler. I'm still making some adjustments, but I can let you know how it works and what the requirements would be.

@f-f f-f mentioned this issue Aug 13, 2019
3 tasks
@f-f
Copy link
Member

f-f commented Aug 13, 2019

@andyarvanitis thanks, looking forward to it! I'll rename this issue to track support for alternate backends then 🙂

@f-f f-f changed the title purs compile flags in spago.dhall First class support for alternate backends Aug 13, 2019
@andyarvanitis
Copy link
Author

Following up on my previous comment, I think I have the golang tooling tweaking done (for now, at least). In the end, the only thing you currently need to do a go-backend build (typical case) involves one more step than what I showed in this issue earlier, namely:

$ spago build -- -g corefn
$ psgo

If spago (via the project config file) can provide those purs flags and then execute psgo, the user would get a native build/executable.

FYI, psgo has a command switch of --run which doesn't build an executable, but instead runs the results of the compilation immediately. Maybe something to think about supporting for backends in general. Same goes for --no-build, which only generates intermediate language (e.g. Go) source files.

Let me know what you think.

@f-f
Copy link
Member

f-f commented Aug 14, 2019

Sounds great! A possible UX for all of this could be:

  • adding an optional backend key to the spago.dhall, e.g. backend = "go"
  • if that's set, spago build would call spago build -- -g corefn && psgo
  • since psgo supports --run then we could make it so that spago run calls spago build -- -g corefn && psgo --run
  • I don't have UI ideas for using the --no-build flag. We have such flag already in Spago, but that skips the build entirely. One thing I'd like to avoid is adding flags for certain backends only in Spago, so maybe we can skip the --no-build flag for now?

If the above makes sense then I have a few questions:

  1. should Spago worry about fetching the psgo toolchain? And in general ensuring things like minimum psgo, purs versions?
  2. is the default package set fine for use with psgo?
  3. should we worry about bundling native go dependencies here or will psgo take care of that? (I'm afraid the go package management story has changed a lot since I last used it several years ago, so I have no context on this)

@f-f
Copy link
Member

f-f commented Aug 14, 2019

And cc @nwolverson: would this be interesting for the Erlang backend too?

@andyarvanitis
Copy link
Author

  • adding an optional backend key to the spago.dhall, e.g. backend = "go"
  • if that's set, spago build would call spago build -- -g corefn && psgo
  • since psgo supports --run then we could make it so that spago run calls spago build -- -g corefn && psgo --run

These all sound great to me.

  • I don't have UI ideas for using the --no-build flag. We have such flag already in Spago, but that skips the build entirely. One thing I'd like to avoid is adding flags for certain backends only in Spago, so maybe we can skip the --no-build flag for now?

Definitely. My mention of it was mainly for information; skipping for now sounds good.

  • should Spago worry about fetching the psgo toolchain? And in general ensuring things like minimum psgo, purs versions?

If spago is not responsible for installing purs, I'd say no for psgo too (which it seems is the case?). As for ensuring versions, maybe so. I'm happy to do what's needed to support it. For now, I think it would be fine not to check/ensure versions, especially if spago support for alternate backends can be marked "experimental" or something.

  • should we worry about bundling native go dependencies here or will psgo take care of that? (I'm afraid the go package management story has changed a lot since I last used it several years ago, so I have no context on this)

Good question. psgo should be able to take care of it using Go's module system (which it now uses, and currently pulls in all needed go dependencies). It might help if I add support for something like psgo --package-set psc-0.13.0-20190626 if I start tagging the go foreign implementations of those packages.

@f-f
Copy link
Member

f-f commented Sep 7, 2019

@csicar congrats for the release of the Kotlin backend! 🙂

Cc'ing you to ask if you'd have any inputs about this thread, i.e. would the current description of "integration" work for pskt too?

@csicar
Copy link
Contributor

csicar commented Sep 8, 2019

First of all, I think adding support for alternative backends is a great idea.

adding an optional backend key to the spago.dhall, e.g. backend = "go"

I think just using the name of the executable there might even be easier: eg. for the go backend you would write psgo.
Spago could expect the commandline interface to be standardized: calling the executable without arguments compiles; calling with --run runs the program.
For spago that would mean, that no special support for any backend would need to be build.

The proposed changes would also work for pskt

should Spago worry about fetching the psgo toolchain? And in general ensuring things like minimum psgo, purs versions?

I agree with @andyarvanitis there: I think spago shouldn't have to care about that

Some other ideas:

  • Support side-loading foreign files: PsKt and (if I remember correctly also PsGo) side-load foreign files for some standard purescript libraries (like prelude). If there was some support for that, the user experience would be improved. Especially cloning the correct version of the side-loaded repository for the installed package-set

@csicar
Copy link
Contributor

csicar commented Sep 15, 2019

btw: pskt now has the same cli interface as psgo, so no additional arguments need to be provided to compile

spago build -- --codegen corefn && pskt

@f-f
Copy link
Member

f-f commented Sep 18, 2019

@csicar thanks for the inputs, it all sounds great!

I have only one question:

Support side-loading foreign files: PsKt and (if I remember correctly also PsGo) side-load foreign files for some standard purescript libraries (like prelude). If there was some support for that, the user experience would be improved. Especially cloning the correct version of the side-loaded repository for the installed package-set

How would this work? Also why not just push the various .go and .cpp and .kt files to the core libraries so there wouldn't be the need for sideloading but we could just use the "official" versions?

Though I think the above is a detail, so I'd say at this point we have a pretty clear plan. Since I'm going to be short on time myself in the next weeks I'll detail here what I think it should be done, so anyone can eventually pick it up and implement it:

  • add a backend key to the Config, of type Maybe Text, where Nothing is the default backend and if it's Just cmd then cmd is the alternate backend executable
  • have spago build (and all the commands that build underneath) call spago build -- -g corefn && cmd
  • same for spago run but passing the --run flag to the backend
  • write down an "alternate backend CLI specification" in here, so that we have an interface that any backend can conform to if they want to work with Spago

@andyarvanitis
Copy link
Author

It's been a bit of a hard sell to get non-js foreign code into the official core libraries. I can understand some of their reluctance, though, especially with more backends coming onto the scene. The approach I started taking with the second generation C++ backend and then continued with the Go backend works around this. But I wouldn't say it's a perfect solution, and some versioning provisions are still needed. See the comments on Aug 14 above for some (very basic) discussion on the matter.

As for conforming to an "alternate backend CLI specification," I'm all for it, and would be happy to modify my stuff to accommodate it. Spago has been really great to work with!

@csicar
Copy link
Contributor

csicar commented Sep 19, 2019 via email

@csicar
Copy link
Contributor

csicar commented Sep 19, 2019 via email

@andyarvanitis
Copy link
Author

andyarvanitis commented Sep 20, 2019

Yes, I was thinking of something along those lines, but for the Golang backend, I'd probably need it to go through psgo itself, due to the way the go tools work. So something like a switch on psgo specifying the tag, and then it would take care of fetching the files. An example would be
psgo --ffi-tag 1.13. Do you think maybe pskt could also do the fetching in a similar way? It wouldn't be great, but it would at least make it easier on spago too.

@csicar
Copy link
Contributor

csicar commented Sep 22, 2019 via email

@andyarvanitis
Copy link
Author

For now, the entire purescript-native/go-ffi repo is pulled in (which is what I was talking about tagging). If the user wants to pull in other ffi files, they would have to add them in the go module loader/config files for their project. If they want to omit some of them (in the standard libraries) from their build, they would need to comment them out in the same files.

@csicar
Copy link
Contributor

csicar commented Sep 22, 2019

Yeah, it's the same for me: pskt-foreigns contains all foreign files and all are compiled. Maybe that's fine for now, but I think installing only the packages requested by the user is a better solution long-term (at least for pskt).

Btw: --run is now also supported by pskt

@csicar
Copy link
Contributor

csicar commented Sep 25, 2019

I'm working on the implementation here: #426

@f-f
Copy link
Member

f-f commented Oct 3, 2019

Since the initial request was fixed by #426, I'll close this one and I spawned #434 and #435 to track support for the other things we discussed here.

Thanks for all the great input 😊

@f-f f-f closed this as completed Oct 3, 2019
@andyarvanitis
Copy link
Author

Sounds great, thanks!

@f-f
Copy link
Member

f-f commented Oct 4, 2019

You're welcome 🙂

@i-am-the-slime
Copy link
Contributor

@f-f I think support for spago test is still missing, right? I don't think either of the tickets you spawned encapsulate this.

@nwolverson
Copy link
Collaborator

@i-am-the-slime right now spago test is ultimately following through the run workflow, which means it calls the backend with the test entry point (ie Test.Main). This works out just fine for purerl but some backends may benefit from an explicit test workflow

@f-f
Copy link
Member

f-f commented Jul 25, 2020

Yeah I'm totally in the dark wrt the need of other backends to have a custom test workflow, so please detail if you have more context - I think we'd be fine addind a separate path for test (rather than going through run), but we need to be careful about not hardcoding specific behaviour for this or that backend.

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

5 participants