> For the complete Mojo documentation index, see [llms.txt](/llms.txt).
> Markdown versions of all pages are available by appending .md to any URL (e.g. /docs/manual/basics.md).

# Intro to metaprogramming

Many languages have facilities for *metaprogramming*: writing code
that generates or modifies code. Python has facilities for dynamic
metaprogramming: features like decorators, metaclasses, and many more. These
features make Python very flexible and productive, but since they're dynamic,
they come with run-time overhead. Other languages have static or compile-time
metaprogramming features, like C preprocessor macros and C++ templates. These
can be limiting and hard to use.

Mojo's compile-time metaprogramming system uses the same language as run-time
programs, so you don't have to learn a new language—just a few new features.
The primary features you'll need to learn are:

- Compile-time statements and expressions
- Compile-time parameters
- Generics and traits

## Compile-time statements and expressions

The `comptime` keyword identifies a statement or expression that needs to be
evaluated at compile time. For example, the `comptime` keyword is used to
declare compile-time constant values and to introduce compile-time conditionals
and loops. For information on compile-time assignments and control flow, see
[Compile-time evaluation](/docs/manual/metaprogramming/comptime-evaluation/).

## Compile-time parameters

Functions and structs can be *parameterized* with compile-time parameters,
allowing you to define a container that holds different data types, or a matrix
multiplication algorithm that's parameterized by the matrix dimensions.
Compile-time parameters are similar to C++ template parameters or Rust generic
parameters. At compile time, Mojo *specializes* parameterized code to make
*concrete* versions—that is, it replaces parameters with constant values.

For example, a matrix multiplication function parameterized on its matrix
dimensions can be specialized at compile time to select the most efficient
algorithm based on those dimensions. For information on parameterization, see
[Parameters](/docs/manual/parameters/).

## Traits and generics

Generic functions and structs are made to handle different data types—for
example, a list that can hold `Int`, `Float32`, or `String` values. In Mojo, you
build generics using compile-time parameters—generic functions and structs are
parameterized on *types*.

  A *trait* defines a set of shared behaviors for structs. Generic code uses
  traits to identify the behaviors it requires. For example, instead of being
  bound to a specific type, a sort function could require that the type being
  sorted is `Movable` and `Comparable`. For more information, see the sections
  on [traits](/docs/manual/traits/) and
  [generics](/docs/manual/generics/).
