leostera / caramel

:candy: a functional language for building type-safe, scalable, and maintainable applications

Home Page:https://caramel.run

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Function declarations with explicit type annotations compile to the wrong Erlang code

tmbb opened this issue · comments

commented

Describe the bug

Explicit type annotations seem to compile to the wrong Erlang code.

To Reproduce

(* example.ml *)
let f (x : int) : int = x + 1

compiles to:

% Source code generated with Caramel.
-module(example).

-export([f/1]).

-spec f(integer()) -> integer().
f(_) -> erlang:'+'(fun x/0, 1).

Expected behavior

I'd expect something like this:

% Source code generated with Caramel.
-module(example).

-export([f/1]).

-spec f(integer()) -> integer().
f(X) -> erlang:'+'(X, 1).

Hello there! Thanks for opening the issue 🙏🏽

Just to set the right expectations This version of the compiler is no longer maintained. I have been working on a new one but I can't promise when it'll be public.

If you're still looking for a type-safe language on the BEAM that you can start using today, try out Gleam ✨

commented

I have been working on a new one but I can't promise when it'll be public.

Ok. What does the new compiler bring to the table that couldn't be done with the current one?

If you're still looking for a type-safe language on the BEAM that you can start using today, try out Gleam ✨

I've looked into Gleam and I don't see it bringing anything that OCaml doesn't do better. Maybe a different approach based on dependent typing or something else not related to the HM typesystem would be valuable, but I don't think Gleam is going in that direction.

The new compiler is a full rewrite that uses the OCaml Lambda and translates it directly into Core Erlang. It's also architected so much better, so onboarding into it, fixing things and growing it, will be much more productive.

The last thing I've been playing around is a syntax that has less quirks and is more modern, mainly inspired by ReScript and Rust. This would allow for two things. First, it allows the compiler to restrain what type-level features you can use rather than just crashing with a "oops, unsupported feature!" or whatnot. Second, building an interesting macro system that doesn't rely on ppx or other off-chain code transforms, that we could use to get rid of a lot of boilerplate without losing any type-safety. This is still highly experimental so nothing to show just yet, but the macro system is heavily inspired in Racket, Rust, and Elixir.

Anyway, I've said too much! 😱 I don't expect any of this to be usable this year.

commented

The new compiler is a full rewrite that uses the OCaml Lambda and translates it directly into Core Erlang. It's also architected so much better, so onboarding into it, fixing things and growing it, will be much more productive.

I once tried to hack OCaml's Lambda intermediate representation, but I didn't have much success. I hope you succeed there! I agree with you that's probably the best representation if you want to compile to Erlang (I believe that they added more metadada to the Lambda representation which probably makes it easier).

The last thing I've been playing around is a syntax that has less quirks and is more modern, mainly inspired by ReScript and Rust.

I'm not a huge fan of OCaml's syntax (although it's less noisier and better than most - better than Elixir for example, for sure), but I think that using a different syntax brings very few benefits and a lot of costs. Namely, it makes it impossible to reuse normal OCaml tools (like editor plugins). This is my opinion, though, and I understand you might have different criteria which leads to a different solution.

This would allow for two things. First, it allows the compiler to restrain what type-level features you can use rather than just crashing with a "oops, unsupported feature!" or whatnot.

This is an example of a valid reason to change the syntax, although personally I'd prefer to keep support for as many OCaml features as possible. The OCaml typesystem is very cool and very complete, and can probably support any programing paradigm that makes sense on the BEAM.

Anyway, I've said too much! 😱 I don't expect any of this to be usable this year.

Is there any way you could make it public earlier, so other people could play with it? I totally respect your decision to keep it private while you want to, of course. I'm just curious.

@tmbb re: as many features as possible, I hear you. I think one example would be OCaml 5 effects -- this may be one of the features that are just too hard to map onto the BEAM. A lot of ground to explore here, and barely any resources to do it! 😄

re: trying it out, the branch is up under the name sugarcane (yes! another candy from my land), but you need a fork of the OCaml compiler to run it -- specifically, you need this PR: ocaml/ocaml#11064 -- so its a little tricky to get it up and running atm.

commented

specifically, you need this PR: ocaml/ocaml#11064 -- so its a little tricky to get it up and running atm.

I understand why you'd need a full year, then. The metadata you add is important to deal with variants, but it's a little invasive for the compiler.

commented

you need a fork of the OCaml compiler to run it

Do you have a version that does NOT require a fork of the OCaml compiler? Even if error reporting is horrible, I guess I'd prefer something that doesn't require an OCaml fork. The loss of metadata from the TypedTree to the Lambda representation in the OCaml is really quite unfortunate.

The current main branch doesn't depend on my OCaml fork, but it also has several bugs that you'd have to work around. If you are interested in trying this out for real, I'd love to learn more about your use case to see how much work sugarcane needs to fit your needs.

Worst case scenario, we can just use the OCaml fork while we wait for changes to be upstreamed. After all, as a language user you'd be getting the binaries straight out of Github, and you wouldn't need a custom OCaml installation.

Would you mind sending me an email to leandro at abstractmachines dot dev with more info?