Thinking about creating a Gleam-like BEAM language with Python syntax

A subset of Python will be supported. Not interested at all in OOP, so classes will be used just as types for static analysis. Just like in gleam, no functions inside.

I like that gleam is composed of modules and functions, and don’t like modules and structs in Elixir for that matter. Gleam is minimalistic, and, with a few exceptions, its syntax can be viewed as a subset of Python’s. So I think I can support most of its features with Python syntax. Types included, of course, with the same semantics they have in gleam.

Let me give you some details. First of all, if, for, match, try and def will become expressions. Here is how we can make a list, for example

li = for i in range(10): i

What kind of functional language may be without lambdas?

f = def(x: int):
  x + 1

The keyword-based expressions will be pretty limited as they could only be the right hand of an assignment or pipeline operator. An example for the latter:

1 |> def(x):
  x + 1

They will be limited in a sense that things like wrapper_func.(fn(x) -> x + 1 end) won’t be possible, instead you will have to first assign the inner function to a variable:

f = def(x): x + 1

A common use for the pipeline operator will be at the end of keyword-based expressions. For example, with match:

match x:
  case False: True
  case True: False
|> expression
|> expression2

As you see, the syntax resembles Elixir pretty much. But with types. Without macros and structs.

Now let’s talk implementation. gleam does source-to-source transpilation to Erlang, and I think I’m going to reuse its code (it’s in Rust). Quite conveniently one of the best libs for Python code-intel is also written in Rust (GitHub - charliermarsh/ruff: An extremely fast Python linter, written in Rust.).

Another nice thing: I will be able to get almost 100% working version using just vanilla Python syntax. No need to change the parsing rules even! Because the syntax of keyword-based expressions, when they are the last statement in a function, does not need to be changed. It is the same as in Python:

def test_match_expr():
  # can use match
  # as an expression
  # without introducing new syntax
  match x:
    case RightType(x): x

So, I will be able first to get the working implementation, and then to introduce the new syntax. Isn’t that nice?

What do you think, dear erlangers? Do you feel the sparkling joy in this? Or the utter disgust? Please say it out loud!

1 Like

I hope you won’t be copying Python’s insanely low limit
for procedure calling depth. which broke a nice little
dynamic programming algorithm I once tried to write in

The main reason I’d have for Python would be to run
numpy/scipy/pandas, or, alternatively, micro-Python
on RPi pico and ESP32 boards. If your dialect
remains compatible with the mypy type checker, more
power to you.

It will be gleam with Python syntax. No pandas or scipy :slight_smile:

this proposal has been rated 10 out of 10