# Arguments and Symbols in PureData
PureData uses dollar sign variables (`$0`, `$1`, `$2`, etc.) for different purposes depending on context. Understanding how these work with arguments, set messages, and symbols is fundamental to creating flexible and reusable patches.
## Dollar Sign Variables Overview
PureData has two main contexts for dollar variables:
1. **Object arguments** - `$1`, `$2`, `$3`, etc. in object boxes
2. **Patch-local identifiers** - `$0` for unique identification within abstractions
## `$0` - Patch-Local Unique Identifier
**Purpose:** `$0` provides a unique number for each instance of an abstraction or subpatch. This prevents naming collisions when multiple instances exist.
**Key characteristics:**
- Automatically assigned by PureData when patch loads
- Different for each abstraction instance
- Same throughout a single patch instance
- Commonly used for send/receive pairs, arrays, and tables
**Example use case:**
```
[r $0-frequency] ← Receives from unique channel
[osc~]
[s $0-output] ← Sends to unique channel
```
When you create multiple instances of this abstraction, each gets its own `$0` value (e.g., 1001, 1002, 1003), ensuring `1001-frequency` doesn't conflict with `1002-frequency`.
## `$1`, `$2`, `$3` - Creation Arguments
**Purpose:** These represent arguments passed when creating an object. They are **replaced at creation time** and become fixed values.
**Key characteristics:**
- Set when object is created
- Cannot be changed dynamically
- Used in **object boxes** only (rectangular boxes)
- Evaluated left-to-right from the object's arguments
**Example in object box:**
```
[osc~ $1] ← OBJECT BOX: If created as [osc~ 440], $1 becomes 440
```
If you type `[osc~ 440]` in a patch, PureData creates an oscillator at 440 Hz. The `$1` is replaced with `440` at creation.
**Another example - receive object:**
```
[r $1-frequency] ← OBJECT BOX: If created as [r 1001-frequency],
$1 is replaced with 1001 at creation
```
**Important:** You create these as **object boxes**, not message boxes. In PureData:
- **Object box** = rectangular with sharp corners → `[r $1-ff]`
- **Message box** = rectangular with rounded top → `(set $1(` ← Different behavior!
### Combining `$0` and Creation Arguments
A common pattern combines both:
```
[table $0-buffer $1]
```
If this is in an abstraction called `[mysampler 1024]`:
- `$0` might be `1001` (unique instance ID)
- `$1` is `1024` (creation argument)
- Result: `[table 1001-buffer 1024]`
## Arguments vs Set Messages
### Using Arguments (Static)
```
[osc~ 440] ← Frequency fixed at creation
```
### Using Inlet + Set Message (Dynamic)
```
[set $1( ← Message box that will replace object's argument
|
[osc~ 440] ← Can be updated dynamically
```
**The `set` message** tells an object to replace its internal parameter without triggering output. This is different from sending a value directly.
**Example with `[float]` (f):**
```
[100(
|
[set $1(
|
[f] ← Sets to 100 but doesn't output
|
[bang( ← Triggers output of 100
```
## Symbols and Symbol Arguments
**Symbols** are text identifiers in PureData. When using `$1`, `$2` with symbols, they can represent text rather than numbers.
**Example:**
```
[symbol $1] ← If created as [symbol myname], outputs "myname"
```
### Symbol Substitution in Messages
In **message boxes** (rounded top), `$1` refers to **inlet values** received at runtime, not creation arguments:
```
[440( ← Number box
|
[set $1( ← MESSAGE BOX: $1 gets value from inlet (440) when triggered
|
[osc~]
```
**Key difference:**
- **Object box** `[r $1-ff]` → `$1` replaced at creation time (static)
- **Message box** `(set $1(` → `$1` replaced when message is triggered (dynamic)
This is why you use **object boxes** for receive channels in abstractions - you want the channel name to be determined at creation, not at runtime.
## Practical Workflow Examples
### Example 1: Abstraction with Configurable Parameters
**File: `myosc.pd`**
```
[inlet]
|
[* $1] ← $1 = frequency multiplier (creation argument)
|
[osc~]
|
[*~ $2] ← $2 = amplitude (creation argument)
|
[outlet~]
```
**Usage in parent patch:**
```
[440(
|
[myosc 2 0.5] ← 2x frequency multiplier, 0.5 amplitude
|
[dac~]
```
### Example 2: Using `$0` for Local Send/Receive
**File: `envelope.pd`**
```
[inlet]
|
[s $0-trigger]
[r $0-trigger]
|
[line~]
|
[outlet~]
```
Each instance has isolated communication via unique `$0` values.
### Example 3: Parent Patch Broadcasting to Multiple Abstraction Instances
**Problem:** You want to send a fundamental frequency to multiple instances of a `partial` abstraction without collisions between different parent patches (e.g., square wave vs triangle wave patches).
**Solution:** Use `$0` in the **parent patch** to create a unique send channel, and have abstractions receive from it using `$0` passed as a creation argument.
**Parent patch: `square-wave.pd`**
```
[440( ← Fundamental frequency input
|
[s $0-ff] ← Send to THIS patch's unique ff channel
[partial $0 1] ← 1st harmonic (fundamental)
|
[partial $0 3] ← 3rd harmonic
|
[partial $0 5] ← 5th harmonic (square waves use odd harmonics)
|
[partial $0 7] ← 7th harmonic
|
[+~]
|
[dac~]
```
**Abstraction: `partial.pd`**
```
[r $1-ff] ← OBJECT BOX: $1 replaced at creation with parent's $0
|
[* $2] ← OBJECT BOX: $2 is the harmonic number (1, 3, 5, 7...)
|
[osc~]
|
[outlet~]
```
**Important:** `[r $1-ff]` is an **object box** (not a message box). When you create `[partial 1001 3]` in the parent:
- `$1` becomes `1001` → object becomes `[r 1001-ff]`
- `$2` becomes `3` → object becomes `[* 3]`
- These values are **fixed at creation time**
**How it works:**
1. Parent patch `square-wave.pd` has its own `$0` value (e.g., `1001`)
2. It sends fundamental frequency to `[s 1001-ff]`
3. Each `[partial 1001 N]` instance receives from `[r 1001-ff]` and multiplies by its harmonic number
4. A separate `triangle-wave.pd` would have `$0` = `1002`, creating `[s 1002-ff]` with no collision
**Critical Note: Why Pass `$0` as an Argument?**
Each abstraction instance has its **own unique `$0` value**, completely separate from the parent's `$0`:
- Parent `square-wave.pd`: `$0` = `1001`
- First `[partial]` instance: `$0` = `1005`
- Second `[partial]` instance: `$0` = `1006`
- Third `[partial]` instance: `$0` = `1007`
If you tried to use `[r $0-ff]` directly in `partial.pd`, each instance would listen to a different channel (`1005-ff`, `1006-ff`, `1007-ff`), and the parent couldn't broadcast to all of them.
**By passing the parent's `$0` as `$1`, all instances subscribe to the same channel.**
**Alternative: Global Send/Receive (No Isolation)**
If you don't need isolation between different parent patches:
**Parent: `square-wave.pd`**
```
[440(
|
[s ff] ← Global send (no $0)
[partial 1] ← Only pass harmonic number
[partial 3]
```
**Abstraction: `partial.pd`**
```
[r ff] ← Global receive
|
[* $1] ← Harmonic multiplier
|
[osc~]
```
**Trade-off:** Simpler (no need to pass `$0`), but you can't run multiple waveform patches simultaneously without interference.
### Example 4: Dynamic Parameter Changes with Set
**Changing oscillator frequency without clicks:**
```
[metro 1000]
|
[random 1000]
|
[+ 200]
|
[set $1( ← Prepare new frequency
|
[bang( ← Trigger change at zero-crossing
|
[osc~]
```
The `set` message updates the frequency parameter, and the bang triggers the change smoothly.
## Common Pitfalls
❌ **Trying to change creation arguments dynamically:**
```
[440(
|
[osc~ $1] ← This does NOT work - $1 is fixed at creation
```
✅ **Instead, send values to the inlet:**
```
[440(
|
[osc~] ← Send directly to inlet for dynamic control
```
❌ **Forgetting `$0` in abstractions:**
```
[r frequency] ← Conflicts if multiple instances exist
```
✅ **Use `$0` for unique naming:**
```
[r $0-frequency] ← Each instance has unique channel
```
❌ **Hardcoding send/receive names across parent and abstractions:**
```
Parent: [s ff]
Abstraction: [r ff] ← All parent patches share same channel!
```
✅ **Pass parent's `$0` to abstractions:**
```
Parent: [s $0-ff] and [myabstraction $0]
Abstraction: [r $1-ff] ← Uses parent's unique namespace
```
## Summary Table
| Variable | Context | When Set | Can Change? | Use Case |
|----------|---------|----------|-------------|----------|
| `$0` | Object/Message | Patch load | No | Unique identifiers in abstractions |
| `$1`, `$2`... | Object box | Object creation | No | Fixed parameters from creation arguments |
| `$1`, `$2`... | Message box | Message received | Yes | Dynamic value substitution |
| `set $1` | Message to object | Message sent | Yes | Update object parameter without output |
## Related Topics
- [[PureData Abstractions]] - Creating reusable patches
- [[Send and Receive in PureData]] - Global vs local communication
- [[Message Boxes vs Object Boxes]] - Understanding PureData's dual syntax
## References
- PureData Documentation: [Arguments in Abstractions](http://puredata.info/)
- Miller Puckette's "Theory and Techniques of Electronic Music"