Caramel Versions Save

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

v0.1.1

3 years ago

📙 Manual

  • The manual is now automatically released in CI through Github Actions.
  • We've got an open invite to Discord available on every page.
  • Erlang as a runtime dependency has been clarified.
  • Fixed several SEO issues.

🧰 Compiler

  • Better support for bit-shift, unary float, and keyword operators
  • Now support for floating point numbers without trailing digits (1. == 1.0)

📚 Standard Library

  • Introduced the Math module
  • Clean up several unimplemented bindings that were leftovers from the OCaml standard library

v0.1.0

3 years ago

Read the Caramel Changelog

🌎 From a Backend to Language

Caramel is starting to take shape, and we'll now refer to it as a language rather than an OCaml backend to make it a little easier to talk about it.

After all, it isn't really 100% OCaml but a strict subset of it. It doesn't ship the same standard library or tools.

We also have a new website at: caramel.run

🗫 Community

We've updated our Code of Conduct to the Contributor Covenant v2.0.

We've opened the Github Discussions -- drop by and say hi or grab a Discord invite link! 👋

📙 Manual

I've started work on the Caramel Manual where we have an installation guide, an introduction, a small syntax cheatsheet, some examples, and a small guide on writing Caramel code that talks to existing Erlang code.

This is a big work in progress, so if you'd like to help, please reach out!

In the future I'm planning to write guides for how to use Caramel with existing build systems like Rebar3 or Mix, and include a reference guide to the standard library.

💅 Caramel Formatter

Caramel now ships a formatter that you can run to make sure your code is always stylish and you have no more bikesheds. It supports ZERO configuration, so what you see is what you get.

This is currently just a wrapper around ocamlformat, and all the kudos go to the amazing team putting that together.

You can use it by calling caramel fmt *.ml and it should work on both .ml and .mli sources.

It only does in-place formatting.

🧰 Compiler

The compiler has dropped support for several targets, including Core Erlang to Native, and the default OCaml compilation modes.

It will from now on focus only on taking Caramel sources into runnable Erlang and Core Erlang code. Over time we will move from Erlang to only Core Erlang support, to make it easier to reuse Caramel code from Erlang, Elixir, Gleam, and Hamler.

The additions to the compiler are:

  • Replaced unbound vars in specs with wildcards (thanks @ilya-klyuchnikov, PR)
  • Keyword atoms are automatically quoted now
  • Removed unnecessary compilation steps (thanks @Drup)
  • Removed unused object file generation (.cmo)
  • Better support for operators like &&, ||, and >=

📚 Standard Library

The standard library has been simplified for contributing to it, and you can now find it at the top of the repository.

Changes:

  • String concatenation now possible with the ^ operator: "yay" ^ "!!!"
  • Binary.split/3 to split binary strings
  • Erlang.floor/1 to round down floats to integers
  • Erlang.list_to_float/1 to parse strings to floats
  • Erlang.float_to_list/1 to turn floats into strings
  • Erlang.list_to_integer/1 to parse strings to integers
  • Erlang.integer_to_list/1 to turn integers into strings
  • Lists.foldl/foldr signature has been fixed

v0.0.14

3 years ago

Changelog

  • erlang: the Erlang library included, with a lexer/parser/AST/printer for Standard Erlang, is now completely split from the Caramel code and will be published to opam shortly.

  • caramelc: will return exit code 0 if everything went well. Otherwise expect a non-zero status!

  • stdlib: remove dependency on the Erlang AST printer for parts of the runtime (like the recv function), and instead include the relevant .erl sources as part of the packed stdlib.

  • docs: better contribution notes, documenting the release flow and saying a word about the rationale behind it. I've also put together a small website for Caramel here: https://caramel.abstractmachines.dev

  • examples: the echo tcp server has been refactored to make it harder to accidentally override the gen_tcp module that is shipped with Erlang. We'll have to figure out a nice way to prevent these things from happening, which may just mean using all the modules on the Stdlib to avoid redefinition.

  • ci: several changes to CI to ensure we can release the erlang library to opam.

v0.0.13

3 years ago

Not much, just a few internal refactors that aren't very interesting.

Next release tag will include a better changelog.

v0.0.12

3 years ago

Release Notes

This is the first actual release of Caramel that I'm making available 🎉

It includes 2 things:

  • caramelc, the Caramel compiler
  • erlang, an OCaml library for handling Erlang code, including an AST, lexer, parser, and printer

The Caramel compiler

Caramel can compile a large portion of the OCaml language, in particular most of the immutable functional OCaml, and into idiomatic Erlang code. Whenever possible it will look quite decent, and some times it will have pretty terrible formatting.

It runs as a single stand-alone binary with no dependencies (other than glibc or musl), and it should be blazing fast. Here's some benchmark results from the examples/ocaml_to_erlang.t folder:

Screenshot from 2020-10-30 23-08-04

The compiler also includes an additional target that may be of interest to those who want to dig into the compilation process: caramelc parse. This command will read Erlang and OCaml sources, and dump different ASTs of them. It was very useful to have around for testing purposes as well.

erlang library for OCaml

The Erlang library currently includes support for the vast majority of the Standard Erlang language, according to the grammar shipped with Erlang/OTP as of version 24.

It includes a series of modules to make it easy to construct Erlang programs from OCaml, as well as deconstruct them and operate on them.

A pretty printer is also included that right now is used within the Caramel compiler to generate the Erlang sources. It unfortunately still has some tiny remnants of Caramel logic in it, but they should be cleaned up in the near future and should not get in the way of more general usage of this library.

Changelog

  • compiler: match expressions with cascading cases are not that straighforward to translate to Erlang and my gut tells me that doing the juggling here will get in the way of type-checking Erlang in the upcoming milestone, so this is forbidden as it is right now.

v0.0.11

3 years ago

Changelog

  • compiler: preliminary support for guards is added in this release. They are "safe" as long as you don't redefine any of the expected functions. There is no good way at the moment to prevent this from happening, but we could achieve it by essentially forbidding the use of the module name Erlang and requiring all guards to be fully qualified names.

    This still leaves us with the issue of compounded guard expressions.

    At the end of the day, we want a function is_valid_guard : expression -> bool that can traverse an arbitrary expression and tell us if it is or is not a valid guard based on the specification found at the Erlang docs.

  • caramelc: the parse subcommand now can take a --lang and --tree parameters to print out the parse and typed trees for OCaml, as well as the parse tree of Erlang, and the parse tree of the result of compiling OCaml to Erlang.

    This is particularly useful for testing and understanding the AST translation, and will likely be used later on to see if the compile -> typecheck -> compile cycle yields the same inputs, and thus is an isomorphism.

v0.0.10

3 years ago

Changelog

  • Add support for record updates (see #23):
{ my_record with field = value }
My_record#{ field := value }
  • Add tests showing that lambda function calls are now working as expected and will be called with the right number of parameters:
let f () =
  let g () = 1 in
  g ()
f() ->
  G = fun () -> 1 end,
  G().

v0.0.9

3 years ago

Changelog

  • compiler(#12): the compiler will now let you know when you're redefining a function on the OCaml side, which is not allowed on the Erlang side and stop compilation.

  • compiler(#16): shadowing bindings with let are (for) now unsupported on the OCaml side, which makes translation runtime safe. We won't see any more X = X + 1 on the Erlang side.

  • compiler(#15): to help with #16, priming of variables is now supported and translated to valid Erlang. We can write x' = x + 1 and it will translate to X_prime = X + 1.

  • compiler(#13): recursive let bindings within a function definition are now not supported since they don't have a direct Erlang equivalent and require runtime overhead.

  • error messages have been created for all of the above

v0.0.8

3 years ago

Changelog

  • stdlib: fix name of Io module so Merlin can pick it up properly.

Shoutouts

Thanks a lot to @seanhinde for playing opening issue #19 and working through the problems outlined there with me 🙌🏼

v0.0.7

3 years ago

Better releases

  • compiler: automatic function reference arities! As see in #10

  • compiler: We're ignoring all fresh type variables when translating to Dialyzer specs for now. More work will be done in #20

  • caramelc: caramelc compile now supports multiple --target flags, so you can compile both archives and Erlang sources at once.

  • caramelc: standard library will now by default be in the respective installation directory (respecting dune install conventions)

  • stdlib: Process.spawn/1 has been renamed to Process.make/1 until we have support for module attributes (see #21)

  • stdlib: Dropped top-level namespacing until we figure out how it can work best with .merlin

  • ci: several changes to release flow, including a nicer folder structure in the tarball

  • ci: entire codebase is instrumentabled by bisect_ppx now to start gathering coverage reports

  • erlang: removed an unused helper