Parentheses
Parentheses typically have four purposes in programming languages:
- in expressions, parentheses are used to override operator precedence, e.g.,
a * (b + c)
- in calls, parentheses are used to enclose actual arguments, e.g.,
f(x, g(h(y, z)))
- in function declarations, parentheses are used to enclose formal argument, e.g.,
square(x f64) => x*x
- defining tuples, e.g.,
(x, y)
Parentheses in Operator Expression
Parentheses for Operator Precedence
Just as one would expect, parentheses in Fuzion can override default operator precedence in Fuzion. This can be particularly important since operators could be prefix, infix, or postfix operators:
f (s String) is prefix + => f("<" + s + ">") postfix + => f("[" + s + "]") infix + (g f) => f("(" + s + "," + g.s + ")") redef as_string => s.as_string say "(1): " + (+ f("a") + + + f("b") +) say "(2): " + ((+ f("a")) + ((+ (+ (f("b") +))))) say "(3): " + ((+ ((f("a") +) +) + f("b")) +)
Here, the expression passed to say
marked with (1)
will produce the same output as the one marked with (2)
, while the
parentheses used in (3)
results in completely different output:
(1): (<a>,<<[b]>>) (2): (<a>,<<[b]>>) (3): [(<[[a]]>,b)]
Parentheses for Multi-line Expressions
Expressions in Fuzion are restricted to a single code line. Expressions extending over several lines, must be enclosed in parentheses. For example
x := 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10
will cause a compile time exception since this will be parsed as two statements, first
x := 1 + 2 + 3 + 4 + 5 +
followed by
6 + 7 + 8 + 9 + 10
resulting in two errors: First, the second lines indentation is invalid, and
also there is no postfix +
operator that could be applied
to 5
at the end of the first line.
To compile these two lines, we can use parentheses as follows:
x := (1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)
Parentheses in Calls
Function call chaining
Parentheses in calls are optional in Fuzion as long as the innermost call takes the last argument, e.g,, the calls in
f(x, g(h(y, z)))
Are equivalent to
f x, g h y, z
However, if an inner call takes only part of the following argument such as the call to h
in
f(x, g(h(y)), z)
requires parentheses as follows
f x, g h(y), z
For the parser to distinguish this from the previous code.
Function calls and operators
Mixing operators, in particular prefix operators with calls causes problems for the parser if parentheses are left out. In this code:
a := f(-x)
Leaving out the parentheses results in
a := f -x
Which can be parsed as an infix minus operator applied to f
and x
. So we need to put parentheses in a call if the first
parameter starts with a prefix operator, which is somewhat ugly.
Alternatively, we can change the parser to syntactically differentiate infix
and prefix operators as follows, similar to what is done in XL:
An operator with white space (including comments) to its left and no white space
(nor comments) to its right would be parsed as an infix operator. Consequently,
the following code would all compile as a call to f
with
argument -x
:
# all of the following lines will call f with argument -x a := f(-x) a := f(- x) a := f( - x) a := f -x a := f /* first and only argument: */ -x a := f/* first and only argument: */-x
While the following code would be parsed as infix -
applied
to f
and x
:
# all of the following lines will call the infix operator '-' as in f.infix -(x) a := f-x a := f - x a := f- x a := f-/* <- this is an infix minus */x
Using white space to change the semantics of a program causes a lot of dispute. However, if you look at these examples, interpreting the white space as suggested here results in the least surprise for human readers, so the danger of introducing errors can be expected to be very low.
There are other situations where white space would change the semantics as
well, examples are the differences between x ++ y
and x +
+
, where the first uses an infix operator ++
and the second
uses two operators, a postfix +
and an infix +
.
Similarly, foobar
is clearly semantically different from foo
bar
.
Parentheses in Feature Declarations
TBW
Parentheses for tuples
TBW