This document outlines the strategy for transitioning from "Parameterized/Universal" to "Lazy/Eager" terminology while maintaining backward compatibility and easing the transition for existing users.
| Old Term | New Term | Academic Name | Status |
|---|---|---|---|
| Parameterized | Lazy | Schulz & Mihov 2002 | ✅ Active |
| Universal | Eager | Mitankin 2005 | ✅ Active |
Goal: Introduce new terminology without breaking anything.
Actions:
#[doc(alias)] attributesTimeline: Immediate (v0.6.0 → v0.7.0)
Goal: Support both terminologies equally, encourage migration.
Actions:
Timeline: 6-12 months (3-6 releases)
Goal: Signal that old terminology will be removed, but don't break code.
Actions:
#[deprecated] attributes to type aliasesTimeline: 6-12 months before v1.0.0
Goal: Clean API with only lazy/eager terminology.
Actions:
Timeline: v1.0.0 major version bump
Current Structure:
src/
├── transducer/ # "Parameterized" (lazy)
└── transducer/universal/ # "Universal" (eager)
Strategy: Keep module names unchanged (no filesystem changes), use type aliases and docs.
Rationale:
// src/transducer/mod.rs
/// Lazy Levenshtein automaton (constructs states on-demand).
///
/// Also known as "Parameterized Levenshtein Automaton" in academic literature.
pub struct Transducer<D: Dictionary, P: SubstitutionPolicy = Unrestricted> {
// ...
}
// Phase 1-2: Add doc alias for discoverability
#[doc(alias = "ParameterizedTransducer")]
#[doc(alias = "ParameterizedAutomaton")]
// Phase 3: Add deprecation
// #[deprecated(since = "0.10.0", note = "Use `Transducer` directly. The 'parameterized' terminology is being phased out in favor of 'lazy'. See docs/migration/LAZY_EAGER_TERMINOLOGY.md")]
// pub type ParameterizedTransducer<D, P = Unrestricted> = Transducer<D, P>;
// src/transducer/universal/mod.rs
/// Eager Levenshtein automaton (precomputed structure).
///
/// Also known as "Universal Levenshtein Automaton" in academic literature.
pub struct UniversalAutomaton<V: PositionVariant> {
// ...
}
#[doc(alias = "EagerAutomaton")]
// Phase 1-2: Just documentation aliases
// Phase 3: Add actual type alias with deprecation
// #[deprecated(since = "0.10.0", note = "Use `UniversalAutomaton` directly. Consider the 'eager' terminology for conceptual clarity. See docs/migration/LAZY_EAGER_TERMINOLOGY.md")]
// pub type EagerAutomaton<V> = UniversalAutomaton<V>;
Phase 1-2 Documentation Pattern:
/// Lazy Levenshtein automaton for dictionary queries.
///
/// This automaton constructs states **lazily** (on-demand) during dictionary
/// traversal, minimizing memory usage and construction overhead.
///
/// # Terminology Note
///
/// In academic literature, this is called a "Parameterized Levenshtein Automaton"
/// (Schulz & Mihov, 2002). We use "lazy" terminology to emphasize **when**
/// construction happens (on-demand vs upfront), making the trade-offs more
/// intuitive for developers.
///
/// See [`UniversalAutomaton`] for the "eager" (precomputed) alternative.
Phase 3+ Documentation Pattern:
/// Lazy Levenshtein automaton for dictionary queries.
///
/// This automaton constructs states **lazily** (on-demand) during dictionary
/// traversal, minimizing memory usage and construction overhead.
///
/// Formerly called "Parameterized Levenshtein Automaton" in academic literature
/// (Schulz & Mihov, 2002).
src/transducer/mod.rs:
//! Lazy Levenshtein Automata
//!
//! This module implements lazy (on-demand) construction of Levenshtein automata,
//! also known as Parameterized Levenshtein Automata in academic literature.
//!
//! # Terminology
//!
//! - **Lazy**: States constructed on-demand during queries
//! - **Parameterized**: Academic term from Schulz & Mihov (2002)
//!
//! See [`crate::transducer::universal`] for eager (precomputed) automata.
src/transducer/universal/mod.rs:
//! Eager Levenshtein Automata
//!
//! This module implements eager (precomputed) Levenshtein automata,
//! also known as Universal Levenshtein Automata in academic literature.
//!
//! # Terminology
//!
//! - **Eager**: Entire structure precomputed upfront
//! - **Universal**: Academic term from Mitankin (2005)
//!
//! See [`crate::transducer`] for lazy (on-demand) automata.
Phase 1-2: Show Both
// examples/basic_query.rs
//! Basic dictionary query example.
//!
//! This example uses the lazy (parameterized) automaton for efficient
//! dictionary queries.
use liblevenshtein::prelude::*;
fn main() {
// Create lazy automaton (also called "parameterized")
let dict = DynamicDawg::from_terms(vec!["apple", "banana", "orange"]);
let transducer = Transducer::new(dict, Algorithm::Standard);
// Query
let results: Vec<_> = transducer.query("aple", 1).collect();
println!("Matches: {:?}", results);
}
Phase 3+: Use Only New Terms
// examples/basic_query.rs
//! Basic dictionary query example using lazy automaton.
use liblevenshtein::prelude::*;
fn main() {
// Create lazy automaton
let dict = DynamicDawg::from_terms(vec!["apple", "banana", "orange"]);
let transducer = Transducer::new(dict, Algorithm::Standard);
// Query
let results: Vec<_> = transducer.query("aple", 1).collect();
println!("Matches: {:?}", results);
}
Q: Will my code break? A: No. Module names and type names are unchanged. Only documentation terminology is evolving.
Q: Do I need to change my code? A: No immediate changes required. Your code will continue to work through v1.0.0.
Q: Should I adopt the new terminology? A: Yes, when convenient. New terminology is clearer for:
Q: What if I'm writing academic papers? A: Use original terminology (Parameterized/Universal) and cite:
Recommended: Learn and use "lazy/eager" terminology.
Why?
Academic context: Documentation notes the academic origins and paper names.
v0.7.0:
### Terminology Clarification
We're introducing clearer terminology for our two automaton implementations:
- **Lazy Automata**: On-demand state construction (formerly "Parameterized")
- **Eager Automata**: Precomputed structure (formerly "Universal")
**Why?** The new terms emphasize **when** construction happens, making trade-offs
more intuitive.
**Impact**: Zero. This is documentation-only. Your code works unchanged.
**Migration**: See docs/migration/LAZY_EAGER_TERMINOLOGY.md
**Academic context**: We maintain references to original paper terminology.
v0.10.0:
### Soft Deprecation: Old Terminology
Type aliases for old terminology are now deprecated:
- `ParameterizedTransducer` → use `Transducer` (lazy automaton)
- (If we added) `UniversalTransducer` → use `UniversalAutomaton` (eager automaton)
**Action required**: None yet. Compiler warnings help transition.
**Timeline**: Full removal in v1.0.0 (6+ months away).
v1.0.0:
### Breaking: Terminology Migration Complete
Removed deprecated type aliases:
- `ParameterizedTransducer` (removed)
- Use `Transducer` for lazy automata
**Migration**: See docs/migration/LAZY_EAGER_TERMINOLOGY.md
Title: "Clearer Terminology: Lazy vs Eager Levenshtein Automata"
Sections:
// tests/terminology_compatibility.rs
#[test]
fn test_transducer_works_as_lazy_automaton() {
// New terminology
let dict = DynamicDawg::from_terms(vec!["test"]);
let lazy_transducer = Transducer::new(dict, Algorithm::Standard);
assert_eq!(lazy_transducer.query("test", 0).count(), 1);
}
#[test]
fn test_universal_automaton_works_as_eager() {
// Academic terminology still works
let eager = UniversalAutomaton::<Standard>::new(2);
assert!(eager.accepts("test", "text"));
}
// Phase 3: Test aliases
#[test]
#[allow(deprecated)]
fn test_deprecated_aliases_still_work() {
// If we add: let _ = ParameterizedTransducer::new(...);
}
/// Example using new terminology.
///
/// ```
/// use liblevenshtein::prelude::*;
///
/// // Lazy automaton
/// let dict = DynamicDawg::from_terms(vec!["test"]);
/// let lazy = Transducer::new(dict, Algorithm::Standard);
/// ```
If adoption is poor or confusing:
Success Metrics (before Phase 3):
Guiding Principles:
Key Dates:
Community Input:
This gradual, respectful approach ensures:
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |