Giter Club home page Giter Club logo

Comments (14)

michaeljones avatar michaeljones commented on May 19, 2024 2

And I've published a blog post on dev.to: https://dev.to/michaeljones/mixing-gleam-elixir-3fe3

As the README in the demo project is most of a blog post anyway. Thanks for the suggestions. Feedback welcome on both. I can make you a collaborator on the repo if you want to tweak or tune anything.

from gleam.

michaeljones avatar michaeljones commented on May 19, 2024 1

Here is an example repository: https://github.com/michaeljones/gleam-phoenix-mix

There is a weird dance around pre-compiling the mix compiler task before calling mix compile. I think that would go away if there was a published mix-gleam dependency that people could use. Though I'm sure there is plenty of room to improve the actual mix compile task I've written - given that it is one line.

I'll happily put together a blog post too at some point soon.

from gleam.

michaeljones avatar michaeljones commented on May 19, 2024 1

Cool! Makes me happy. Thanks for letting me know. Kind of you.

from gleam.

CrowdHailer avatar CrowdHailer commented on May 19, 2024 1

We could have a section on the gleam docs about running in mix now.

  • This PR means gleam code in dependencies is found correctly #596
  • All that is require is to:
      1. install Gleam binary
      1. Add these lines to the mix file.
        erlc_paths: ["src", "gen"],
        compilers: [:gleam | Mix.compilers()],
        aliases: ["compile.gleam": "cmd gleam build"],
      

Open an issue for mix docs and just point me to where they need to go if this is of interest

from gleam.

michaeljones avatar michaeljones commented on May 19, 2024

Hi, did you explore this in the end? For some reason I find myself wanting to use gleam explicitly through mix rather than an umbrella project and rebar3. I suspect it just because I'm quite new to the Elixir ecosystem and a bit scared :)

It looks like it is possible to write Mix.Compiler modules. Have you explored that for gleam at all? I can understand it not being a priority.

from gleam.

lpil avatar lpil commented on May 19, 2024

No work has been done here I'm afraid. This could be a good place for someone to contribute :)

from gleam.

michaeljones avatar michaeljones commented on May 19, 2024

Ok, cool. I'll keep it in mind and let you know if I start or progress on it. Thanks for the quick response.

from gleam.

michaeljones avatar michaeljones commented on May 19, 2024

Ok, I've been poking around a little bit. I don't have a full solution but some of the parts to it.

If you start with a fresh phoenix project, you can add a mix compiler task by creating a file called lib/mix/tasks/compile/gleam.ex. If we give it the following content:

defmodule Mix.Tasks.Compile.Gleam do
  use Mix.Task.Compiler

  def run(_args) do
    System.cmd("gleam", ["build"])
    :ok
  end
end

Then it does the basic job. We should then run mix compile to compile it and then change the mix.exs file like so:

       elixirc_paths: elixirc_paths(Mix.env()),
-      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
+      compilers: [:phoenix, :gettext, :gleam] ++ Mix.compilers(),
       start_permanent: Mix.env() == :prod,
       aliases: aliases(),

Then we can add a src folder with a hello-world gleam file in it in src/hello_world.gleam:

pub fn hello_world() {
  "Hello, from gleam!"
}

Then we have to tell mix to make the erlang compiler pass look in the gen folder, back to our mix.exs file with:

       elixir: "~> 1.5",
       elixirc_paths: elixirc_paths(Mix.env()),
+      erlc_paths: ["gen"],
       compilers: [:phoenix, :gettext, :gleam] ++ Mix.compilers(),
       start_permanent: Mix.env() == :prod,
       aliases: aliases(),

Then we can change our lib/my_app_web/controllers/page_controller.ex like so:

 defmodule MyAppWeb.PageController do
   use MyAppWeb, :controller

   def index(conn, _params) do
-    render(conn, "index.html")
+    render(conn, "index.html", title: :hello_world.hello_world())
   end
 end

And our lib/my_app_web/templates/page/index.html.eex with:

 <section class="phx-hero">
-   <h1><%= something about gettext, I forget %></h1>
+   <h1><%= @title %></h1>
   <p>A productive web framework that<br/>does not compromise speed or maintainability.</p>
 </section>

And run mix compile and mix phx.server and load localhost:4000 to see Hello, from gleam! in the centre of the page.

Notes:

  • One issue is that on the first pass the elixir file with the mix compiler task in it needs to be compiled by the elixir compiler which means we might want to put :gleam after Mix.compilers() in the mix.exs file but then more generally we want the output of the gleam compiler to be compiled by the erlang compiler in the Mix.compilers so we want the :gleam before Mix.compilers(). I'm assuming that the compilers are run from left to right through the list. This concern would go away if the :gleam mix compiler integration was coming in through a dependency and compiled with mix deps.compile before :gleam was added to mix.exs compilers line. Bit awkward but not a deal breaker, I guess.
  • I'm also not mad keen on having lib, src and gen. Though by default mix looks for erlang files in src rather than lib so it expects that to exist and I can see the reason behind generating modules into an entirely separate folder (gen in this case) rather than next to their source modules.

Anyway, I'm quite new to all of this so maybe none of this is that interesting, or maybe it is useful. It has been interesting to dig in a bit and see what is going on.

I've spent quite a while with Elm and now that I'm programming Elixir I dearly miss the type system. I also like Rust (though I'm new to it) so gleam is ticking lots of boxes. Personally I would write something with pretty much just the Elm syntax but I don't know how to write a programming language/compiler and I respect that we have different preferences. I'm impressed by the work you've put into gleam and look forward to learning more from the code base.

from gleam.

lpil avatar lpil commented on May 19, 2024

Wow this is really cool! Perhaps you could make an example GitHub repo to show people? I imagine there would be some interest in a blog post about it too if you're interested.

I'm also not mad keen on having lib, src and gen. Though by default mix looks for erlang files in src rather than lib so it expects that to exist and I can see the reason behind generating modules into an entirely separate folder (gen in this case) rather than next to their source modules.

I agree, gen is somewhat irksome. I think the ideal way to handle generated files would be to keep them in _build somewhere but I'm not sure what the appropriate place would be. If you find out let me know :)

I've spent quite a while with Elm and now that I'm programming Elixir I dearly miss the type system. I also like Rust (though I'm new to it) so gleam is ticking lots of boxes.

Thank you for your kind words! I like those languages a lot :)

Personally I would write something with pretty much just the Elm syntax but I don't know how to write a programming language/compiler and I respect that we have different preferences

I too would prefer the Elm syntax, but the more C style syntax that Gleam has these days is proving much more popular and approachable.

from gleam.

lpil avatar lpil commented on May 19, 2024

Cool stuff! Thank you!

from gleam.

michaeljones avatar michaeljones commented on May 19, 2024

I don't know the details but the mix compiler task supports return error information and diagnostics in a manner that the rest of the tool chain can work with. Possibly allowing the elixir language server to do something or at least a step in that direction.

The diagnostics are documented to some degree here: https://hexdocs.pm/mix/Mix.Task.Compiler.Diagnostic.html#content

Is that something that you'd consider exploring for gleam? Could I make a new issue for it?

I imagine that it would involve adding a --format flag to the compiler with certain options. Possibly a generic json format that the mix compiler task could then transform into the diagnostic format. Rather than gleam using that format itself. I'm assuming that isn't possible at the moment as gleam build doesn't seem to have such an option.

That said, I've really not used gleam much at all so maybe I should learn more about the set up and current options before pushing for random stuff that I've stumbled across in the docs.

from gleam.

lpil avatar lpil commented on May 19, 2024

There are no plans to support any Elixir format at present, though we do wish to support Language Server Protocol. I think we'd want to have better tooling before we start thinking about things like diagnostic integration

from gleam.

lpil avatar lpil commented on May 19, 2024

@michaeljones https://app.rdstation.email/mail/9b0b82b7-f47a-4cf3-a916-0b64a8817fae

You've been featured in the Elixir Radar newsletter :)

from gleam.

lpil avatar lpil commented on May 19, 2024

Once you've used this for a while and we're confident exactly what approach to recommend we could add a "adding gleam to a Elixir mix project" to this section of the book -> https://gleam.run/writing-gleam/index.html

from gleam.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.