We had a discussion in the OTP team about what the matching operator should be. In the previous OTP Technical Board meeting, we decided that we should not overload the <- operator used in list comprehensions. Eliminating operators that could be useful for other purposes in the future, we ended up with <~ earlier this week. Unfortunately, <- and <~ look quite similar to each other (especially in some fonts and text sizes), so we wasn’t completely happy with that choice.
After some more discussion and thinking, we came up with ?=. Now that may seem to cause ambiguity since macro invocations start with ?, but it is not. Even if there exists a macro named =, it must be invoked like ?'='.
Thus, the previous example will now look like:
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),
I hadn’t seen that EEP before, it looks great! I usually end up implementing my own short-circuting higher-level sequencing function in every other project I do, and this will definitely be a cleaner way.
?= exists as an operator in groovy, as the “Elvis assignment operator”, and has a similar(ish) purpose, general handling of “unhappy path” values (or setting of default values). It assigns the value on the right hand side to the variable on the left hand side, if and only if the left hand side is falsy (null, empty string, etc). errorMessage ?= "Unknown error"
Maybe not the most popular language, but still the familiarity and similarity in function is an added bonus to those familiar with it!
Parameterized modules was an experimental feature that we had in the language for several releases. The feature mostly worked but was not fully supported by the rest of the OTP (I don’t remember exactly, but it could have been release handling). Eventually, we decided that we would either have to fully support parameterized modules or take them out. We took them out.
Tuple calls (needed to implement parameterized modules) remained for a while until we removed them too.
I can think of one supported feature of the language that we have actually managed to remove. It is another kind of tuple call that was frequently used before funs were invented:
Maybe it is too late for this comment, but the reason why reusing <- makes sense to me is because both maybe and comprehensions are monadic operations where <- have the same semantic meaning. I understand that Erlang does not have monads, and most users won’t be aware of such background, but I wanted to mention there is a framework to describe it.
I’m in fully agreement with Jose on this one and also hopefully not too late to weigh in… I’d favor <- unless it significantly complicates the underlying implementation. I don’t think anyone will be confused.
I was less a fan of parameterized modules, but tuple calls allows for a lot of usually higher-typed functionality (like think OCaml’s first class modules), which is very difficult to emulate otherwise (have to go back down to carrying a load of data everywhere you go).
We have now had the OTP Technical Board meeting. While we spent some time discussing monads , we still decided to go with the ?= operator, since there is not really any cost to adding a new operator and overloading an existing operator will not make it any easier to document it, or for a new user to understand it.
I will update the EEP, and I will continue to implement the maybe construct in the rest of OTP (shell, tools, documentation, and so on).
?= can have a fun case with macros where you do something like:
X ??OP exp()
There’s no real practical case for it, but in doing so the X ?= exp() expansion never takes place and instead we get X "=" exp() as a result. That’s an edge case and not something I would expect to seriously be an issue.