Infix functions?

In ReScript, can we define a infix function:

let blah = (a, b) => { ... }

then use it like

a `blah` b // evaluates to blah(a, b)

Thanks!

No, and you cant really define custom infix operators either (though you can overwrite + and similar). And, even if rescript would get custom infix operators in the future, it probably wouldn’t get non-operator infix functions anyway, as even ocaml does not support that (ocaml docs).

Some background

1 Like

Thanks for that summary.

Just a quick thought experiment: Status of custom infix operators? - #5 by cristianoc
but locally defined infix operators, as opposed to extensions to the core language, could easily be more permissive.

For example ! is a unary operator. And having also a binary ! operator in the language would come with lots of complexity, potential parser conflicts etc.
But, a per-file use of ! as binary operator (effectively shadowing out unary !) could be done without worrying about all that.

See proof of concept here: Proof of Concept: explore per-file custom infix operators. by cristianoc · Pull Request #6076 · rescript-lang/rescript-compiler · GitHub

1 Like

The file-local infix ops are an interesting idea…

So would the rational be, on a per-file, opt-in basis, you could say, define applicative infix ops for a parser, eg looking like this, use them in that file, and not have it clutter up other files/modules?

Out of curiosity, why not module-level rather than file-level?

It was per file-level only in the first iteration. After some initial feedback, it was converted to module-level scoping, which is quite nice (and more intuitive IMO).

But you cannot open or include it from somewhere else, so there is no accidental overwriting of your existing operators possible.

2 Likes

This is quite exciting, some (extremely uncommon) use cases do require infix operators, so it’d be great to have those for such tasks, and writing parsers is definitely one of them (I personally haven’t encountered any other use cases where I found I couldn’t do without infix)

That’s what concerns me. I don’t see any use cases for this feature. And now it looks like a feature just for feature. And having more features is not necessarily good.

3 Likes

Agreed, it’s definitely not in my priority list, but if we do make it, it has to be carefully scoped.

1 Like

I haven’t worked with parsers, but: is it realistic to always limit the usage of a particular operator to a single module? Or would you, say, have to repeat the directive for creating the same operator in other modules.

Overall, I do get the danger of infix operators (fragmentation, plus they’re not as self-explanatory as well-named function), but once you decide that a certain operator is worth it, or that a sort of DSL will make your code more readable, you kinda want to standardise that DSL across the app. So I actually think in some cases single-module infixes could fragmentise not the whole ecosystem but particular codebases, and make the code ownership problem worse.

5 Likes

Are you thinking of conceptually having the same operators available to every file in the project?

Well, I haven’t thought of that, exactly. I was just contemplating whether the single-module approach is preferable to the traditional OCaml/Reason approach, i.e., scoping infix operators the same way you scope the regular function.

But now that you mention it, you probably could define infix operators, e.g., in bscofing.json. Or, I don’t know, only allow to define while extending a Pervasives module, effectively making them available everywhere. That would discourage devs from defining too many operators and would make it impossible to define multiple versions of the same operators. Not sure it’s too idiomatic (in a way it’s like only having Array.map, but not, say, Result.map, and it’s also weird for Array.map to be pervasive), so I’m not sure it’s such a great idea either?

So… it should have probably occurred to me to ask this earlier, but: do you want to limit custom operators to single modules for technical (e.g., parsing complexity) reasons, or because you want to encourage/discourage certain usage scenarios?

For example ! is a unary operator. And having also a binary ! operator in the language would come with lots of complexity, potential parser conflicts etc.

How many people actually want to override built-in operators and change their arity? And how hard is it to forbid overriding the arity?

The traditional OCaml approach means extending the language with a set of predefined operators, and way to define them. That’s a much bigger and invasive change that raises several design questions. In the space of extensions of the language, it seems pretty unlikely that infix operators would get enough community support.
Separately, there are questions of discoverability, indirect scope (include etc), readability etc, that would need to be considered too.

2 Likes