• टाइप सिस्टम का उपयोग करके runtime validation की जगह compile time पर invariants की गारंटी देने वाली Rust डिज़ाइन पद्धति को समझाया गया है
  • NonZeroF32, NonEmptyVec जैसे नए types (newtype) परिभाषित करके गलत states (0, empty vector आदि) को व्यक्त करना असंभव बनाया जाता है
  • Option या Result से failure लौटाने के बजाय, function arguments में constraints को मजबूत करके errors को पहले ही रोका जाता है
  • String::from_utf8 या serde_json::from_str की तरह parsing के ज़रिए meaningful types में बदलने के उदाहरण दिए गए हैं
  • Illegal states को unrepresentable बनाना और validation को जितना हो सके उतना पहले करना — यह डिज़ाइन सिद्धांत code stability और readability दोनों को बेहतर बनाता है

1. Runtime validation की जगह type से constraints व्यक्त करना

  • divide(a, b) function में 0 से divide करने पर runtime panic होता है
    • Option लौटाकर failure व्यक्त किया जा सकता है, लेकिन यह return type को कमजोर करने जैसा है
  • NonZeroF32 type परिभाषित करके केवल non-zero values को ही बनाया जा सकता है
    • constructor fn new(n: f32) -> Option<NonZeroF32> के रूप में है, और failure पर None लौटता है
    • divide_floats(a: f32, b: NonZeroF32) के रूप में define करने पर runtime validation की ज़रूरत नहीं रहती
  • Validation की ज़िम्मेदारी function के अंदर से caller की तरफ शिफ्ट करके errors को पहले ही हटाया जाता है

2. Duplicate validation हटाना और code को सरल बनाना

  • roots(a, b, c) function में a == 0 validation को Option से handle करने पर caller और function दोनों तरफ duplicate validation होता है
  • NonZeroF32 का उपयोग करने पर validation केवल एक बार किया जाता है, और उसके बाद logic सरल हो जाता है
  • इसी सिद्धांत से NonEmptyVec<T> परिभाषित करके empty vector की अनुमति नहीं दी जाती
    • अगर get_cfg_dirs() NonEmptyVec<PathBuf> लौटाए, तो बाद में main() में अतिरिक्त validation की ज़रूरत नहीं रहती

3. वास्तविक उदाहरण: String और serde_json

  • String अंदरूनी रूप से Vec<u8> का newtype है, और String::from_utf8 validity check करता है
    • उसके बाद इसे UTF-8 guaranteed string के रूप में सुरक्षित रूप से इस्तेमाल किया जा सकता है
  • serde_json का from_str::<Sample> JSON को struct में parse करता है और field presence तथा type consistency को compile time पर guarantee करता है
    • foo, bar fields की मौजूदगी, type match, array length आदि सभी constraints type level पर verify होते हैं

4. Type-driven design के दो सिद्धांत

  • Illegal states को unrepresentable बनाना
    • NonZeroF32 में 0 और NonEmptyVec में empty state को व्यक्त नहीं किया जा सकता
    • साधारण validation function (is_nonzero) अब भी गलत state को व्यक्त कर सकता है, इसलिए वह अधूरा है
  • Validation को जितना संभव हो उतना पहले करना
    • ‘Shotgun Parsing’ की तरह अगर validation पूरे codebase में बिखर जाए, तो यह security vulnerabilities (CVE-2016-0752 आदि) तक ले जा सकता है
    • Parsing stage में सभी constraints check कर लेने पर बाद का logic सुरक्षित रूप से चलाया जा सकता है

5. Rust में type-based proof और उसके उपयोग

  • Curry-Howard correspondence के अनुसार types को logical propositions और values को उनके proofs के रूप में देखा जा सकता है
    • typenum crate का उपयोग करके compile time पर mathematical relations (3 + 4 = 8) को verify किया जा सकता है
  • Type system के ज़रिए program की correctness को compile stage पर prove किया जा सकता है

6. Practical application के लिए सलाह

  • अगर external API simple types (bool, i32) माँगता हो, तब भी अंदरूनी तौर पर meaningful enum या newtype का उपयोग करें
    • उदाहरण: LightBulbState { On, Off } define करें और From<LightBulbState> for bool implement करें
  • अगर verify() या do_something_fallible() जैसे साधारण validation functions हों, तो parsing के ज़रिए structured type conversion पर विचार करें
  • यदि function का कोई side effect नहीं है, तो Result<Infallible, MyError> की तरह जानबूझकर impossible state को type में व्यक्त किया जा सकता है

7. निष्कर्ष

  • Rust के type system को validation tool की तरह इस्तेमाल करने पर code की clarity और stability बेहतर होती है
  • Vec, sqlx, bon जैसे Rust ecosystem के कई tools पहले से type-based design का उपयोग कर रहे हैं
  • हर समस्या को type से हल नहीं किया जा सकता, लेकिन validation logic को type level तक उठाने का तरीका maintainability और safety दोनों बढ़ाता है
  • Rust के शक्तिशाली type system का अधिकतम उपयोग करके ऐसा code लिखने की सिफारिश की गई है जिसमें compiler errors पकड़ ले

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.