- अमेरिकी IRS ने नया Tax Withholding Estimator(TWE) ओपन सोर्स के रूप में जारी किया है, और इसकी मुख्य डिज़ाइन सिद्धांत अमेरिकी टैक्स क़ानून को XML-आधारित declarative specification के रूप में मॉडल करना है
- TWE का टैक्स कैलकुलेशन लॉजिक Fact Graph नामक लॉजिक इंजन पर बना है, और हर टैक्स आइटम को XML में परिभाषित "Fact" के dependency graph के रूप में व्यक्त किया गया है
- JavaScript जैसी imperative language में टैक्स लॉजिक लागू करने पर execution order management, intermediate values के खो जाने, और implementation details के उजागर होने जैसी समस्याएँ आती हैं, इसलिए declarative approach आवश्यक है
- JSON arbitrary nested expressions को संभालने के लिए उपयुक्त नहीं है, जबकि XML में टैग खुद object type को दर्शाते हैं, इसलिए DSL बनाने के लिए यह कहीं अधिक अनुकूल है
- XML के साथ XPath जैसी mature tool ecosystem का मुफ़्त उपयोग किया जा सकता है, इसलिए cross-platform declarative specifications के लिए यह सबसे cost-effective विकल्प है
Fact Graph: XML में व्यक्त अमेरिकी टैक्स क़ानून
- IRS द्वारा जारी Tax Withholding Estimator(TWE) एक ऐसा टूल है जिसमें करदाता अपनी आय और deductions दर्ज करके टैक्स और withholding राशि का अनुमान लगा सकते हैं
- यह प्रोजेक्ट open source है, और आम लोगों के योगदान भी स्वीकार करता है
- TWE दो XML configurations से बनने वाली एक static site है, जिनमें पहला अमेरिकी टैक्स क़ानून को व्यक्त करने वाला Fact Dictionary है
- Fact Graph मूल रूप से IRS Direct File प्रोजेक्ट के लिए बनाया गया लॉजिक इंजन है, जो करदाता की टैक्स देनदारी और withholding को Fact Dictionary में परिभाषित facts के आधार पर गणना करता है
- हर fact XML में परिभाषित होता है; उदाहरण के लिए
/totalOwed को /totalTax में से /totalPayments घटाने वाले derived fact के रूप में व्यक्त किया गया है
- "कुल देय राशि(total owed)" आय पर कुल टैक्स(total tax) और पहले से चुकाई गई राशि(total payments) के अंतर के बराबर है
- Refundable credits ऐसे tax credits हैं जो टैक्स बैलेंस को नकारात्मक बना सकते हैं; इनमें Earned Income Credit, Child Tax Credit, American Opportunity Credit आदि को
<Add> से जोड़ा जाता है
- Non-refundable credits टैक्स देनदारी को केवल 0 तक ही घटा सकते हैं, और
<GreaterOf> operator के ज़रिए 0 और (tentative tax - non-refundable credits) में से बड़ा मान चुना जाता है
- User input values के लिए
<Derived> की जगह <Writable> टैग का उपयोग होता है, और <Dollar/>, <Boolean/> आदि से value type निर्दिष्ट किया जाता है
- Facts एक-दूसरे पर निर्भर रहते हैं और अंतिम टैक्स संख्या निकालने वाली graph structure बनाते हैं
टैक्स लॉजिक के लिए declarative specification क्यों ज़रूरी है
- वही गणना JavaScript में
const totalOwed = totalTax - totalPayments की तरह संक्षिप्त दिख सकती है, लेकिन यह imperative शैली है, जिसमें sequential execution के बाद intermediate steps खो जाते हैं
- Dependency संबंध गहरे होने पर execution order की समस्या आती है:
getInput() जैसी user input function आगे की सारी गणना रोक सकती है, और spouse की मौजूदगी जैसी शर्तों के आधार पर पूछे जाने वाले सवाल भी बदलने चाहिए
- Social Security आय जोड़ने वाले लॉजिक में JavaScript के
map/reduce जैसी implementation details सामने आ जाती हैं, जबकि XML का <CollectionSum> सीधे टैक्स गणित की अवधारणा को व्यक्त करता है
<Dependency path="/socialSecuritySources/*/totalFederalTaxesPaid"/> से collection के भीतर के आइटम जोड़े जाते हैं
- Fact Dictionary declarative शैली अपनाती है: इसमें गणना के ठोस execution steps या order नहीं लिखे जाते, केवल named calculations और dependency relations लिखे जाते हैं, और इंजन खुद execution तरीका तय करता है
- Declarative tax model का सबसे महत्वपूर्ण लाभ auditability और introspection है: आप प्रोग्राम से पूछ सकते हैं, "यह संख्या कैसे निकली?"
- Imperative प्रोग्रामों में intermediate values पहले ही हट चुके होते हैं, इसलिए उन्हें केवल logs या debugger से ही देखा जा सकता है; अमेरिकी टैक्स क़ानून जैसे मामलों में, जहाँ सैकड़ों intermediate calculations होती हैं, यह scalable नहीं है
- Fact Graph के मूल लेखक Chris Given के अनुसार, Fact Graph "यह साबित करने का साधन" है कि जिन बातों के बारे में पूछा नहीं गया, उन्होंने टैक्स रिटर्न के परिणाम को नहीं बदला, और कि पात्र व्यक्ति को सभी उपलब्ध टैक्स लाभ मिल रहे हैं
- TurboTax बनाने वाली Intuit भी इसी निष्कर्ष पर पहुँची थी और उसने 2020 में "Tax Knowledge Graph" श्वेतपत्र प्रकाशित किया, लेकिन उसका implementation सार्वजनिक नहीं है
- IRS Fact Graph open source और public domain में है, इसलिए कोई भी इसका अध्ययन, साझा या विस्तार कर सकता है
XML, JSON की तुलना में DSL के लिए कहीं अधिक उपयुक्त क्यों है
- टैक्स क़ानून के declarative data representation format के रूप में JSON आज़माने पर arbitrary nested expressions को संभालना बहुत असुविधाजनक हो जाता है
- JSON की एकमात्र composite data structure object है, इसलिए हर child object को
"type", "kind" आदि के ज़रिए अपना प्रकार खुद बताना पड़ता है
- XML में टैग का नाम ही object type को दर्शाता है, इसलिए अलग से घोषणा की ज़रूरत नहीं होती
- उसी
/tentativeTaxNetNonRefundableCredits fact का JSON representation, XML की तुलना में, उल्टा और लंबा व अधिक जटिल हो जाता है
- XML में comments का समर्थन है, whitespace/line break handling भी उचित है, इसलिए JSON में आम तौर पर मानी जाने वाली असुविधाएँ यहाँ नहीं हैं
- Attributes और named child elements भाषा डिज़ाइन में किस बात पर ज़ोर देना है, यह चुनने की अभिव्यक्तिक क्षमता देते हैं
- "Dollar" और "Integer" जैसे custom data types परिभाषित किए जा सकते हैं
- लंबे explanatory text को संभालते समय XML, JSON की तुलना में, पढ़ने और manually edit करने में कहीं अधिक आरामदायक है
XML की सार्वभौमिकता और tool ecosystem
- S-expression, Prolog, KDL जैसी वैकल्पिक syntaxes XML से अधिक पठनीय हो सकती हैं, लेकिन XML अपनाने पर parser और general-purpose tool ecosystem मुफ़्त में मिल जाता है
- S-expression Lisp में, Prolog terms Prolog में अच्छे से काम करते हैं, लेकिन XML को किसी भी फ़ॉर्मेट में बदला जा सकता है
- Prolog में XML को Prolog terms में बदलना सिर्फ एक predicate से संभव है
- Hacker News उपयोगकर्ता ok123456 का "क्या Prolog/Datalog का उपयोग नहीं किया जा सकता?" सवाल भी उल्लेखित है; यह संभव है, लेकिन सार्वभौमिकता के मामले में XML आगे है
- Chris Given ने YAML के बारे में कहा कि "अमेरिकी टैक्स क़ानून के लॉजिक को YAML में व्यक्त करने की कोशिश कभी मत करना"
- XPath के उपयोग का एक वास्तविक उदाहरण: shell command की एक पंक्ति से fact paths को fuzzy search करना और चुने गए path की definition तुरंत देख लेने वाला script
cat facts.xml | xpath -q -e '//Fact/@path' | grep -o '/[^"]*' | fzf से fact search
- Dependency chain को उल्टी दिशा में ट्रेस करके यह देखना कि कौन-सा fact उस fact पर निर्भर है, यह सुविधा भी जोड़ी गई
- लगभग 60 लाइनों के bash script से यह लगभग रोज़ इस्तेमाल होने वाले debugging tool में बदल गया
- टीम के सदस्यों ने भी इसी तरह के तेज़ debugging tools अपने-अपने तरीके से बनाए, और सभी ने XML को मामूली स्तर पर parse करके Fact Graph की Scala implementation को छुए बिना अपनी पसंद की भाषा में काम किया
- मुख्य सीख: general-purpose data representation बहुत मूल्यवान है, और इस श्रेणी में केवल JSON और XML ही आते हैं
- ज़्यादातर मामलों में JSON चुनना चाहिए, लेकिन अगर DSL चाहिए तो XML सबसे सस्ता विकल्प है, और उसकी cost-efficiency की वजह से टीम अपना innovation budget दूसरी जगह खर्च कर सकती है
अतिरिक्त बातें
- यदि schema design अच्छा हो, तो non-programmer लोग भी XML पढ़ सकते हैं, हालांकि वैकल्पिक view अलग से बनाना बेहतर रहेगा
- हाल में XML के प्रति रुचि फिर बढ़ती दिख रही है: Jake Low का XML documents को flat line-oriented representation में बदलने वाला टूल
grex, और Martijn Faassen का Rust में बना आधुनिक XPath/XSLT engine Xee आदि
- TWE के facts withholding estimation के लिए हैं, इसलिए इन्हें सीधे टैक्स फाइलिंग में उपयोग नहीं करना चाहिए
अभी कोई टिप्पणी नहीं है.