-
Notifications
You must be signed in to change notification settings - Fork 251
Design note: Postfix operators
Consider this easy case:
f: (i:int) -> string = {/*...*/}
What is the type of f
? of f(42)
?
-
f
is a function that takes anint
and 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:
-
f
is type(int) -> * (int) -> string
, a function that takes anint
and returns a pointer to a function that takes anint
and returns astring
. And we just said exactly that in code. -
f(42)
is type* (int) -> string
, a pointer to a function that takes anint
and returns astring
. -
f(42)*
is type(int) -> string
, a function that takes anint
and returns astring
. -
f(42)*(1)
is typestring
, astring
.
Similarly, consider:
x: * int = /*...*/;
This also reads left to right:
-
x
is 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.