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,
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 wrapper_func(f)
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!