-
Couldn't load subscription status.
- Fork 264
Design note: Postfix operators
Consider this easy case:
f: (i:int) -> string = {/*...*/}
What is the type of f? of f(42)?
-
fis a function that takes anintand returns astring. -
f(42)is astring.
That was a good warmup. Now consider this function:
f: (i:int) -> * (:int) -> string = {/*...*/}
This reads left to right:
-
fis type(int) -> * (int) -> string, a function that takes anintand returns a pointer to a function that takes anintand returns astring. And we just said exactly that in code. -
f(42)is type* (int) -> string, a pointer to a function that takes anintand returns astring. -
f(42)*is type(int) -> string, a function that takes anintand returns astring. -
f(42)*(1)is typestring, astring.

Similarly, consider:
x: * int = /*...*/;
This also reads left to right:
-
xis type*int, a pointer to anint. -
x*is typeint, anint.

In Cpp2, my current experiment to disambiguate postfix unary operators that look similar to binary operators is that the postfix unary operators have to be written without intervening whitespace, such as x*. And that's pretty much the only rule to remember... additionally, as a convenience, cases like x**y mean the same as x* * y since they can't mean anything else, which is convenient so we can still write things like a*b and a*2 conveniently with the obvious meaning. That's the current experiment!
Note: This is the writeup that I promised in the CppCon 2022 talk.