Evaluation priorities

Rye’s base dialect has no special forms so all code evaluates in exactly the same manner based just on types of words in a block.

Different types of words, and nothing else, do affect evaluation precedence, so understanding these basic rules will help you understand the code.

The three infix types

There are three word types that take their first argument from the left:

; dot-words - pin to immediate left, right-to-left
subtract: ?_-
12 .subtract 6 .subtract 4
; right-to-left: 12 .subtract (6 .subtract 4) = 12 .subtract 2 = 10

; op-words (bridges) - left-to-right  
12 - 6 - 4
; left-to-right: (12 - 6) - 4 = 6 - 4 = 2

; pipe-words (walls) - wait for left side to fully evaluate
inc 10 |* 10
; wall effect: (inc 10) * 10 = 11 * 10 = 110

Dot-words: right to left

Dot-words (like .inc or .upper) pin to the immediate value on their left. When chained, they evaluate from right to left.

subtract: ?_-

12 .subtract 6 .subtract 4
; .subtract 4 pins to 6 → 2
; .subtract 2 pins to 12 → 10
; returns: 10

inc 10 .print
; .print pins to 10, prints 10
; inc then gets 10, returns 11

Op-words: left to right

Op-words (operators like + - * / and angle-bracket words like <concat>) bridge two values. When chained, they evaluate from left to right.

12 - 6 - 4
; (12 - 6) - 4 = 2

"a" <concat> "b" <concat> "c"
; ("a" <concat> "b") <concat> "c" = "abc"

Pipe-words: the wall

Pipe-words (like |* or |print) act as a wall. No expression passes through - everything on the left must fully evaluate first.

inc 10 |* 10
; wall: inc 10 = 11, then 11 * 10 = 110

; compare with op-word:
inc 10 * 10
; * bridges 10 and 10: inc 100 = 101

Mixing them

You can mix dot-words, op-words, and pipe-words to control exactly how expressions evaluate:

inc 10 * 10
; op-word * bridges 10 and 10: inc 100 = 101

inc 10 |* 10
; pipe-word |* is a wall: 11 * 10 = 110

13 + 14 .print |print
; .print pins to 14, prints 14
; |print waits for 13 + 14, prints 27

Using parentheses

When in doubt, parentheses give you explicit control:

( 12 - 6 ) - 4
; result: 2

12 - ( 6 - 4 )
; result: 10

Note: Expressions inside parentheses are not affected by walls outside them.

With assignment

Set-words and mod-words have even higher priority than pipe-words, meaning they capture everything that follows until the end of expression (including pipe-words).

Set/Mod-words (right assignment)

x:: 12 - 6 - 4
; x = 2 (captures the whole expression)

x:: inc 10 |* 10
; x = 110 (captures the whole expression)

Left Set/Mod-words (left assignment)

Left set-words (mod-words) capture the value from left in the same manner as pipe-words do:

12 - 6 - 4 ::x
; x = 2 (captures the result)

101 ::x + 1 |+ 2 |* 3 ::y
; x = 101, y = 312
; ::x captures 101, ::y captures the final result

Combining both

You can use both set/mod-words and left set/mod-words together:

x:: 101 + y:: 1 |+ 2 |* 3
; x = 110, y = 9
; y:: captures the pipe expression (9)
; x:: captures 101 + 9 = 110

In summary: dot-words evaluate right-to-left, op-words and pipe-words evaluate left-to-right, and set/mod-words have higher priority, capturing their respective expressions.