← Back to Course Index

Lesson 2: Language Basics

Learn Nix syntax and write your first expressions

Learning Objectives

The Nix Language: A Brief Overview

Nix is a purely functional programming language designed specifically for declarative package management. It's simple enough to learn in a few hours, but powerful enough to describe complex systems.

Key insight: Everything in Nix is an expression—even your system configuration is just a fancy expression that evaluates to a data structure describing what you want.

Data Types

Numbers

Integers and floating-point numbers:

42 3.14 -7 0

Strings

Two kinds: simple strings (single quotes, literal) and double-quoted (with interpolation):

"hello world" 'single quoted string' "The answer is ${42}" # Evaluates to "The answer is 42"
String interpolation: Use ${...} to embed Nix expressions inside double-quoted strings. Single quotes are literal (no interpolation).

Lists

Ordered collections:

[ 1 2 3 ] [ "hello" "world" ] [ 1 "mixed" 3.14 ] # Mix types

Attribute Sets (Dictionaries/Objects)

The most important data structure in Nix. A set of key-value pairs:

{ name = "alice"; age = 30; email = "alice@example.com"; }

Access attributes with dot notation:

person.name # "alice" person.age # 30

Null and Booleans

true false null

Basic Operations

Arithmetic

2 + 3 # 5 10 - 4 # 6 3 * 7 # 21 20 / 4 # 5 10 % 3 # 1 (modulo)

String Concatenation

"hello" + " " + "world" # "hello world" # Using interpolation (preferred) let name = "bob"; in "Hello, ${name}!" # "Hello, bob!"

List Operations

[ 1 2 ] ++ [ 3 4 ] # Concatenate: [1 2 3 4]

Logical Operations

true && true # true (AND) true || false # true (OR) !true # false (NOT)

Key Language Constructs

The let...in Expression

Define local variables:

let x = 5; y = 10; in x + y # Evaluates to 15
Important: let introduces bindings (variables), in marks the start of the expression that uses them. Everything is an expression.

The if...then...else Expression

if true then "yes" else "no" # "yes" let x = 5; in if x > 3 then "big" else "small" # "big"

Comments

# Single-line comment /* Multi-line comment */

Working with Attribute Sets

Attribute sets are everywhere in Nix. Here's practical syntax:

Example: A package definition

let package = { name = "my-app"; version = "1.0"; dependencies = [ "nodejs" "python3" ]; }; in package.name # "my-app" package.version # "1.0"

Accessing nested attributes:

let config = { database = { host = "localhost"; port = 5432; }; }; in config.database.host # "localhost"

The with keyword (shorthand):

let person = { name = "alice"; age = 30; }; in with person; "${name} is ${toString age}" # "alice is 30"

Try It Yourself

Interactive Exercise

Open a terminal and start the Nix REPL:
nix repl

You'll see a prompt: nix-repl>

Try basic expressions:
nix-repl> 2 + 3 5 nix-repl> "hello" + " world" "hello world" nix-repl> [ 1 2 3 ] [ 1 2 3 ]
Define an attribute set:
nix-repl> person = { name = "alice"; age = 30; } { age = 30; name = "alice"; } nix-repl> person.name "alice"
Use string interpolation:
nix-repl> name = "bob" "bob" nix-repl> "Hello, ${name}!" "Hello, bob!"
Try a let...in expression:
nix-repl> let x = 10; y = 20; in x + y 30
Exit the REPL:
nix-repl> :quit

Challenge: Write a Package Description

Create a Nix expression that describes a software package. Here's a template:

let pkg = { name = "???"; version = "1.0.0"; description = "???"; dependencies = [ "???" "???" ]; url = "https://???"; }; in "Package ${pkg.name} (${pkg.version}): ${pkg.description}"

Try filling in the blanks and evaluating it in the REPL. Reference the glossary if you get stuck.

Key Takeaways