123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 | # Where a sub-expression needs parentheses to stay one. An inline `if`/`match`
# runs on through whatever follows it, and `_min_`/`_max_` are operators like
# any other, so both have to give the syntax around them somewhere to resume.
enum E(A{q:Int})
struct P{x:Int, y:Int}
func id(v:Int -> Int)
return v
func chosen(c:Bool -> Int)
# `return if ...` would be read as the postfix `return x if c`:
return (if c then 1 else 2)
func main()
a := yes
b := no
x := 1
y := 2
e := E.A{1}
# An argument list has to find its comma and its closing paren again:
>> id((if yes then x else y))
>> id(v=(match e case A{q} then q else 0))
>> P{(if yes then x else y), 2}
>> x.plus((if yes then x else y))
# ...and a table entry its `:`:
>> {(if yes then x else y): 1}
>> {1: (if yes then x else y)}
# `_min_` and `_max_` group by the same tightness as any other operator:
>> (a and b) _min_ b
>> a _min_ (b and a)
>> (x == y) _min_ x
>> (if yes then x else y) _min_ x
>> x _min_ (y _min_ x)
# ...so an operand it does absorb keeps no parentheses, as long as the
# grouping that leaves is one a reader can see (test/format/clarity.tm):
>> x _min_ y _min_ x
>> (x * y) _min_ x
>> (x _min_ y) _max_ x
# A comprehension written bare runs on: what follows it is read as another of
# its iterables or as its filter. It can stay bare where the construct around
# it ends right after it -- a container's last item, the whole of a reduction --
# and needs parentheses everywhere else. Beside a later item it needs them to
# keep its meaning at all: bare, the two below come back as one comprehension
# nested inside another.
func comprehensions(xs:[Int] -> Int)
a := (x for x in xs)
b := [x for x in xs]
c := [(x for x in xs), x * 2 for x in xs]
d := [1, (x for x in xs), 99]
e := (+: x for x in xs) or 0
f := {x: x * 2 for x in xs}
g := [x for x in y for y in [xs]]
>> [a, b, c, d, e, f, g]
return e
func wide(c:Bool -> Int)
# The same, when the sub-expression is too wide for one line: the block
# form runs on exactly as the one-line form does, so a list's `,` and a
# table entry's `:` need it bounded just the same.
>> [
(
if c
111111111111111111
else
22222222222222222222 + 333333333333333333 + 44444444444444
),
3,
]
>> {
1: (
if c
111111111111111111
else
22222222222222222222 + 333333333333333333 + 444444444444
),
}
>> id((
if c
111111111111111111
else
22222222222222222222 + 33333333333333333 + 44444444444444
))
return 1
func decimal_receivers()
# A `.` written straight against a decimal literal is hard to read: `2.`
# and `.sqrt()` run together into `2..sqrt()`, which looks like a range,
# and `4.2.ceil()` gives the eye nowhere to stop. An integer has no such
# trouble, so it keeps the bare form the author wrote.
>> (2.).sqrt()
>> (4.2).ceil()
>> (12.).round()
>> (0.25).is_exact(10)
>> 2.to(5)
>> 7.next_prime()
>> Num.PI.cos()
func word_prefix(optional:Int?, a:Bool, b:Bool)
# `not` is a word, and a word in front of an expression reads as taking all
# of it: `not x == y` is `not (x == y)` in most places it can be written,
# and `(not x) == y` here. It binds tighter than every binary operator, so
# nothing else was giving it parentheses.
assert (not optional) == no
assert a and (not b)
# Standing alone it needs none:
assert not optional
|