---
title: "Factor Overview"
slug: factor-overview
url: https://listedarticles.com/articles/factor-overview
canonical_url: https://re.factorcode.org/2026/10/factor-overview.html
content_type: tutorial
language: en
published_at: 2026-10-04T00:00:00.000Z
updated_at: 2026-10-05T14:28:38.344Z
author: "John Benediktsson"
author_url: https://re.factorcode.org/
authored_by: human
publisher: "Re: Factor"
publisher_url: https://re.factorcode.org/
topics: ["Programming", "Tutorials", "Open Source"]
license: all-rights-reserved
word_count: 4819
reading_minutes: 21
citation: "John Benediktsson, Re: Factor. \"Factor Overview.\" 4 Oct 2026. https://re.factorcode.org/2026/10/factor-overview.html (all-rights-reserved)"
# The full text follows. The web page shows an extract and sends readers
# to the source above; quote the citation and link the canonical URL.
---

# Factor Overview

> John Benediktsson's code-forward tour of the Factor stack-based language for programmers new to concatenative languages, covering the stack, word definitions, quotations and combinators, sequences, tuples, generic words, vocabularies, errors and resource cleanup, macros, and common libraries such as JSON, regex, and HTTP.

# Factor Overview

I highly recommend reading the [guided tour of Factor](https://docs.factorcode.org/content/article-tour.html).
It provides a great introduction to the language and libraries of [Factor](https://factorcode.org).
Even still, I sometimes have also wanted to have more code-forward examples of everyday syntax,
control flow, combinators, and some of the main libraries. This is that overview. It assumes you have programmed before, but have not necessarily used a
stack-based language.

### Hello, world

The simplest [Hello, world](https://en.wikipedia.org/wiki/Hello,_world) is just:

```
"Hello, world!" print
```
You can run that from [the listener](https://docs.factorcode.org/content/article-listener.html):

```
IN: scratchpad "Hello, world!" print
Hello, world!
```
And you can run it from the command-line:

```
$ ./factor -e="\"Hello, world!\" print"
Hello, world!
```
Of course, you can also make this a file named `hello.factor`, which
defines a `hello` vocabulary (something you learn about in the
[your first program](https://docs.factorcode.org/content/article-first-program.html) tutorial).

```
USING: io ;
IN: hello
: main ( -- )
    "Hello, world!" print ;
MAIN: main
```
The [syntax](https://docs.factorcode.org/content/article-syntax.html) used above includes:

- [`USING:`](https://docs.factorcode.org/content/word-USING__colon__%2Csyntax.html) imports vocabularies (named collections of words)
- [`IN:`](https://docs.factorcode.org/content/word-IN__colon__%2Csyntax.html) selects the vocabulary for definitions, and
- [`MAIN:`](https://docs.factorcode.org/content/word-MAIN__colon__%2Csyntax.html) sets an entry point.

And then you can run it either as a script:

```
$ ./factor hello.factor
Hello, world!
```
Or, if this is available in the [vocabulary roots](https://docs.factorcode.org/content/article-vocabs.roots.html)
search path, run the vocabulary’s main word:

```
$ ./factor -run=hello
Hello, world!
```
For the rest of this overview, try the examples in the *listener*, Factor’s
[interactive REPL](https://docs.factorcode.org/content/article-listener.html).
Start the terminal listener with `./factor -run=listener`,
or use the graphical listener in the development environment. Each example
includes its imports; examples that build on a definition assume you have
entered that definition too. [`IN: scratchpad`](https://docs.factorcode.org/content/word-IN__colon__%2Csyntax.html) puts experimental definitions
in the listener’s usual working vocabulary. Feel free to paste the code
directly, to see what it does. Comments beginning with `!` are part of
valid Factor source.

For a quick start, work through the stack, word definitions, quotations, control flow, and sequences. The later sections introduce objects, metaprogramming, and libraries that you can return to as you need them.

### Values and the stack

[Literals](https://docs.factorcode.org/content/article-literals.html) push values onto the data stack. Words consume inputs from the top
of that stack and push their outputs. Code runs from left to right:

```
USING: math prettyprint ;
2 3 + .                         ! 5
10 4 - .                        ! 6
2 3 + 4 * .                     ! 20
```
[`.`](https://docs.factorcode.org/content/word-.%2Cprettyprint.html) consumes and prints an object. [`print`](https://docs.factorcode.org/content/word-print%2Cio.html) consumes and prints a string.
The comments beside examples show the output. Because printing removes the
value, these examples leave the stack empty unless stated otherwise.
There are no parentheses around function arguments: put the arguments on
the stack, then invoke the word. Below, the top of the stack is on the right:

```
Code       Stack
2          2
3          2 3
+          5
4          5 4
*          20
.          (empty)
```
Spaces matter. `2 3 +` is three tokens; `2+3` is a single token, which would
need to be the name of a word. Names like [`number>string`](https://docs.factorcode.org/content/word-number__gt__string%2Cmath.parser.html), [`empty?`](https://docs.factorcode.org/content/word-empty__que__%2Csequences.html), and
[`set-at`](https://docs.factorcode.org/content/word-set-at%2Cassocs.html) are ordinary word names. A trailing `?` conventionally marks a
predicate; `>` often appears in conversion names. Those characters are part
of the name, not separate operators. A trailing `!` often marks a mutating
variant, such as [`append!`](https://docs.factorcode.org/content/word-append%21%2Csequences.html); `*` usually marks an alternative form. There are some
[conventions](https://docs.factorcode.org/content/article-conventions.html) useful
for learning word and type naming.

### Comments and literals

```
USING: math multiline prettyprint ;
! A comment runs to the end of the line.
/* A block comment can span
   several lines. */
42 .                            ! Integer
-17 .                           ! Negative integer
0xff .                          ! 255, hexadecimal
0b1010 .                        ! 10, binary
3/4 .                           ! Exact rational
1.25 .                          ! Floating point
C{ 2 3 } .                      ! Complex number: 2 + 3i
t .                             ! True
f .                             ! False
"hello\nworld" .                ! String with an escape
CHAR: A .                       ! 65, a character code point
{ 1 2 3 } .                     ! Array
V{ 1 2 3 } .                    ! Growable vector
B{ 0 127 255 } .                ! Byte array
H{ { "name" "Ada" } } .         ! Hashtable
[ 1 + ] .                       ! Quotation: code as a value
```
Arrays and quotations contain objects without executing them. Collection
literals are useful for fixed data; when mutating one inside a word, use
[`clone`](https://docs.factorcode.org/content/word-clone%2Ckernel.html) to obtain a fresh copy rather than changing a shared literal.
This is a shallow copy: objects inside the collection are still shared.

Block comments come from the [`multiline`](https://docs.factorcode.org/content/vocab-multiline.html) vocabulary.

[`CHAR:`](https://docs.factorcode.org/content/word-CHAR__colon__%2Csyntax.html) produces an integer code point; Factor has no separate character
type. `{ ... }` is an array, while `[ ... ]` is executable code held as a
value called a [quotation](https://docs.factorcode.org/content/article-quotations.html).
Spaces separate the literal openers, their contents, and the closing
delimiters, as in `{ 1 2 3 }` and `[ 1 + ]`.

### Strings and escape characters

String literals use double quotes. A backslash introduces a
[character escape](https://docs.factorcode.org/content/article-escape.html):

| Escape | Meaning | 
|---|---|
| `\"` | Double quote | 
| `\\` | Backslash | 
| `\a` | Bell (code point 7) | 
| `\b` | Backspace (8) | 
| `\e` | Escape (27) | 
| `\f` | Form feed (12) | 
| `\n` | Newline (10) | 
| `\r` | Carriage return (13) | 
| `\s` | Space (32) | 
| `\t` | Tab (9) | 
| `\v` | Vertical tab (11) | 
| `\0` | Null (0) | 
| `\ooo` | Code point given by one to three octal digits | 
| `\xHH` | Code point given by exactly two hexadecimal digits | 
| `\uHHHHHH` | Code point given by exactly six hexadecimal digits | 
| `\u{H...}` | Code point given by hexadecimal digits inside braces | 
| `\u{name}` | Named Unicode character, with Unicode support loaded | 

For example:

```
USING: io prettyprint sequences unicode ;
"She said \"hello\"." print        ! She said "hello".
"C:\\Users\\Ada" print             ! C:\Users\Ada
"\x41\u000042\u{43}" print         ! ABC
"\u{greek-small-letter-pi}" print  ! π
"first\nsecond" print              ! Prints two lines
"\t" length .                      ! 1: the escape represents one character
"hello" length .                   ! 5
"hello" >upper .                   ! "HELLO"
"a,b,c" "," split .                ! { "a" "b" "c" }
{ "a" "b" "c" } ", " join .        ! "a, b, c"
"42" string>number .               ! 42
42 number>string .                 ! "42"
"oops" string>number .             ! f
```
The six-digit `\u` form differs from languages that use four digits; the
braced form is often easier to read. Unknown escapes are errors. Strings
can also span source lines directly: an actual newline becomes part of the
string. A backslash immediately before a source newline continues the
string without including that newline. A backslash followed by a literal
space also represents a space, like `\s`.

*Note: the length of a [string](https://docs.factorcode.org/content/article-strings.html)
is the number of code points, not the number of visible glyphs. You can learn a bit more
by reading about Factor’s [Unicode](https://re.factorcode.org/2023/05/unicode.html) support.*

### Stack shuffling

Typical of [concatenative languages](https://concatenative.org/wiki/view/Concatenative%20language),
the stack is a data structure with it’s own access patterns that we often call
[stack shuffling](https://docs.factorcode.org/content/article-tour-stack-shuffling.html).

```
USING: kernel prettyprint ;
10 dup . .                      ! Prints 10, then 10
10 20 swap . .                  ! Prints 10, then 20
10 20 over . . .                ! Prints 10, then 20, then 10
10 20 nip .                     ! 20: discard the second item
10 20 drop .                    ! 10: discard the top item
```
The usual [stack shuffling words](https://docs.factorcode.org/content/article-shuffle-words.html) have these effects:

```
! dup   ( x -- x x )
! drop  ( x -- )
! swap  ( x y -- y x )
! over  ( x y -- x y x )
! nip   ( x y -- y )
! rot   ( x y z -- y z x )
```
Most Factor code uses short definitions and combinators to keep explicit shuffling to a minimum.

In a stack effect, inputs and outputs run from left to right, with the
topmost value last. [`swap`](https://docs.factorcode.org/content/word-swap%2Ckernel.html) therefore changes a stack ending in `x y` into
one ending in `y x`; values below those inputs are untouched. Repeated
[`.`](https://docs.factorcode.org/content/word-.%2Cprettyprint.html) calls print the topmost result first.

### Defining words

You can create [words](https://docs.factorcode.org/content/article-words.html) that
contain code that is executed when called:

```
USING: kernel math prettyprint ;
IN: scratchpad
: square ( n -- n-squared ) dup * ;
: neighbors ( n -- below above )
    dup 1 - swap 1 + ;
5 square .                      ! 25
5 neighbors . .                 ! Prints 6, then 4
CONSTANT: answer 42
answer .                        ! 42
```
[`:`](https://docs.factorcode.org/content/article-colon-definition.html) begins a definition and [`;`](https://docs.factorcode.org/content/word-%3B%2Csyntax.html) ends it. The [stack effect](https://docs.factorcode.org/content/article-effects.html) `( inputs -- outputs )` documents how many values the word consumes and produces. Its
names describe the values; they do not bind variables or specify types.
The compiler checks stack effects, including compatible effects for branches.
Words can return several values simply by leaving them on the stack.
There is no explicit `return`: execution finishes at the end of the word.

[`ALIAS: new-name existing-word`](https://docs.factorcode.org/content/word-ALIAS__colon__%2Csyntax.html) defines another name for a word.

### Arithmetic and comparisons

Lots of [arithmetic](https://docs.factorcode.org/content/article-arithmetic.html) is
available for computing with [numbers](https://docs.factorcode.org/content/article-numbers.html):

```
USING: kernel math math.functions math.order prettyprint ;
7 2 / .                         ! 3+1/2, an exact rational
7 2 /i .                        ! 3, integer division
7 2 mod .                       ! 1
2 10 ^ .                        ! 1024
9 sqrt .                        ! 3.0
-5 abs .                        ! 5
3 8 min .                       ! 3
3 8 max .                       ! 8
2 3 < .                         ! t
2 3 >= .                        ! f
"hello" "hello" = .             ! t, value equality
```
[Integers](https://docs.factorcode.org/content/article-integers.html) grow beyond machine size automatically, and division of integers
can produce [exact ratios](https://docs.factorcode.org/content/article-rationals.html). Use floating-point inputs when you want
floating-point arithmetic.

Bitwise operations have their own names, separate from boolean logic:

```
USING: math prettyprint ;
0b1100 0b1010 bitand .          ! 8
0b1100 0b1010 bitor .           ! 14
0b1100 0b1010 bitxor .          ! 6
1 3 shift .                     ! 8: shift left
8 -1 shift .                    ! 4: shift right
```
### Quotations

Square brackets produce a [quotation](https://docs.factorcode.org/content/article-quotations.html). [`call`](https://docs.factorcode.org/content/word-call,kernel.html) executes it:

```
USING: kernel math prettyprint sequences ;
5 [ 1 + ] call .                ! 6
{ 1 2 3 } [ 2 * ] map .         ! { 2 4 6 }
```
Quotations can be passed to words, returned from words, and stored in
collections. Words that take quotations are called
[*combinators*](https://docs.factorcode.org/content/article-combinators.html).

### Booleans and conditionals

In [boolean tests](https://docs.factorcode.org/content/article-booleans.html), only [`f`](https://docs.factorcode.org/content/word-f%2Csyntax.html) is false. Zero, an empty string, and an empty array are all true.

```
USING: kernel math prettyprint ;
t f and .                        ! f
t f or .                         ! t
f not .                          ! t
3 2 > [ "yes" ] [ "no" ] if .    ! "yes"
0 [ "truthy" ] [ "false" ] if .  ! "truthy"
t [ "runs" . ] when
f [ "runs too" . ] unless
```
[`if`](https://docs.factorcode.org/content/word-if,kernel.html) consumes a condition and two quotations. It calls the first quotation
for a true condition and the second for [`f`](https://docs.factorcode.org/content/word-f%2Csyntax.html). [`when`](https://docs.factorcode.org/content/word-when%2Ckernel.html) and [`unless`](https://docs.factorcode.org/content/word-unless%2Ckernel.html) take one
quotation. These are words that operate on code values, just like [`+`](https://docs.factorcode.org/content/word-%2B%2Cmath.html)
operates on numbers.

For several alternatives, use [`cond` or `case`](https://docs.factorcode.org/content/article-conditionals.html):

```
USING: combinators kernel math prettyprint ;
IN: scratchpad
: sign-name ( n -- string )
    {
        { [ dup 0 < ] [ drop "negative" ] }
        { [ dup 0 = ] [ drop "zero" ] }
        [ drop "positive" ]
    } cond ;
-3 sign-name .                  ! "negative"
: color-name ( color -- string )
    {
        { "r" [ "red" ] }
        { "g" [ "green" ] }
        [ drop "unknown" ]
    } case ;
"g" color-name .                ! "green"
```
[`cond`](https://docs.factorcode.org/content/word-cond%2Ccombinators.html) tries predicate quotations in order. [`case`](https://docs.factorcode.org/content/word-case%2Ccombinators.html) compares an input with
each key; a matching branch consumes the key automatically, while the
default branch receives the unmatched input.

[`and`](https://docs.factorcode.org/content/word-and%2Ckernel.html) and [`or`](https://docs.factorcode.org/content/word-or%2Ckernel.html) combine values that have already been computed. For
[short-circuit evaluation](https://docs.factorcode.org/content/article-combinators.short-circuit.html), pass predicate quotations instead:

```
USING: combinators.short-circuit kernel math prettyprint ;
5 { [ 0 > ] [ 10 < ] } 1&& .    ! t: positive and less than ten
-5 { [ 0 < ] [ 10 > ] } 1|| .   ! t: negative or greater than ten
```
Each predicate receives the same input. [`1&&`](https://docs.factorcode.org/content/word-1%26%26%2Ccombinators.short-circuit.html) stops at the first false
result; [`1||`](https://docs.factorcode.org/content/word-1__pipe____pipe__%2Ccombinators.short-circuit.html) stops at the first true result. The leading number is the
number of inputs passed to each predicate.

### Keeping and hiding values

The [`dip`](https://docs.factorcode.org/content/word-dip,kernel.html) word temporarily hides a value while a quotation works on the stack below
it. [`keep`](https://docs.factorcode.org/content/word-keep,kernel.html) gives a quotation a value and also preserves that value:

```
USING: kernel math prettyprint ;
10 20 [ 1 + ] dip + .           ! 31: increment 10, then restore 20
5 [ 1 + ] keep . .              ! Prints 5, then 6
```
```
! dip   ( ..a x quot -- ..b x )
! keep  ( ..a x quot -- ..b x )
```
The overall shapes look alike, but `dip` hides `x` from the quotation and
`keep` passes it in. [`2dip`](https://docs.factorcode.org/content/word-2dip%2Ckernel.html) hides two values; [`2keep`](https://docs.factorcode.org/content/word-2keep%2Ckernel.html) preserves two inputs.

### Applying several quotations

The [`bi` family](https://docs.factorcode.org/content/article-cleave-combinators.html) covers several common ways to distribute inputs:

```
USING: kernel math prettyprint ;
! Apply two quotations to the same input.
5 [ 1 + ] [ 2 * ] bi . .        ! Prints 10, then 6
! Apply one quotation to each of two inputs.
3 4 [ 2 * ] bi@ . .             ! Prints 8, then 6
! Apply separate quotations to separate inputs.
3 4 [ 1 + ] [ 2 * ] bi* . .     ! Prints 8, then 4
! Apply two quotations to the same pair of inputs.
3 4 [ + ] [ * ] 2bi . .         ! Prints 12, then 7
```
For example, [`2bi`](https://docs.factorcode.org/content/word-2bi%2Ckernel.html) lets a word calculate two results from the same inputs:

```
USING: kernel math prettyprint ;
IN: scratchpad
: sum-and-product ( a b -- sum product )
    [ + ] [ * ] 2bi ;
3 4 sum-and-product . .         ! Prints 12, then 7
```
Then [`tri`](https://docs.factorcode.org/content/word-tri%2Ckernel.html), [`tri@`](https://docs.factorcode.org/content/word-tri__at__%2Ckernel.html), and [`tri*`](https://docs.factorcode.org/content/word-tri__star__%2Ckernel.html) extend these patterns to three quotations or
inputs.

You can find [`cleave`](https://docs.factorcode.org/content/word-cleave%2Ccombinators.html), [`napply`](https://docs.factorcode.org/content/word-napply%2Cgeneralizations.html) and [`spread`](https://docs.factorcode.org/content/word-spread%2Ccombinators.html) as the generalizations
of those patterns.

### Partial application and composition

The [`curry`](https://docs.factorcode.org/content/word-curry,kernel.html) word binds a value to the beginning of a quotation.
[`compose`](https://docs.factorcode.org/content/word-compose,kernel.html) joins two
quotations so that one runs after the other:

```
USING: kernel math prettyprint sequences ;
{ 1 2 3 } 10 [ + ] curry map .    ! { 11 12 13 }
5 [ 1 + ] [ 2 * ] compose call .  ! 12
```
`10 [ + ] curry` behaves like `[ 10 + ]`. This is a convenient way to build
a quotation using a value computed at runtime.

The [`fry` vocabulary](https://docs.factorcode.org/content/article-fry.html) provides quotation templates. [`_`](https://docs.factorcode.org/content/word-_%2Csyntax.html) inserts a value;
[`@`](https://docs.factorcode.org/content/word-__at__%2Csyntax.html) inserts a call to a supplied quotation:

```
USING: fry kernel math prettyprint sequences ;
{ 1 2 3 } 10 '[ _ + ] map .     ! { 11 12 13 }
5 [ 1 + ] '[ @ 2 * ] call .     ! 12
```
The apostrophe in `'[ ... ]` makes this a template rather than an ordinary
quotation. Its placeholders consume their values when the template is
constructed, not when the resulting quotation is called.

### Defining combinators

A combinator can be an ordinary word with quotation inputs. Give those
inputs their own [stack effects](https://docs.factorcode.org/content/article-inference-combinators.html) and declare the word [`inline`](https://docs.factorcode.org/content/word-inline%2Csyntax.html) so the
compiler can infer the effects at its call sites:

```
USING: kernel math prettyprint ;
IN: scratchpad
: twice ( ... quot: ( ... -- ... ) -- ... )
    dup [ call ] dip call ; inline
3 [ 2 * ] twice .               ! 12
```
The `...` represents values carried through the combinator. Here, the
supplied quotation must preserve stack height, and `twice` calls it twice.

### Loops and recursion

```
USING: kernel math prettyprint sequences ;
3 [ "hello" . ] times           ! Print three times
{ "Ada" "Grace" } [ . ] each    ! Visit each element
5 <iota> [ . ] each             ! Print 0 through 4
0 [ dup 3 < ] [ dup . 1 + ] while drop
! Print 0, 1, 2; keep the counter on the stack
```
The [looping combinator](https://docs.factorcode.org/content/article-looping-combinators.html) [`while`](https://docs.factorcode.org/content/word-while%2Ckernel.html) calls its predicate before each iteration. The predicate leaves
a condition; the body updates the loop’s values. [`until`](https://docs.factorcode.org/content/word-until%2Ckernel.html) reverses the
condition. Often [`each`](https://docs.factorcode.org/content/word-each%2Csequences.html), [`map`](https://docs.factorcode.org/content/word-map%2Csequences.html), or [`reduce`](https://docs.factorcode.org/content/word-reduce%2Csequences.html) expresses the loop directly.

Recursion uses an ordinary call to the word being defined:

```
USING: kernel math prettyprint ;
IN: scratchpad
: factorial ( n -- n! )
    dup 1 <=
    [ drop 1 ]
    [ dup 1 - factorial * ] if ;
5 factorial .                   ! 120
```
Definitions are read in order: define helper words before words that use
them. [`DEFER:`](https://docs.factorcode.org/content/article-deferred.html)
declares a word before its implementation, allowing mutual recursion:

```
USING: kernel math prettyprint ;
IN: scratchpad
DEFER: odd-count?
: even-count? ( n -- ? )
    dup 0 = [ drop t ] [ 1 - odd-count? ] if ;
: odd-count? ( n -- ? )
    dup 0 = [ drop f ] [ 1 - even-count? ] if ;
6 even-count? .                 ! t
7 odd-count? .                  ! t
```
These examples accept nonnegative integers. Factor guarantees
[tail-call optimization](https://docs.factorcode.org/content/article-tail-call-opt.html),
so a final call such as the one to `odd-count?` can continue without growing
the call stack.

### Local variables and closures

When names make an algorithm easier to read, import
[`locals`](https://docs.factorcode.org/content/article-locals.html) and define
a word with [`::`](https://docs.factorcode.org/content/word-__colon____colon__%2Csyntax.html). Inputs become lexical variables:

```
USING: kernel locals math prettyprint sequences ;
IN: scratchpad
:: rectangle-area ( width height -- area )
    width height * ;
:: add-offset ( seq offset -- newseq )
    seq [| n | n offset + ] map ;
3 4 rectangle-area .            ! 12
{ 1 2 3 } 10 add-offset .       ! { 11 12 13 }
:: hypotenuse-squared ( a b -- n )
    a a * :> a-squared
    b b * :> b-squared
    a-squared b-squared + ;
```
[`:>`](https://docs.factorcode.org/content/word-__colon____gt__%2Csyntax.html) binds a computed value. [`\[| n | ... \]`](https://docs.factorcode.org/content/word-%5B__pipe__%2Csyntax.html) names quotation inputs and can
capture enclosing variables, as `offset` does above. Output names in [`::`](https://docs.factorcode.org/content/word-__colon____colon__%2Csyntax.html)
still describe stack results; there is no implicit return variable.

[Mutable locals](https://docs.factorcode.org/content/article-locals-mutable.html) have an exclamation point in their declaration and an
associated setter:

```
USING: kernel locals math prettyprint ;
[let
    0 :> total!
    5 [ total 1 + total! ] times
    total .                     ! 5
]
```
[`\[let ... \]`](https://docs.factorcode.org/content/word-%5Blet%2Csyntax.html) establishes a lexical scope, including in the listener.

### Sequences

Arrays, vectors, strings, and several other types share the sequence
[protocol](https://docs.factorcode.org/content/article-sequence-protocol.html). Most sequence words work across these types:

```
USING: kernel math prettyprint sequences sorting ;
{ 10 20 30 } length .               ! 3
{ 10 20 30 } first .                ! 10
1 { 10 20 30 } nth .                ! 20, zero-based indexing
{ 1 2 } { 3 4 } append .            ! { 1 2 3 4 }
{ 1 2 3 } reverse .                 ! { 3 2 1 }
{ 1 2 3 4 } [ dup * ] map .         ! { 1 4 9 16 }
{ 1 2 3 4 } [ 2 mod 0 = ] filter .  ! { 2 4 }
{ 1 2 3 4 } 0 [ + ] reduce .        ! 10
{ 1 2 3 } [ 0 > ] all? .            ! t
{ 1 2 3 } [ 2 = ] any? .            ! t
{ 3 1 2 } natural-sort .            ! { 1 2 3 }
V{ 1 2 } clone
3 over push .                       ! V{ 1 2 3 }
```
The [sequence combinator](https://docs.factorcode.org/content/article-sequences-combinators.html) [`map`](https://docs.factorcode.org/content/word-map%2Csequences.html) collects quotation results; [`each`](https://docs.factorcode.org/content/word-each%2Csequences.html) is for side effects. [`reduce`](https://docs.factorcode.org/content/word-reduce%2Csequences.html)
threads an accumulator through the sequence. [`push`](https://docs.factorcode.org/content/word-push%2Csequences.html) mutates a growable
sequence and consumes both the new element and the sequence.

For incremental construction, [`make`](https://docs.factorcode.org/content/article-namespaces-make.html)
collects values produced inside a quotation. [`,`](https://docs.factorcode.org/content/word-__comma__%2Cmake.html) adds one element and [`%`](https://docs.factorcode.org/content/word-__percent__%2Cmake.html)
adds the elements of a sequence:

```
USING: make prettyprint ;
[ 1 , { 2 3 } % 4 , ] { } make .            ! { 1 2 3 4 }
[ "Hello" % CHAR: \s , "Ada" % ] "" make .  ! "Hello Ada"
```
The final exemplar (`{ }` or `""`) chooses the result type. Prefer [`map`](https://docs.factorcode.org/content/word-map%2Csequences.html),
[`filter`](https://docs.factorcode.org/content/word-filter%2Csequences.html), or [`append`](https://docs.factorcode.org/content/word-append%2Csequences.html) when one of those directly expresses the operation.

[`Specialized arrays`](https://docs.factorcode.org/content/article-specialized-arrays.html)
store elements as C numeric types in contiguous memory while supporting
the sequence protocol:

```
USING: alien.c-types prettyprint sequences specialized-arrays ;
SPECIALIZED-ARRAY: double
double-array{ 1.0 2.0 3.0 } length .  ! 3
```
### Hashtables and sets

Associative collections use the [`assocs` protocol](https://docs.factorcode.org/content/article-assocs.html):

```
USING: assocs kernel prettyprint ;
"Ada" H{ { "Ada" 36 } { "Grace" 85 } } at .  ! 36
"missing" H{ { "Ada" 36 } } at .             ! f
"enabled" H{ { "enabled" f } } at* . .       ! Prints t, then f
H{ { "Ada" 36 } } clone
37 "Ada" pick set-at
"Ada" swap at .                              ! 37
```
[`at*`](https://docs.factorcode.org/content/word-at__star__%2Cassocs.html) returns a presence flag as well as a value, distinguishing a missing
key from a key whose value is [`f`](https://docs.factorcode.org/content/word-f%2Csyntax.html). [`set-at`](https://docs.factorcode.org/content/word-set-at%2Cassocs.html) takes a value, key, and assoc.

[Sets](https://docs.factorcode.org/content/article-sets.html) also have a protocol, with useful operations on ordinary sequences:

```
USING: prettyprint sets ;
{ 1 2 2 3 } members .           ! { 1 2 3 }
2 { 1 2 3 } in? .               ! t
{ 1 2 } { 2 3 } union .         ! { 1 2 3 }
{ 1 2 } { 2 3 } intersect .     ! { 2 }
{ 1 2 } { 2 3 } diff .          ! { 1 }
```
For repeated membership checks, use a hash set rather than scanning a sequence:

```
USING: hash-sets prettyprint sets ;
2 HS{ 1 2 3 } in? .             ! t
```
### Tuples and accessors

[Tuples](https://docs.factorcode.org/content/article-tuples.html) define classes with named slots. [`boa`](https://docs.factorcode.org/content/word-boa%2Ckernel.html) constructs a tuple from
slot values in declaration order:

```
USING: accessors kernel prettyprint ;
IN: scratchpad
TUPLE: person name age ;
C: <person> person
"Ada" 36 <person>
dup name>> .                    ! "Ada"
37 >>age
age>> .                         ! 37
```
[`C:`](https://docs.factorcode.org/content/word-C__colon__%2Csyntax.html) defines a constructor using [`boa`](https://docs.factorcode.org/content/word-boa%2Ckernel.html). [`name>>`](https://docs.factorcode.org/content/article-accessors.html) reads a slot; [`>>age`](https://docs.factorcode.org/content/article-accessors.html)
writes a slot and returns the tuple, allowing chained updates. You can also
construct an instance with `person new` and set its slots explicitly.
Names such as `<person>` conventionally denote constructors; the angle
brackets are part of the word’s name.

Tuple literals use [`T{ ... }`](https://docs.factorcode.org/content/word-T%7B%2Csyntax.html). Slots can also declare a class, an initial
value, or the [`read-only`](https://docs.factorcode.org/content/word-read-only%2Csyntax.html) attribute:

```
USING: accessors kernel math prettyprint ;
IN: scratchpad
T{ person { name "Grace" } { age 85 } } name>> .  ! "Grace"
TUPLE: counter { value integer initial: 0 } ;
counter new
[ 1 + ] change-value
value>> .                                         ! 1
```
[`Slot declarations`](https://docs.factorcode.org/content/article-tuple-declarations.html)
constrain stored values. `{ name string read-only }`, for example, declares
a string slot that is initialized at construction and has no generated
setter. [`change-value`](https://docs.factorcode.org/content/article-accessors.html) applies a quotation to the current slot value,
stores the result, and returns the tuple.

### Structs and C layouts

[`STRUCT:`](https://docs.factorcode.org/content/article-classes.struct.html)
defines a record backed by a C memory layout. Every field declares a C
type, and the usual slot accessors work on struct instances:

```
USING: accessors alien.c-types classes.struct kernel prettyprint ;
IN: scratchpad
STRUCT: c-point
    { x double }
    { y double } ;
3.0 4.0 c-point boa
dup x>> .                       ! 3.0
y>> .                           ! 4.0
PACKED-STRUCT: packet-header
    { kind uint8_t }
    { length uint32_t } ;
packet-header heap-size .       ! 5
```
[`boa`](https://docs.factorcode.org/content/word-boa%2Ckernel.html) initializes fields from stack values; `c-point <struct>` creates an
instance with its declared initial field values. These constructors use
garbage-collected storage. [`STRUCT:`](https://docs.factorcode.org/content/word-STRUCT__colon__%2Cclasses.struct.html) includes alignment padding according
to the platform’s C layout rules. [`PACKED-STRUCT:`](https://docs.factorcode.org/content/word-PACKED-STRUCT__colon__%2Cclasses.struct.html) removes padding between
fields and at the end, for layouts that explicitly require packed storage.
It does not choose byte order.

[`UNION-STRUCT:`](https://docs.factorcode.org/content/word-UNION-STRUCT__colon__%2Cclasses.struct.html) defines overlapping C fields that share the same storage.
It serves a different purpose from [`UNION:`](https://docs.factorcode.org/content/word-UNION__colon__%2Csyntax.html), which groups Factor classes.
Use tuples for ordinary Factor records and structs when you need C-compatible
memory or an explicitly specified binary layout.

### Generic words and classes

A [generic word](https://docs.factorcode.org/content/article-generic.html) chooses a method based on the class of its topmost input.
This example reuses `person` and `<person>` from “Tuples and accessors”:

```
USING: accessors kernel math math.parser prettyprint ;
IN: scratchpad
GENERIC: description ( obj -- string )
M: person description name>> ;
M: integer description number>string ;
"Ada" 36 <person> description .  ! "Ada"
42 description .                 ! "42"
```
A [tuple subclass](https://docs.factorcode.org/content/article-tuple-subclassing.html)
inherits its parent’s slots and can add its own. An overriding method can
reuse the next less-specific method with
[`call-next-method`](https://docs.factorcode.org/content/article-call-next-method.html):

```
USING: accessors kernel prettyprint sequences ;
IN: scratchpad
TUPLE: employee < person role ;
C: <employee> employee
M: employee description
    [ call-next-method ] [ role>> ] bi " - " glue ;
"Ada" 36 "programmer" <employee> description .
! "Ada - programmer"
```
The constructor takes inherited slots first (`name`, `age`), then `role`.
Here [`call-next-method`](https://docs.factorcode.org/content/word-call-next-method%2Csyntax.html) receives the employee, calls the `person` method,
and returns `"Ada"`; the override combines that with the employee’s role.
It must appear inside a method definition and receives its inputs from the
stack, just like an ordinary call.

[`M:`](https://docs.factorcode.org/content/word-M__colon__%2Csyntax.html) defines a method. This is how protocols such as sequences and assocs
provide common operations for many concrete types. Classes also have
predicate words, and you can define narrower predicate classes or unions:

```
USING: kernel math prettyprint strings ;
IN: scratchpad
PREDICATE: positive-integer < integer 0 > ;
UNION: text-or-integer string integer ;
3 positive-integer? .           ! t
-3 positive-integer? .          ! f
"hello" text-or-integer? .      ! t
```
[`Mixin classes`](https://docs.factorcode.org/content/article-mixins.html)
are open groups of classes: [`INSTANCE:`](https://docs.factorcode.org/content/word-INSTANCE__colon__%2Csyntax.html) adds a member, including after the
mixin was defined. They are useful for protocols spanning unrelated types:

```
USING: prettyprint ;
IN: scratchpad
MIXIN: named
INSTANCE: person named
"Ada" 36 <person> named? .      ! t
```
[`Singleton classes`](https://docs.factorcode.org/content/article-singletons.html)
each have one stateless instance, useful as distinct states or options.
Unlike a plain symbol, each can have its own generic methods:

```
USING: prettyprint ;
IN: scratchpad
SINGLETONS: pending running finished ;
UNION: job-state pending running finished ;
pending job-state? .            ! t
```
[`UNION:`](https://docs.factorcode.org/content/word-UNION__colon__%2Csyntax.html) accepts instances of any listed class. [`INTERSECTION:`](https://docs.factorcode.org/content/word-INTERSECTION__colon__%2Csyntax.html) requires
membership in all listed classes. For named numeric values,
[`ENUMERATION:`](https://docs.factorcode.org/content/article-enums.html)
is available in [`classes.enumeration`](https://docs.factorcode.org/content/vocab-classes.enumeration.html):

```
USING: classes.enumeration prettyprint ;
IN: scratchpad
ENUMERATION: priority low medium high ;
priority.low .                  ! 0
priority.high .                 ! 2
```
### Symbols and dynamic variables

Lexical locals are scoped by source structure. [`namespaces`](https://docs.factorcode.org/content/vocab-namespaces.html) provides
[variables scoped dynamically](https://docs.factorcode.org/content/article-namespaces.html) around a quotation:

```
USING: namespaces prettyprint ;
IN: scratchpad
SYMBOL: current-user
"Ada" current-user [
    current-user get .          ! "Ada"
] with-variable
```
Called words inside the quotation see the binding too. [`with-variable`](https://docs.factorcode.org/content/word-with-variable%2Cnamespaces.html)
restores the previous binding on exit. [`set`](https://docs.factorcode.org/content/word-set%2Cnamespaces.html) changes a binding in the
current namespace; [`set-global`](https://docs.factorcode.org/content/word-set-global%2Cnamespaces.html) sets a global binding. A symbol is itself
a value, so symbols also work as distinct markers and hashtable keys.

### Errors and cleanup

```
USING: continuations kernel prettyprint ;
IN: scratchpad
ERROR: invalid-age age ;
[ -1 invalid-age ] [ drop "handled" ] recover .  ! "handled"
[ "work" . ] [ "cleanup" . ] finally
! Prints "work", then "cleanup"
```
The [exception handling](https://docs.factorcode.org/content/article-errors.html) form [`ERROR:`](https://docs.factorcode.org/content/word-ERROR__colon__%2Csyntax.html) defines an error class and a word that throws an instance.
[`recover`](https://docs.factorcode.org/content/word-recover%2Ccontinuations.html) calls a handler with the thrown object. The data stack is restored
to its state before the protected quotation, then the error is pushed.
[`finally`](https://docs.factorcode.org/content/word-finally%2Ccontinuations.html) runs cleanup on either normal completion or an error.

Factor also exposes [continuations](https://docs.factorcode.org/content/article-continuations.html),
which capture execution state and can later resume it. They underpin error
handling and cooperative threads; most everyday code uses those higher-level
facilities directly.

### Resource disposal

Ordinary objects are garbage collected. Resources such as open streams
also need [deterministic disposal](https://docs.factorcode.org/content/article-destructors.html).
[`dispose`](https://docs.factorcode.org/content/word-dispose%2Cdestructors.html) releases a resource explicitly. [`with-disposal`](https://docs.factorcode.org/content/word-with-disposal%2Cdestructors.html) passes a resource
to a quotation and disposes it when the quotation finishes or throws:

```
USING: destructors io io.encodings.utf8 io.files prettyprint ;
"Hello!\n" "disposal.txt" utf8 set-file-contents
"disposal.txt" utf8 <file-reader>
[ stream-readln . ] with-disposal  ! "Hello!"
```
This example creates `disposal.txt` in the current directory. The reader
is closed after reading the line. For several resources, use
[`with-destructors`](https://docs.factorcode.org/content/article-destructors-using.html)
and register each one for cleanup:

```
USING: destructors io io.encodings.utf8 io.files prettyprint ;
[
    "disposal.txt" utf8 <file-reader> &dispose
    stream-readln .             ! "Hello!"
] with-destructors
```
Both registration words leave the resource on the stack so you can use it:

| Word | When the resource is disposed | 
|---|---|
| [`&dispose`](https://docs.factorcode.org/content/word-%26dispose%2Cdestructors.html) | When the enclosing [`with-destructors`](https://docs.factorcode.org/content/word-with-destructors%2Cdestructors.html) scope finishes, on success or error | 
| [`\|dispose`](https://docs.factorcode.org/content/word-__pipe__dispose%2Cdestructors.html) | When the enclosing [`with-destructors`](https://docs.factorcode.org/content/word-with-destructors%2Cdestructors.html) scope exits with an error | 

[`&dispose`](https://docs.factorcode.org/content/word-%26dispose%2Cdestructors.html) is for resources used within a scope. [`|dispose`](https://docs.factorcode.org/content/word-__pipe__dispose%2Cdestructors.html) is useful when
building a result that owns resources: if construction fails, clean up;
if it succeeds, return the resources to the caller. For example:

```
USING: destructors io.encodings.utf8 io.files kernel ;
IN: scratchpad
: open-two-readers ( path1 path2 -- reader1 reader2 )
    [ [ utf8 <file-reader> |dispose ] bi@ ] with-destructors ;
"disposal.txt" "disposal.txt" open-two-readers
[ dispose ] bi@                 ! Caller closes both readers
```
If opening the second reader throws, the first reader is disposed. On
success, both readers remain open and the caller owns their cleanup.
Within each registration group, destructors run in reverse registration
order. The [`with-file-reader`](https://docs.factorcode.org/content/word-with-file-reader%2Cio.files.html) and [`with-file-writer`](https://docs.factorcode.org/content/word-with-file-writer%2Cio.files.html) combinators shown below
manage stream cleanup automatically.

### Vocabularies

A [vocabulary](https://docs.factorcode.org/content/article-vocabularies.html) is a namespace and a unit of source organization. A vocabulary
named `examples.greeting` conventionally lives in
`examples/greeting/greeting.factor` under a vocabulary root:

```
USING: io ;
IN: examples.greeting
<PRIVATE
: greeting ( -- string ) "Hello, world!" ;
PRIVATE>
: greet ( -- ) greeting print ;
MAIN: greet
```
[`<PRIVATE ... PRIVATE>`](https://docs.factorcode.org/content/word-__lt__PRIVATE%2Csyntax.html) places helper definitions in the vocabulary’s
private namespace. Import public definitions with `USE: examples.greeting`
or include it in a [`USING:`](https://docs.factorcode.org/content/word-USING__colon__%2Csyntax.html) list. Run the entry point with
`./factor -run=examples.greeting` once its directory is in a vocabulary
[root](https://docs.factorcode.org/content/article-vocabs.roots.html), such as your installation’s `work` directory. Dots organize vocabulary
names; importing a parent does not automatically import its children.

Source files need explicit imports. If a word is missing, its documentation
shows which vocabulary provides it. The listener may offer to import a word
automatically; include that vocabulary in [`USING:`](https://docs.factorcode.org/content/word-USING__colon__%2Csyntax.html) when saving the code.
For [ambiguous names](https://docs.factorcode.org/content/article-word-search.html),
use a vocabulary prefix or select a word with [`FROM:`](https://docs.factorcode.org/content/word-FROM__colon__%2Csyntax.html):

```
USING: math prettyprint ;
2 3 math:+ .                    ! 5
FROM: math => + ;
2 3 + .                         ! 5
```
### Editing and reloading

Factor’s listener runs in a live image containing loaded definitions and
objects. You can redefine a word and try it again in the same session.
For code saved in a vocabulary, load it once with [`USE:`](https://docs.factorcode.org/content/word-USE__colon__%2Csyntax.html), then
[reload changes](https://docs.factorcode.org/content/article-vocabs.refresh.html)
after editing its source:

```
USING: vocabs.loader vocabs.refresh ;
USE: examples.greeting
"examples.greeting" reload      ! Reload this vocabulary
refresh-all                     ! Reload changed files in loaded vocabularies
```
This assumes you saved `examples.greeting` in a vocabulary root as above.
The [scaffold tool](https://docs.factorcode.org/content/article-tools.scaffold.html)
can create source, documentation, and test files for a new vocabulary.

### Code as data, macros, and parsing words

Words are objects too. A backslash obtains a word without executing it:

```
USING: accessors math prettyprint words ;
\ + name>> .                    ! "+"
```
Quotations are built out of objects and words.
[Macros](https://docs.factorcode.org/content/article-macros.html) compute quotations
that the compiler expands at call sites:

```
USING: kernel macros math prettyprint ;
IN: scratchpad
MACRO: add-constant ( n -- quot ) [ + ] curry ;
5 10 add-constant .             ! 15
```
Here `10` is the macro input, and the expansion adds it to the runtime
value `5`. Macro inputs must be known at compile time.

Syntax is extensible through [*parsing words*](https://docs.factorcode.org/content/article-parsing-words.html), which execute while source
is being read. `:`, [`TUPLE:`](https://docs.factorcode.org/content/word-TUPLE__colon__%2Csyntax.html), and literal openers are examples. Libraries
can add their own syntax, such as `R/ ... /` for regular expressions.

### Memoization

[`MEMO:`](https://docs.factorcode.org/content/article-memoize.html) defines a word whose results are cached by its inputs:

```
USING: kernel math memoize prettyprint ;
IN: scratchpad
MEMO: fibonacci ( n -- m )
    dup 1 <= [ ] [
        [ 1 - fibonacci ] [ 2 - fibonacci ] bi +
    ] if ;
10 fibonacci .                  ! 55
```
This is useful for pure computations. Cached mutable results are shared objects, so memoization needs care when callers mutate those results.

### Files and formatted output

```
USING: formatting io io.encodings.utf8 io.files prettyprint ;
"Ada" 36 "%s is %d years old.\n" printf
"Hello, world!\n" "hello.txt" utf8 set-file-contents
"hello.txt" utf8 file-contents print
"hello.txt" utf8 [
    readln .
] with-file-reader
```
The [file examples](https://docs.factorcode.org/content/article-io.files.html) create `hello.txt` in the current directory.
[`formatting`](https://docs.factorcode.org/content/article-formatting.html) provides [`printf`](https://docs.factorcode.org/content/word-printf%2Cformatting.html) for formatted output.
[`with-file-reader`](https://docs.factorcode.org/content/word-with-file-reader%2Cio.files.html) binds the current input stream and closes it after the
quotation finishes. [`with-file-writer`](https://docs.factorcode.org/content/word-with-file-writer%2Cio.files.html) does the same for output.

### JSON, regular expressions, and HTTP

The [`json` vocabulary](https://docs.factorcode.org/content/article-json.html) converts between JSON text and Factor objects:

```
USING: assocs json kernel prettyprint ;
"{\"name\":\"Ada\",\"age\":36}" json>
"name" swap at .                ! "Ada"
H{ { "name" "Ada" } } >json .   ! "{\"name\":\"Ada\"}"
```
[Regular expressions](https://docs.factorcode.org/content/article-regexp.html) use their own literal syntax:

```
USING: prettyprint regexp ;
"12345" R/ [0-9]+/ matches? .   ! t
"hello" R/ [0-9]+/ matches? .   ! f
```
The [HTTP client](https://docs.factorcode.org/content/article-http.client.html) returns both a response object and the downloaded content:

```
USING: http.client kernel ;
"https://factorcode.org" http-get
nip                             ! Leave only the content
```
### Dates and calendars

[`calendar`](https://docs.factorcode.org/content/article-calendar.html) provides timestamps and durations and computations on them.

```
USING: calendar prettyprint ;
now .                              ! Current local timestamp
10 months duration>minutes         ! Lots of minutes
today next-monday                  ! The next monday after today
```
### Random

[`random`](https://docs.factorcode.org/content/article-random.html) selects random numbers or collection elements:

```
USING: prettyprint random ;
10 random .                        ! Random integer from 0 through 9
{ "red" "green" "blue" } random .  ! Random element
```
We also have various [random distributions](../../2024/07/random-distributions.html) available.

### Threads

Factor [threads](https://docs.factorcode.org/content/article-threads.html) are cooperatively scheduled. [`yield`](https://docs.factorcode.org/content/word-yield%2Cthreads.html) lets another runnable
thread execute, and blocking I/O integrates with the scheduler:

```
USING: kernel math prettyprint threads ;
42 [ 1 + . ] curry "worker" spawn drop
yield                           ! Worker prints 43
```
The worker starts with an empty data stack; `curry` explicitly carries the
input into its quotation. The `concurrency` vocabularies provide additional
tools such as mailboxes and promises.

### Calling C

The [foreign function interface](https://docs.factorcode.org/content/article-alien-invoke.html) declares C functions as Factor words.
For example, this binds `strlen` from the C library:

```
USING: alien.c-types alien.syntax prettyprint ;
IN: scratchpad
LIBRARY: libc
FUNCTION: size_t strlen ( c-string str )
"hello" strlen .                ! 5
```
The [`c-string`](https://docs.factorcode.org/content/word-c-string%2Calien.c-types.html) argument converts a Factor string for the C call. The FFI
also supports structures, pointers, callbacks, and arrays. Unlike the
managed objects used above, foreign allocations can require explicit
lifetime management.

### Testing and exploring

[`tools.test`](https://docs.factorcode.org/content/article-tools.test.html) expresses expected stack results as an array:

```
USING: kernel math tools.test ;
{ 5 } [ 2 3 + ] unit-test
{ 25 } [ 5 dup * ] unit-test
[ 1 0 / ] must-fail
```
Tests for a vocabulary conventionally live alongside its source in a
`*-tests.factor` file. After saving tests for `examples.greeting`, run them
with `"examples.greeting" test` in the listener. This also runs tests in
its child vocabularies.

The development environment also lets you inspect definitions, look up documentation, and time quotations:

```
USING: help kernel math see sequences tools.time ;
\ map help                      ! Open documentation for map
\ + describe                    ! Describe the object ``+``
\ square see                    ! Show the earlier definition
[ 1000000 [ ] times ] time      ! Time a quotation
```
The [Factor handbook](https://docs.factorcode.org/content/article-handbook.html)
is the next stop for more detail. For a project walkthrough, the
[first-program tutorial](https://docs.factorcode.org/content/article-first-program.html)
covers creating a vocabulary, editing and reloading it, and extending it
with tests. The
[vocabulary index](https://docs.factorcode.org/content/article-vocab-index.html) covers
the libraries, and the source distribution includes documentation and tests
next to the code. Start with small words, follow their stack effects, and
use combinators to make the flow of values clear.
