What Erlang/BEAM related stuff are you doing?

Spawn a little process and tell us what Erlang/BEAM related stuff you’ve been up to recently :003:

2 Likes

My latest itch that I’m scratching is to improve the documentation support in Erlang LS.

For anyone working with Erlang I think this will be a great improvement!

13 Likes

From time to time I’m updating docker-erlang-otp.

4 Likes

This is will be excellent improvement! Thanks!

2 Likes

I’ve been recently working on improving GitHub - josefs/Gradualizer: A Gradual type system for Erlang.

My personal top 3 are:

  • Some map typing fixes by erszcz · Pull Request #340 · josefs/Gradualizer · GitHub - this allows for typechecking maps. Erlang maps are actually tricky to typecheck, since they’re not the same thing as standard records described in typesystem literature. For now, the typechecking is limited to “maps as records”, but it’s pretty convenient already and it should also be sufficient to typecheck Elixir structs.

  • Non-trivial sum type exhaustiveness checking by erszcz · Pull Request #330 · josefs/Gradualizer · GitHub - this extends exhaustiveness checking (checking if a case statement or function definition cover all variants of a sum type) from plain alternatives of atoms - a | b | c - to types with structure - {not_a_string, integer()} | #my_record{} | {yet_another_variant, [atom()]} | #{map_key := map_val()}. This is probably the biggest feature I miss from statically typed functional programming languages in Erlang, but with this PR it started to work reasonably well (there’re still some glitches here and there).

  • Still a work in progress - Property based tests to find bugs and infinite loops by erszcz · Pull Request #363 · josefs/Gradualizer · GitHub - but it should help with finding bugs before people report them :slight_smile: In general, typechecking precision improvements (like the exhaustiveness PR above) started uncovering some infinite loops here and there and it’s better to get rid of them sooner rather than later. BTW, the Erlang AST form generator comes from Proper and the whole idea is borrowed from the Erlang compiler.

None of the above would be possible without zuiderkwast (Viktor Söderqvist) · GitHub and his tireless reviews, so kudos to him!

8 Likes

over the summer I wrote a tree-walking interpreter that implements a subset of Godot’s built-in scripting language, GDScript. It’s a whitespace-significant imperative language, so implementing that in Erlang was challenging but also really fun!

I have never implemented a programming language before, so I spent a lot of time staring at the Luerl
source code, the documentation for leex and yecc, and the book Crafting Interpreters.

overall I’m pretty happy with it, but the interface is rather bad. this partially stems from cheating a bit and using the process dictionary to hold state for the interpreter rather than threading it through all of the functions. :face_with_hand_over_mouth:

3 Likes

I have a repository where GitHub Actions runs Dialyzer on Elixir source code on a daily basis. So I contribute small fixes to Elixir code or specs from time to time.

I am also trying out different things for static typing on the BEAM: playing with Gleam, contributing to Caramel in the past or to Sesterl more recently, and experimenting with implementing typechecking algorithms (e.g. Algebraic Subtyping or bidirectional). Right now I am learning about structural typing in Typescript and plan to try out Gradualizer that @erszcz mentioned and is doing great work on.

5 Likes

I have been working on implementing the compiler part of EEP 49: Value-Based Error Handling Mechanisms by @MononcQc. The EEP was first submitted in 2018, and later revised by Fred in late 2020. The latest revision addresses notes from the OTP Technical Board.

The idea of the EEP is to eliminate deeply nested caseend constructs such as the following code from Mnesia:

commit_write(OpaqueData) ->
    B = OpaqueData,
    case disk_log:sync(B#backup.file_desc) of
        ok ->
            case disk_log:close(B#backup.file_desc) of
                ok ->
                    case file:rename(B#backup.tmp_file, B#backup.file) of
                       ok ->
                            {ok, B#backup.file};
                       {error, Reason} ->
                            {error, Reason}
                    end;
                {error, Reason} ->
                    {error, Reason}
            end;
        {error, Reason} ->
            {error, Reason}
    end.

Using the new maybeend construct described in the EEP, the code can be simplified to:

commit_write(OpaqueData) ->
    maybe
        ok <~ disk_log:sync(OpaqueData#backup.file_desc),
        ok <~ disk_log:close(OpaqueData#backup.file_desc),
        ok <~ file:rename(OpaqueData#backup.tmp_file, OpaqueData#backup.file),
        {ok, OpaqueData#backup.file}
    end.

@MononcQc and @peerst implemented a first proof of concept during the Spawnfest in September.

That implementation and a previous revision of the EEP reused the begin keyword instead of introducing the new maybe keyword to avoid backward incompatibilities with code that used maybe as a function name or atom, for example the compiler itself.

The OTP Technical Board decided that the maybe keyword should be used. By default, maybe would remain an atom, and the maybeend would not be available. To use the maybe construct, a compiler option to enable it would be needed. The option can be applied to individual modules, so one part of a code base can use maybe as an atom, while some modules in the code base can use the maybeend construct. There is currently ongoing work on an EEP and an implementation of a mechanism that will allow adding new features that can be enabled with an option but by default are disabled.

I have implemented the compiler part of EEP 49 as a draft EEP.

13 Likes

Correct me if I’m wrong, but maybe is a regular monad. Monad is a function, that controls calling other functions and chaining their outputs.

We have a code in our flussonic:

validate([F|Funs]) ->
  try F() of
    ok -> validates(Funs);
    {error, E} -> {error, E}
  catch
    _:E -> {error, E}
  end.

....
  validate([
     fun check_name_uniqueness/0,
     fun check_links/0,
     ..
  ])

Here I can control how does this monad behaves, but this code is not suitable for hot path. When it is called about 100 000 per second, it should be rewritten to nested cases.

Questions are:

  • is this implementation designed to be first-class in terms of performance?
  • is it possible to change behaviour of maybe ? For example, it maybe very good to measure time of each step and add it to {ok, #{timings => #{}}} tuple.
2 Likes

Yes, it is designed to generate efficient code. A maybe compiles down to nested cases. There are no exceptions involved.

No.

2 Likes

Hi :wave:, I’ve started to explore the world of Erlang, OTP and the BEAM recently and I have two projects working on related to OTP and also the ecosystem itself.

  • eigr.io - A Serverless Runtime on the BEAM
  • Implementing SHA3 SHAKE128/SHAKE256 support in OTP

I’m exited about both and looking forward to dive into the system as well as to expand its use in areas not well known yet.

3 Likes

Hi, I’m Sergey.
Working full-time with Erlang at Klarna, hacking “kred” system which is 15 years old, ~1.5M LOC system and seen multiple genrations of erlangers, but still actively evolving.

Talkin about the opensource:

Currently trying to push for map comprehensions syntax in Erlang together with Pablo Costas Sanchez and Carlos Rendon.

8 Likes

I’ll be using Erlang to drink my tea:


(Sorry for this post :stuck_out_tongue: )

8 Likes

Continue with:

http://nova framework.org
https://supernova.chat

Hope to start doing more on the GitHub - erldb/erldb: ORM implementation in Erlang

7 Likes

Our short term goal is to finish the new documentation site for Zotonic and having GitHub - zotonic/zotonic: Zotonic - The Erlang Web Framework & CMS packaged as rebar3 dependencies.

So that people will have an easy start using Zotonic as their content/information management system.

8 Likes

For the past month or so I’ve been working on a self hosted password manager. It is mostly feature complete. I’m currently finishing it up with some polish.

The development process has been a good opportunity to sharpen my web security skills and building accessible web pages.

It wasn’t built with a framework. Simply a plain cowboy app. As I’ve been building it I’ve also been breaking off components and publishing small libraries like:

Maybe others will find these useful for their own projects.

6 Likes

I am trying to build a USSD application that can provide a USSD menu for services.
I am a newbie, so building this is taking quite a while, but I’ve been learning so much, and quite frankly Erlang language makes it fun.
Hopefully I will have learnt enough to apply to my studies as well.

3 Likes

I had never heard of USSD before. This looks really cool and well suited for Erlang.

1 Like

That’s a really neat idea! Gotta see more about when I get to my machine

2 Likes

How are you handling the protocol stack? We have Erlang implementations of MAP, M3UA and much more on GitHub. Feel free to ask me for any help.

1 Like