Releases: leostera/caramel
v0.1.1: Improvements to Docs, Better operator support, Cleaning up Stdlib
📙 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: Shaping up!
🌎 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 stringsErlang.floor/1
to round down floats to integersErlang.list_to_float/1
to parse strings to floatsErlang.float_to_list/1
to turn floats into stringsErlang.list_to_integer/1
to parse strings to integersErlang.integer_to_list/1
to turn integers into stringsLists.foldl/foldr
signature has been fixed
v0.0.14: Website, split Erlang library, proper exit codes, and better runtime support
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 therecv
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 thegen_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: Internal restructures preparing for OPAM publication
Not much, just a few internal refactors that aren't very interesting.
Next release tag will include a better changelog.
v0.0.12: First Milestone Completed!
Release Notes
This is the first actual release of Caramel that I'm making available 🎉
It includes 2 things:
caramelc
, the Caramel compilererlang
, 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:
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: Prelim. support for guards and printing OCaml ASTs
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 nameErlang
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: Record updates and lambda calls
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: Safer compilation and better error messages
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 moreX = 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 writex' = x + 1
and it will
translate toX_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
Minor Stdlib changes
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 🙌🏼
Almost ready for standalone usage :rocket:
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 toProcess.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