Ecto and Phoenix very macro based, so we will never be able to make full use of them from Gleam, Erlang, or any other non-Elixir language.
Likely you would get the best experience from using Gleam modules as libraries in a way similar you might use Erlang modules.
Are you interested in the community exploring close interop with Ecto & Phoenix & Plug or would you much rather leave that and explore full Gleam solutions for web frameworks and database interactions?
We will never be able to have close interop with these Elixir projects as they are only designed with Elixir in mind and (quite rightly) make full use of Elixir features that cannot be used from other languages.
We will likely have a much better story for common Erlang libraries as they typically are easier to use from other BEAM languages.
Thanks for the information. Makes sense! Interesting that the macro-heavy nature of Elixir makes it harder to interact with. Understandable though. Unfortunately I’ve got no experience with Erlang at the moment but maybe one day
If you’re still looking for a more persistent home, I think our new community platform could actually be a really nice fit for you - I’ll send you some info when I get five mins
I agree with you on syntax, AstonJ. I started out with C and C++ and then did Python for a long time. I’ve also programmed professionally in Perl, COBOL, Pascal, JavaScript, Haskell, Java, C#, TypeScript, Scala, Go, and Swift, so I’ve seen a lot of different styles of syntax. For me, Ruby and Elixir are the most readable and fit into my brain the best.
I’m not criticizing Gleam’s choice of syntax. I’m just saying that, in my opinion, there is more to syntax than familiarity. I’m probably most familiar with bracket-heavy languages but my brain likes that syntax the very least.
Coming back to this a little later, I think you’ll be surprised that Gleam manages to be more concise than Elixir in many places. For example, here’s a pipeline in Elixir:
The else clause can’t be typed (as each clause can be for a different type), so we don’t have a direct mapping to that language construct. We’d likely do something like this instead:
with {:ok, user} <- get_user(id),
{:ok, membership} <- get_membership(user) do
print(membership)
else
{:error, :no_user} ->
{:error, "The user could not be found"}
{:error, :no_membership} ->
{:error, "The membership could not be found"}
end
try user = get_user(id)
|> result.map_error(fn(_) { "The user could not be found" })
try membership = get_membership(user)
|> result.map_error(fn(_) { "The membership could not be found" })
print(membership)
This is similar to how this would be handled in languages like Rust, OCaml, and Haskell.
Haskell:
do
user <- left (\_ -> "The user could not be found")
$ getUser id
membership <- left (\_ -> "The membership could not be found")
$ getMembership user
print membership
Rust (assuming you’re not using std::error::Error):
let user = get_user(id)
.map_error(|_| "The user could not be found")?;
let membership = get_membership(user)
.map_error(|_| "The membership could not be found")?;
print(membership)
OCaml:
let* user = get_user id
|> Result.map_error ~f:(fun _ -> "The user could not be found") in
let* membership = get_membership id
|> Result.map_error ~f:(fun _ -> "The membership could not be found") in
print membership
Whoa this is pretty cool! How does the control flow work… does it essentially halt the flow if one of the try lines doesn’t return an OK? sort of like an early return? Also I haven’t been following Gleam as closely lately but is try already in the language or just a planned feature later?
I just followed along with this blog post to start a Phoenix project with gleam as a mix compiler:
…however, when I make changes to the .gleam files, the application doesn’t pick them up unless I restart the server—even running mix compile won’t do it.
(I did already add a ~r"src/.*(gleam)$" pattern to the live_reload config in dev.exs, and that configures the page reloading successfully, but that doesn’t deal with the other issue.)