# Words, constants, and variables in Fift (https://docs-fpm2731fy-ton-core-docs.vercel.app/llms/languages/fift/variables/content.md)



<Callout type="note">
  The official smart contract language of TON Blockchain is [Tolk](/llms/tolk/overview/content.md). Fift is now a **legacy** language, with its compiler no longer maintained.
</Callout>

## Words [#words]

A *word* is an identifier for an execution token. To define a new word, first define code inside `{ }`; then invoke word `:` followed by the identifier for the word. For instance,

```fift
// square takes the square of the integer at the top of the stack
{ dup * } : square
```

defines a new word `square`, which executes `dup` and `*` when invoked. Typing `5 square` is equivalent to typing `5 dup *`, and produces the same result:

```fift
5 square   // Produces 25 at the top of the stack
5 dup *    // Produces 25 at the top of the stack
```

It is possible to use the defined word inside new word definitions:

```fift
// **5 raises the integer at the top of the stack to the 5th power.
// It makes use of word square previously defined.
{ dup square square * } : **5
3 **5   // Produces 243 at the top of the stack.
```

This is the trace for `3 **5`:

```fift
3         // Stack: 3
// Definition of **5 executes
dup       // Stack: 3 3
square    // Stack: 3 9
square    // Stack: 3 81
*         // Stack: 243
```

If the word indicated after `:` is already defined, it is redefined. However, all existing definitions of other words will continue to use the old definition of the redefined word. For instance, if `square` is redefined after the definition of `**5` above, `**5` will continue to use the original definition of `square`.

## Constants [#constants]

A *constant* is a word that pushes a predefined value when invoked. Constants can be defined using the word `constant`. For instance,

```fift
1000000000 constant Gram
```

defines a constant `Gram` equal to `10^9`. In other words, `1000000000` will be pushed into the stack whenever `Gram` is invoked:

```fift
// Pushes Gram and 2 into the stack.
// Then, multiplies them, producing
// 2000000000 at the top of the stack.
Gram 2 *
```

It is possible to use the result of a computation to initialize the value of a constant:

```fift
// Define constant mGram with the result
// of the computation Gram 1000 /
Gram 1000 / constant mGram
mGram    // Pushes 1000000 into the stack
```

The value of a constant does not necessarily have to be an `Integer`. For instance, a string constant can be defined in the same way:

```fift
"Hello, world!" constant hello
hello   // Pushes "Hello, world!" into the stack
```

<Callout>
  If a constant is redefined, all existing definitions of other words will continue to use the old value of the constant. In this respect, a constant does not behave as a global variable.
</Callout>

It is possible to store two values into one "double" constant by using the word `2constant`. For instance:

```fift
355 113 2constant pifrac
```

defines a new word `pifrac`, which will push `355` and `113`, in that order, when invoked. The two components of a double constant can be of different types.

If a constant with a fixed name within a definition is needed, use `=:` and `2=:`, instead of `constant` and `2constant`.
The word `=: <IDENTIFIER>` takes the value at the top of the stack, creates constant `<IDENTIFIER>` and assigns the value to `<IDENTIFIER>`.
Similarly, word `2=: <IDENTIFIER>` takes the two top-most values in the stack, creates constant `<IDENTIFIER>` and assigns the values to `<IDENTIFIER>`.

For instance, the following defines a word `setxy`, which sets constants `x` and `y`:

```fift
{ dup =: x dup * =: y } : setxy
3 setxy x y +   // Produces 12 at the top of the stack
7 setxy x y +   // Produces 56 at the top of the stack
```

The code `3 setxy x y +`, which is equivalent to `3 dup =: x dup * =: y x y +`, changes the stack as follows:

```fift
3        // Stack: 3
dup      // Stack: 3 3
=: x     // Stack: 3    (x is 3)
dup      // Stack: 3 3
*        // Stack: 9
=: y     // Stack:      (y is 9)
x        // Stack: 3
y        // Stack: 3 9
+        // Stack: 12
```

The code `7 setxy x y +` has a similar explanation.

To recover the execution-time value of a constant inside a definition, prefix the constant name with the word `@'`. For instance, using the definition of `setxy` as above, the following code defines a new word `addxy` which accesses the constants `x` and `y` and adds them:

```fift
{ @' x @' y + } : addxy
3 setxy addxy    // Produces 12 at the top of the stack
```

The code `3 setxy addxy` has the same effect as the code `3 setxy x y +`. The main difference between `3 setxy addxy` and `3 setxy x y +` is that in `3 setxy addxy`, constants `x` and `y` are accessed inside a code definition, which require the use of word `@'` to access them; while in `3 setxy x y +`, the constants are accessed outside a code definition, which does not require the use of word `@'` to access them.

The drawback of this approach is that `@'` has to look up the current definition of constants `x` and `y` in the dictionary each time `addxy` is executed. [Variables](#variables) provide a more efficient way to achieve similar results.

## Variables [#variables]

*Variables* are a much more efficient way to represent changeable values. To declare a variable, use the word `variable` followed by the identifier. Internally, the word `variable` creates an empty [box](/llms/languages/fift/basic-values/content.md), which can then be updated with word `!`, and read with word `@`.

<Callout>
  Word `variable` is a shorthand for `hole constant`. In turn, `variable x` is a shorthand for `hole constant x`, which defines a [constant](#constants) `x` that stores an empty box.
</Callout>

For instance:

```fift
// Create two variables x and y, initialized to null
variable x variable y
// Set the value of x to 2
2 x !
// Set the value of y to 10
10 y !
// Read x and place the value at the top of the stack
x @
// Read y and place the value at the top of the stack
y @
// Add the two values
+     // Produces 12 at the top of the stack
```

The word `variable` produces variables initialized to `null`. Instead, to create initialized variables to a specific value, use the phrase `box constant`:

```fift
// Creates variable x and initializes it with value 17
17 box constant x
// Read x and place the value at the top of the stack
x @      // 17 at the top of the stack
// Increase 17 by 1
1 +
// Update x, now storing 18
x !
```

It is possible to define a special word for creating variables, if they are needed often:

```fift
{ box constant } : init-variable
// Create a variable x, initialized to 17
17 init-variable x
// Create a variable y, initialized to "test"
"test" init-variable y
```

Variables have one disadvantage compared to [constants](#constants): accessing the value stored in a variable requires the use of word `@`. This can be mitigated by defining a "getter" and a "setter" word for a variable, and use these words to write better-looking code:

```fift
// First, create the box storing the variable contents
variable x-box

// Define word x so that it reads the box contents.
// Now, x can be treated as if
// it was the "variable".
// In other words, instead of writing "x-box @"
// to read the variable contents, write "x".
{ x-box @ } : x

// Define a similar procedure for updating variable x.
{ x-box ! } : x!

// Update variable with 5
5 x!

// Read the variable twice and add the results
x x +    // Produces 10 at the top of the stack
```

It is possible to define "getters" and "setters" for variables in a more generic way. The following code defines the word `variable-get-set`, which creates a fresh variable and takes the two strings following `variable-get-set` to name the variable's getter and setter, respectively. For example, `variable-get-set x x!` will create a variable with getter `x` and setter `x!`.

```fift
{ hole dup 1 ' @ does create 1 ' ! does create } : variable-get-set
```

Word `variable-get-set` works as follows:

```fift
// Create a fresh box containing null
hole     // Stack: Box
// Duplicate the box
dup      // Stack: Box Box
// Push 1
1        // Stack: Box Box 1
// Push the word definition for @
' @      // Stack: Box Box 1 WordDef-for-@
// "does" creates the block/execution token { Box WordDef-for-@ execute }
// that first pushes Box and then executes @.
// The 1 integer in the stack tells "does" that it should
// consume only one stack element below 1
// in the stack.
// So, it only takes one Box immediately below 1 to include
// it inside the block/execution token.
does     // Stack: Box { Box WordDef-for-@ execute }
// Assign the block/execution token { Box WordDef-for-@ execute }
// to the first string coming after the invocation of variable-get-set
create   // Stack: Box
// Push 1
1        // Stack: Box 1
// Push the word definition for !
' !      // Stack: Box 1 WordDef-for-!
// Create a block/execution token { Box WordDef-for-! execute }
// that first pushes Box and then calls !.
// The 1 integer in the stack tells "does" that it should
// consume only one argument below 1
// in the stack.
// So, it only takes one Box immediately below 1 to include
// it inside the block/execution token.
does     // Stack: { Box WordDef-for-! execute }
// Assign the block/execution token { Box WordDef-for-! execute }
// to the second string coming after the invocation of variable-get-set
create   // Stack:
```

For instance, `variable-get-set` can be used as follows:

```fift
// Create a fresh variable with getter x and setter x!
variable-get-set x x!
// Create a fresh variable with getter y and setter y!
variable-get-set y y!
// Set x and y to 5 and 10, respectively.
5 x! 10 y!
// Swap variables x and y
x y x! y!
// Push x
x    // Top of stack has 10
// Push y
y    // Top of stack has 5
```

<Callout type="note">
  For more details on block/execution tokens and words `' <WORD_NAME>` and `execute`, refer to the blocks section in the [control flow page](/llms/languages/fift/control/content.md).

  For more details on words `create`, `' <WORD_NAME>`, `does`, refer to sections [4.5](/llms/languages/fift/whitepaper/content.md), [4.6](/llms/languages/fift/whitepaper/content.md), and [4.7](/llms/languages/fift/whitepaper/content.md) in the Fift whitepaper.
</Callout>

As another example of `variable-get-set`, the following implements a simple counter. The example uses auxiliary words `reset-counter` and `incr-counter` to reset the counter variable to `0` and increment the counter by one, respectively.

```fift
// Create the getter "counter" and setter "counter!"
variable-get-set counter counter!

// Reset the counter to 0
{ 0 counter! } : reset-counter

// Increment the counter by one.
{ counter 1 + counter! } : incr-counter

reset-counter      // counter variable has 0
incr-counter       // counter variable has 1
incr-counter       // counter variable has 2
reset-counter      // counter variable has 0
incr-counter       // counter variable has 1
counter            // Pushes 1 to the top of the stack
```

Word `incr-counter` works as follows:

```fift
// Push the current value of counter
counter    // Stack: c
// Push 1
1          // Stack: c 1
// Add c and 1
+          // Stack: c+1
// Store the new value back into the counter variable
counter!   // Stack:
```
