llm
Download
104 lines 3.4 KiBTomoModified 2026-09-09 raw
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
# The spaces around a binary operator say where an expression splits, so they
# are kept -- except in the `*` band of an expression that also holds a `+`
# band operator, where dropping them is what shows the split, or of one that
# holds a division, a quotient being written as one quantity. `^` never takes
# them, and a subscript takes none at all: the brackets already bound it.

func foo(v:Int -> Int)
    return v

func main()
    x := 1
    y := 2
    z := 3
    r := 2.0
    arr := [1, 2, 3]

    # One band and no division, so the spaces stay:
    >> x + y
    >> x * y
    >> x == y * z

    # Both bands, so the tighter one gives them up:
    >> x + y*z
    >> foo(x + y*z)
    >> x*(y + z)//2 + x + 1

    # A division does the same on its own, and takes the rest of its band
    # with it: spaces are a claim about grouping, and `x * y/z` would say
    # this multiplies the quotient rather than dividing the product.
    >> 100 / 10 / 2
    >> x / y
    >> x * y / z
    >> x / y == z
    >> x + y / z
    >> x // y
    >> foo(x)/foo(y)

    # A subscript is written compactly, whatever it holds:
    >> arr[x+1]
    >> arr[x+y*z]
    # ...though a call inside one is still a call:
    >> arr[foo(x + y)]
    >> arr[(x + y)*z]

    # An exponent sits against what it raises:
    >> x^2
    >> Float64.PI * r^2
    >> x + y^2
    >> 2^3^2

    # Parentheses start a fresh expression with its own answer:
    >> (x + y) * z
    >> x * (y + z)

    # An operator that is a word keeps its spaces wherever it stands, or it
    # stops being a word: `aandb` is one identifier, and `(x + y)mod3` does not
    # parse. A subscript, which drops them from everything else, is the place
    # that would go wrong first.
    >> arr[x and y]
    >> arr[x or y]
    >> arr[x xor y]
    >> arr[x mod y]
    >> arr[x mod1 y]
    >> arr[x _min_ y]
    >> arr[x _max_ y]
    >> arr[x*y mod 3]
    # A parenthesized operand settles its own spacing rather than inheriting
    # the subscript's, so the tightening stops at the parenthesis:
    >> arr[x+y and y]
    >> x + y mod 3

    # ...so where the operator around it has given its own spaces up, the
    # word operator takes parentheses instead: without them `a mod b/c` reads
    # as the modulus of a quotient, when it divides the modulus. A tight
    # operator inside a spaced one is already read the right way round and
    # needs nothing.
    #
    # `mod` and `mod1` take them against any other arithmetic operator, spaced
    # or not: they are words sitting somewhere in the middle of that band, and
    # where exactly is not something a reader carries around the way they do
    # `*` before `+`. Against a comparison they need nothing, arithmetic
    # binding tighter than one wherever it is written.
    >> x mod y / z
    >> x mod1 y / z
    >> x / y mod z
    >> x + y mod z*x
    >> arr[x+y mod z]
    >> (x and y)^2

    # `!=` keeps them for the same reason: `a!=b` reads as the `!` suffix on
    # `a`, followed by `= b`.
    >> arr[x != y]
    >> arr[x+y != y]

func decimal_runs(x:Num)
    # A tightened operator keeps its spaces where giving them up would leave it
    # against a `.`: `3.` written straight onto `*3` gives `3.*3`, with no
    # boundary left between the number and the operator. A division is the
    # exception, being how a quotient is written as a single quantity.
    >> 1./3. * 3
    >> 1./3.
    >> 1/3*3
    >> 7.5//2
    >> x * 0.5