leostera / caramel

:candy: a functional language for building type-safe, scalable, and maintainable applications
https://caramel.run
Apache License 2.0
1.06k stars 25 forks source link

mix plugin #30

Closed leostera closed 3 years ago

leostera commented 4 years ago

Right now to be able to use caramelc in an Erlang or Elixir project, we sort of have to manually invoke it in the right place and then also compile the caramel stdlib erlang sources and make sure its available. An entire dance.

It'd be useful to have a mix plugin to see what the interop from the Elixir side feels like so that we can just create a new mix project, and if you have caramel available in your path then it will do the build.

For some inspiration have a look at https://github.com/seanhinde/rebar3_caramel and #22

The end result would be that you can drop in a couple of .ml files in your sources and have it available in the repl.

jrusso1020 commented 4 years ago

@ostera I gave this a shot, you can see my repo here https://github.com/jrusso1020/mix_caramel let me know what you think. The simple basic_project example seems to work and I used the same multiple dependency example from the rebar plugin which works. But I'm not sure if there's more that needs to be done.

The rebar plugin example definitely is doing a lot more, I followed the gleam mix plugin which is relatively straightforward and simple https://github.com/gleam-lang/mix_gleam for reference


Some notes, I think the gleam compiler does this very nicely. I'm curious if the caramel compiler should do something similar? For gleam you just say compile from the current directory (.) and it takes care of compiling and moving the files to the necessary generated directory for you. For the caramel compiler, I have to cd into the src/ directory, create a gen/src/ directory, move all the .erl files into the gen/src directory and then delete all the .cmi and .cmo files

leostera commented 3 years ago

Hej @jrusso1020! Thanks for this 🙌🏼 -- it looks really good! 😄, feel free to submit some of your changes to the one we have hosted in here btw: https://github.com/AbstractMachinesLab/mix_caramel so we eventually converge into a single one 😃

The one thing I'd add is not to remove the .cmi files since those are a compile artifact with type-information that is needed to type-check dependencies of the module. This way, if module a.ml generates a.cmi, then module b.ml depending on a.ml does not need to recompile a.ml, and it will be verified against that .cmi file instead.

It is built to support scaling compilation to thousands of modules.

Re: how Gleam does it -- Gleam is partially implementing a build system, which I won't do in Caramel. Instead, I'm building Crane (and here's why).

The reason for this is that I want to make sure that a caramelc can be used in other build systems too, like dune or bazel, and this is not something that can be achieved by hiding the compilation process. So caramelc will continue to only ask for input files and just compile them.

Re: making outputs relocatable, this would be nice but it is definitely not a priority as it can be worked around by the build systems and at this time would mean heavier refactoring on the ocaml compiler libraries.

jrusso1020 commented 3 years ago

Oh sorry about that, didn't realize there was already a repo 😬 . I renamed my repo, and have opened a PR for my changes. https://github.com/AbstractMachinesLab/mix_caramel/pull/1 which we can discuss there further, I'm open to keeping more of what was already there or adapting slightly.

One thing we may need to figure out is that I pushed my project up to hex already, but I think we can just overwrite it. I may need to give you all access to the project on hex though

leostera commented 3 years ago

Sweet! We'll have a look shortly. Thanks! 🙌🏼

Will also close since we already have the repo there.