Quick Reference
A one-page cheat sheet for Sparkwheel syntax and features.
Core Syntax
| Syntax | Type | Returns | Example |
|---|---|---|---|
@key |
Resolved reference | Final computed value | lr: "@defaults::learning_rate" |
%key |
Raw reference | Unprocessed YAML | config: "%base.yaml::model" |
@key::nested |
Nested access | Nested value | @dataset::train::batch_size |
@list::0 |
List indexing | List element | @transforms::0 |
| Expression | Description | Example |
|---|---|---|
$(@a + @b) |
Math operations | $(@lr * 0.1) |
$(@name + "_v2") |
String concatenation | $(@model_name + "_trained") |
$(@debug ? "dev" : "prod") |
Ternary conditional | $(@is_training ? 0.5 : 0.0) |
$(@items[0]) |
Dynamic indexing | $(@datasets[@mode]) |
$len(@items) |
Built-in functions | $len(@layers) |
| Operator | Purpose | Example | Result |
|---|---|---|---|
=key |
Replace (don't merge) | =optimizer: sgd |
Replaces entire dict/value |
~key |
Delete key | ~debug: true |
Removes the key |
~list: [0, 2] |
Delete list items | ~layers: [1, 3] |
Removes items at indices 1 and 3 |
| (none) | Default: Merge | model: {size: 512} |
Merges with existing dict |
| Key | Type | Purpose | Example |
|---|---|---|---|
_target_ |
str | Class/function to instantiate | torch.optim.Adam |
_partial_ |
bool | Return partial function | true |
_disabled_ |
bool | Skip instantiation | true |
_mode_ |
str | Instantiation mode | "dict" / "dataclass" |
Common Patterns
Single Source of Truth
defaults:
learning_rate: 0.001
optimizer:
lr: "@defaults::learning_rate"
scheduler:
base_lr: "@defaults::learning_rate"
Computed Values
dataset:
samples: 10000
batch_size: 32
training:
steps_per_epoch: "$@dataset::samples // @dataset::batch_size"
Conditional Configuration
environment: "production"
database:
prod_host: "prod.db.com"
dev_host: "localhost"
host: "$@database::prod_host if @environment == 'production' else @database::dev_host"
Object Instantiation
model:
_target_: torch.nn.Linear
in_features: 784
out_features: 10
optimizer:
_target_: torch.optim.Adam
params: "$@model.parameters()"
lr: 0.001
Config Composition
override.yaml
# Merge by default
model:
hidden_size: 1024 # Updates only this field
# Or replace completely
=model:
hidden_size: 1024 # Replaces entire dict
Type Coercion
| From | To | Supported | Notes |
|---|---|---|---|
| str → int | ✅ | "42" → 42 |
|
| str → float | ✅ | "3.14" → 3.14 |
|
| str → bool | ✅ | "true" → True |
Accepts: true/false, yes/no, 1/0 |
| int → float | ✅ | 42 → 42.0 |
|
| float → int | ✅ | 3.14 → 3 |
Truncates decimal |
| Any → str | ✅ | Universal |
CLI Overrides
Schema Validation
from dataclasses import dataclass
from sparkwheel import Config, validator
@dataclass
class AppConfigSchema:
name: str
port: int
debug: bool = False
@validator
def check_port(self):
if not (1024 <= self.port <= 65535):
raise ValueError(f"Invalid port: {self.port}")
# Continuous validation (validates on every mutation)
config = Config(schema=AppConfigSchema)
# Or explicit validation
config = Config()
config.update("config.yaml")
config.validate(AppConfigSchema)
Resolution Order
References are resolved in dependency order:
a: 10
b: "@a" # Resolved first (depends on a)
c: "$@a + @b" # Resolved after a and b
d: "$@c * 2" # Resolved last (depends on c)
Best Practices
Do This
- ✅ Use
@references for DRY config - ✅ Enable schema validation for type safety
- ✅ Leverage composition-by-default (no operators needed)
- ✅ Use expressions for computed values
- ✅ Keep configs simple and readable
Avoid This
- ❌ Don't create circular references
- ❌ Don't overuse expressions (hurts readability)
- ❌ Don't use operators when default composition works
- ❌ Don't put complex logic in configs
Common Gotchas
| Issue | Problem | Solution |
|---|---|---|
| Reference not found | @key doesn't exist |
Check spelling and nesting |
| Circular reference | a: "@b", b: "@a" |
Restructure to break cycle |
| Type mismatch | Schema expects int, got str |
Enable coercion or fix type |
| Expression error | Invalid Python in $() |
Check syntax and references |
| Unexpected merge | Dict merged when you wanted replace | Use =key to replace |
| List not extending | List replaced instead of extended | This is default for scalars, expected |
File Organization
Small Projects
Medium Projects
project/
├── configs/
│ ├── defaults.yaml # Shared defaults
│ ├── dev.yaml # Development
│ └── prod.yaml # Production
└── train.py
Large Projects
project/
├── configs/
│ ├── base/
│ │ ├── model.yaml
│ │ ├── dataset.yaml
│ │ └── training.yaml
│ ├── experiments/
│ │ ├── baseline.yaml
│ │ └── improved.yaml
│ └── env/
│ ├── dev.yaml
│ ├── staging.yaml
│ └── prod.yaml
└── train.py
Performance Tips
Expression Evaluation
Expressions are evaluated at access time. For frequently accessed values:
Next Steps
- Configuration Basics - Learn config fundamentals
- References - Deep dive into
@and% - Expressions - Master
$()expressions - Operators - Composition with
=and~ - Schema Validation - Type-safe configs