10 पॉइंट द्वारा GN⁺ 2025-08-31 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • यह open source प्रोजेक्ट software development में cognitive load को कम करने के कई तरीकों और उदाहरणों को व्यवस्थित रूप से संकलित करता है
  • अनावश्यक रूप से जटिल code, structure, abstraction डेवलपर की उत्पादकता को घटाते हैं और maintenance cost बढ़ाते हैं
  • मॉड्यूल के लिए “छोटा और उथला” होने से अधिक simple interface और शक्तिशाली functionality वाली deep structure वांछनीय है
  • अत्यधिक abstraction, framework dependency, DRY principle का दुरुपयोग उल्टा cognitive load बढ़ाने का कारण बनते हैं
  • सबसे अच्छा architecture वह है जिसमें सरल codebase हो और नए डेवलपर भी उसे जल्दी समझ सकें

प्रोजेक्ट का सारांश और महत्व

यह GitHub open source सामग्री software development के प्रमुख सिद्धांतों में से एक, ‘cognitive load’ पर केंद्रित है। इस repository की सबसे बड़ी विशेषता यह है कि यह team size या technology trend से परे, डेवलपर जिन जटिलताओं का वास्तव में सामना करते हैं, उनके स्रोतों को विभिन्न उदाहरणों और समाधान तरीकों के साथ व्यवस्थित करती है। दूसरी best practice-केंद्रित सामग्रियों से अलग, यह मनोवैज्ञानिक और संज्ञानात्मक बोझ तक को ध्यान में रखती है, इसलिए maintenance और नए team member onboarding दोनों में व्यावहारिक रूप से अधिक उपयोगी है।

परिचय

  • development field में हम जिन trendy concepts या best practices के बारे में सुनते हैं, वे वास्तविक development में अक्सर असफल साबित होते हैं
  • वास्तविक कामकाजी माहौल में महसूस होने वाली उलझन और उससे होने वाले समय/लागत नुकसान का मूल कारण उच्च cognitive load है
  • डेवलपर code लिखने की तुलना में उसे समझने और पढ़ने में अधिक समय लगाते हैं
  • यह लेख खास तौर पर अनावश्यक cognitive load (Extraneous Cognitive Load) को कम करने के व्यावहारिक तरीकों पर केंद्रित है

cognitive load क्या है

  • cognitive load का अर्थ है वह सूचना-भार जिसे किसी task को पूरा करने के लिए डेवलपर को अपने दिमाग में बनाए रखना पड़ता है
  • औसतन, short-term memory में एक समय में लगभग 4 ‘chunks of information’ (जैसे condition, variable value आदि) ही रखे जा सकते हैं
  • जब cognitive load अपनी सीमा के पास पहुँचता है, तो समझने और development speed दोनों में बड़ी गिरावट आती है

cognitive load के प्रकार

  • Intrinsic cognitive load: task की अपनी मूल कठिनाई से उत्पन्न होता है। इसे कम नहीं किया जा सकता
  • Extraneous cognitive load: information presentation, structural design, अनावश्यक pattern जैसी कृत्रिम जटिलताओं से उत्पन्न होता है। इसे सक्रिय रूप से कम किया जा सकता है

व्यावहारिक उदाहरण और सुधार के तरीके

जटिल conditional statements

  • कई nested conditions वाला code हर चरण पर दिमाग में अधिक बातें याद रखने को मजबूर करता है, जिससे cognitive load बढ़ता है
  • समाधान: meaningful intermediate variables लाकर हर condition के उद्देश्य को स्पष्ट रूप से अलग करें

nested if बनाम Early Return

  • nested if की तुलना में Early Return pattern preconditions को याद रखने का बोझ कम करता है
  • इससे केवल ‘happy path’ याद रखना पर्याप्त होता है और working memory पर दबाव कम होता है

inheritance structure के दुष्प्रभाव

  • गहरी inheritance hierarchy (जैसे: Class A → Class B → Class C …) को समझने के लिए कई layer की जानकारी एक साथ याद रखनी पड़ती है, जिससे cognitive load बहुत बढ़ जाता है
  • समाधान: composition first, यानी अनावश्यक inheritance की जगह composition का उपयोग

बहुत अधिक उथले modules/functions

  • 80 छोटे और shallow classes की तुलना में कुछ शक्तिशाली और simple interface वाले deep modules को maintain करना अधिक आसान होता है
  • उदाहरण के तौर पर UNIX I/O का simple interface दिया गया है: open, read, write, lseek, close

'Single Responsibility Principle' की गलत व्याख्या

  • ‘सिर्फ एक काम करता है’ जैसी अस्पष्ट व्याख्या उल्टा shallow और अस्पष्ट abstractions की भरमार पैदा करती है
  • व्यवहार में इसे ‘एक stakeholder के प्रति उत्तरदायी है’ की तरह समझना चाहिए, ताकि business relevance की समझ बढ़े और cognitive load घटे

microservices का अति-उपयोग

  • बहुत अधिक shallow microservices होने पर हर service के संबंध और integration जानकारी दिमाग में बनाए रखनी पड़ती है, जिससे cognitive load तथा debugging/launch cost बढ़ती है
  • शुरुआती चरण में अच्छी तरह निर्मित monolithic structure maintenance के लिए अधिक लाभकारी हो सकती है

language features/options का अतिप्रयोग

  • language की अपनी बहुत-सी नई सुविधाएँ (खासकर C++ आदि में) डेवलपर को यह समझने में उलझा देती हैं कि implementation ऐसा क्यों किया गया, जिससे स्मृति-भार लगातार बढ़ता है
  • यह business से असंबंधित अतिरिक्त cognitive load को बढ़ावा देता है

HTTP status codes और business logic mapping

  • HTTP status codes (401, 403, 418 आदि) को मनमाने internal business meaning से map करने पर team के सभी सदस्यों को उन्हें याद रखना पड़ता है
  • सुधार: self-descriptive string codes (जैसे "jwt_has_expired") का लगातार उपयोग करें

DRY (Do not repeat yourself) principle का दुरुपयोग

  • जटिल codebase में यदि हर हाल में duplication हटाने की कोशिश की जाए, तो मजबूत dependencies बनती हैं और cognitive load व change cost उल्टा बढ़ जाते हैं
  • Rob Pike का प्रसिद्ध कथन उद्धृत है कि local स्तर पर ‘थोड़ी copy’ बेहतर हो सकती है

framework dependency और Layered Architecture के नुकसान

  • framework की ‘magic’ संरचना पर अत्यधिक निर्भरता होने पर नया डेवलपर internal logic समझने में बहुत समय लगाता है
  • abstraction layers का लगातार बढ़ना वास्तविक समस्या trace करते समय cognitive load को तेज़ी से बढ़ा देता है
  • मूल सिद्धांतों—Dependency Inversion, Info Hiding, Cognitive Load control—पर ध्यान देना चाहिए

Domain-Driven Design (DDD) की गलतफहमी

  • DDD का मूल सार problem domain analysis है; folder structure या patterns के प्रति आसक्ति उल्टा subjective interpretation और cognitive load बढ़ाती है
  • ‘Team Topologies’ जैसे framework cognitive load को विभाजित करने में अधिक प्रभावी हो सकते हैं

परिचितपन बनाम सरलता

  • परिचितपन, सरलता के बराबर नहीं है। कोई चीज़ सिर्फ इसलिए हल्की लग सकती है क्योंकि हम उसके आदी हैं; इसका मतलब यह नहीं कि उसकी वास्तविक structure सरल है
  • यदि नया कर्मचारी 40 मिनट से अधिक समय तक उलझन महसूस करे, तो यह code improvement की ज़रूरत का संकेत है

वास्तविक सफलता/विफलता के उदाहरण

  • Instagram जैसे उदाहरण दिखाते हैं कि सरल monolithic architecture के साथ भी उच्च scalability और maintenance हासिल की जा सकती है
  • जिन कंपनियों में “बहुत स्मार्ट डेवलपर” ने अत्यधिक जटिल structure बनाई, वहाँ विफलता के अनुभव अधिक देखे गए
  • ऐसा structure जिसमें हर डेवलपर आसानी से पढ़ सके और जल्दी onboard हो सके, productivity बढ़ाने में केंद्रीय भूमिका निभाता है

निष्कर्ष

  • मूल कार्य से परे जाने वाला अनावश्यक cognitive load सभी development stakeholders के लिए हानिकारक है
  • सबसे अच्छा code वही है जिसे भविष्य में कोई दूसरा डेवलपर और आप स्वयं सबसे जल्दी समझ सकें
  • “स्मार्ट दिखने” वाली structure की तुलना में साधारण और सीधे समाधान long-term maintenance और team productivity के लिए अधिक लाभकारी होते हैं

संदर्भ/टिप्पणियाँ

  • Rob Pike, Andrej Karpathy, Elon Musk, Addy Osmani, antirez (Redis डेवलपर) सहित कई प्रसिद्ध डेवलपर्स के विचार उद्धृत किए गए हैं
  • Chromium, Redis, Instagram जैसे बड़े वास्तविक उदाहरणों से मेल खाते संकेत प्रस्तुत किए गए हैं
  • सरलता, स्पष्टता और cognitive load में कमी ही software sustainability का मूल है

इस open source प्रोजेक्ट का मूल्य

  • अनेक software design पुस्तकों और patterns से छूट जाने वाले वास्तविक डेवलपर अनुभव और व्यावहारिक उदाहरणों पर केंद्रित सामग्री
  • developer onboarding, architecture review, long-term maintenance जैसी विभिन्न team स्थितियों में तुरंत उपयोगी व्यावहारिक मदद प्रदान करती है
  • ‘cognitive load’ जैसे स्पष्ट framework के माध्यम से code को दोबारा परखने के लिए checklist की भूमिका निभाती है

1 टिप्पणियां

 
GN⁺ 2025-08-31
Hacker News राय
  • John Ousterhout की किताब A Philosophy Of Software Design से मुझे सबसे बड़ी समझ मिली; इस विषय पर यह सबसे बेहतरीन किताब है, इसलिए मैं हर डेवलपर को इसे पढ़ने की ज़रूर सलाह दूँगा। इसका मूल विचार यह है कि software design का लक्ष्य complexity को न्यूनतम करना होना चाहिए, और यहाँ complexity का मतलब है 'बदलाव करना कितना कठिन है'। यह 'कठिनाई' इस बात से तय होती है कि कोड को समझने में कितनी cognitive load लगती है

    • समस्या यह है कि कोई भी नियम अंततः judgement, अनुभव और intuition की जगह नहीं ले सकता। हर नियम बहस का हथियार बन सकता है, और architecture बहसों में आप कभी नहीं जीतते। यह लेख इसलिए अच्छा है क्योंकि जिन्हें इसकी ज़रूरत नहीं, वे पहले से जानते हैं, और जिन्हें सच में ज़रूरत है, वे इसे समझेंगे नहीं। आखिरकार यह तकनीकी नहीं, बल्कि लोगों और culture की समस्या है। architecture अंततः लोगों और culture से ही निकलता है। जैसे Rob Pike और Google होने पर Go आया; सिर्फ एक किताब पढ़ लेने से Go जैसी भाषा पैदा नहीं हो जाती

    • मेरा मानना है कि DRY सिद्धांत (दोहराव से बचो) पर तभी विचार करना चाहिए जब आप application को अच्छी तरह समझ चुके हों और उसके कई version बना चुके हों। शुरुआत में तो दोहराते हुए पहले problem space को समझना चाहिए, फिर दूसरे version में maintainability पर सोचना चाहिए। मेरे हिसाब से तीसरे version के आसपास जाकर ही DRY लागू करना ठीक है

    • Jeff Bezos को पैसे दिए बिना यह किताब हासिल करना बहुत मुश्किल है। अगर कोई लेखक John को जानता हो, तो कृपया उन्हें यह समस्या ज़रूर बताए। यह campus bookstore में भी नहीं मिली, और local bookstore या Powell’s में भी नहीं मिल पाई

    • मैंने बहुत पहले perfect software solution खोजने की उम्मीद छोड़ दी। मुझे नहीं लगता किसी ने सब कुछ पूरी तरह व्यवस्थित किया है। अंत में हमारे पास सबसे बड़ा हथियार लोगों की समझ और अनुभव ही है। context, industry और team इतनी अलग होती हैं कि इसे किसी संख्या या नियम से ठीक-ठीक परिभाषित नहीं किया जा सकता। अब design में मेरा लक्ष्य 'अव्यवस्था' और 'सुंदरता' के बीच संतुलन ढूँढना है। सबसे कठिन बात यह थी कि business अनिश्चित होता है, जबकि software deterministic होता है; business requirements लगातार बदलती रहती हैं और उन्हें computer system की कठोरता में फिट करना मुश्किल है। आजकल मैं तभी refactoring करने की कोशिश करता हूँ जब कोड बदलते समय असली असुविधा महसूस हो। तब भी सिर्फ न्यूनतम सफाई करता हूँ। इस तरह बार-बार की गई incremental refactoring से नए pattern उभरते हैं, और फिर कभी-कभी उन्हें abstraction में निकाला जा सकता है

    • इस विषय पर यही किताब सबसे अच्छी है। वह लेख भी इसी किताब से प्रेरित था। लेखक John से भी इस विषय पर एक-दो बातें हुई थीं

  • ऐसा कोड लिखने की क्षमता जो दूसरों की cognitive load कम करे, बहुत दुर्लभ और कठिन skill है। क्षमता होने पर भी इसमें लगातार मेहनत करनी पड़ती है। अंततः डेवलपर का काम मुख्य विचारों को compress करके सार को सामने लाना और केवल अनिवार्य complexity को उजागर करना है। सच कहूँ तो ऐसा अच्छे से करने वाले बहुत कम दिखते हैं

    • सचमुच अच्छा लिखा गया कोड लोगों को यह सोचने पर मजबूर कर देता है, 'क्या यह समस्या शुरू से ही इतनी आसान थी?' दूसरी ओर, वह codebase जो अपनी complexity खुलकर दिखाता है, जैसे 'ताश के पत्तों का घर', अक्सर मेहनत के निशान के रूप में पहचाना जाता है और promotion तक दिला देता है

    • यही बात interface और UX/interaction design पर भी लागू होती है। डेवलपर आम लोगों की तुलना में cognitive load को बहुत बेहतर संभाल लेते हैं, लेकिन non-technical लोगों के लिए चीज़ें आसान बनानी हों तो डेवलपर को अपनी ही intuition से बाहर निकलना पड़ता है, और यही इसे बहुत कठिन बनाता है। ऐसे tool design करना जिनसे आम user जटिल समस्याएँ सहज रूप से हल कर सके, सच में बहुत मुश्किल है

    • ज़्यादातर abstraction requirement बदलने पर टिक नहीं पाते। मुझे वे framework पसंद हैं जो यह समझते हैं कि हमेशा के लिए परफेक्ट abstraction layer बनाना संभव नहीं, इसलिए वे जानबूझकर 'escape hatch' देते हैं। (जैसे web UI framework में html element का direct reference देना) भविष्य को पूरी तरह predict न कर पाने की विनम्र समझ महत्वपूर्ण है

    • असल में यह skill बहुत-सी कंपनियों में अनिवार्य कम, bonus ज़्यादा है। बड़े codebase देखकर यह आसानी से समझ में आ जाता है

  • मैं खुद को 'अजीब लेकिन smart डेवलपर' श्रेणी में मानता हूँ। मुझे abstraction बनाना पसंद है। इसलिए आजकल industry का 'if-statement के ढेर वाली architecture' की ओर लौटना मुझे अजीब भी लगता है और चिंताजनक भी। यह ऊपर से simple दिखता है, समझने में आसान होता है, और बस दिए गए ticket बंद करने होते हैं, इसलिए लोगों को यह क्यों पसंद आता है, मैं समझ सकता हूँ। अधिकतर development process इसी if-statement के ढेर पर निर्भर हैं, और एक सीमा तक यह सच में काम भी करता है। यहाँ तक कि बड़े पैमाने पर personal data leak जैसी घटनाएँ हो जाएँ, तब भी बहुत कम लोग जवाबदेह ठहरते हैं। लेकिन समस्या यह है कि मुझे नहीं पता इससे बेहतर विकल्प है भी या नहीं। चमकदार abstraction या शानदार architecture भी शायद code consistency को वास्तव में नहीं बढ़ाते। खासकर enterprise माहौल में, जहाँ business logic के मालिक स्वयं logic पर बहुत कम ध्यान देते हैं, वहाँ सावधानी से सुंदर abstraction बनाना लगभग असंभव हो जाता है। आज requirement है कि 'ऑर्डर सिर्फ एक address पर डिलीवर होगा', और कल अचानक 'बड़े ग्राहक ने कई address पर डिलीवरी माँगी' जैसी बात आ जाती है। ऐसे chaos में bug-free abstraction का अस्तित्व ही मुश्किल लगता है। कभी-कभी तो लगता है कि enterprise software में if-statement का ढेर ही शायद सबसे व्यावहारिक विकल्प है

    • 'क्या if-statement का ढेर सबसे अच्छा है?' इस सवाल पर, मैं वास्तविक बड़े software architecture पर लिखे Big Ball of Mud paper और इस सारांश पोस्ट की सिफारिश करता हूँ। वास्तविक सिस्टम हमेशा evolve करते हैं; शुरुआत में वे 'कीचड़ के गोले' जैसे होते हैं, फिर हिस्सों में सुधारे जाते हैं, और फिर बदलाव आते ही पहले की सुंदर abstraction फिर टूट जाती है। बात यह है कि system को ऐसे बढ़ाना चाहिए जैसे कोई छोटा कस्बा शहर बनता है—domain modeling, उचित abstraction, और ज़रूरत पड़ने पर disruptive बदलावों के मिश्रण के साथ

    • ऐसे software में भी बेहतरीन abstraction बनाई जा सकती है, लेकिन business logic आते ही उन्हें बनाए रखना कठिन हो जाता है। जिन हिस्सों में abstraction अपेक्षाकृत सही-सलामत रहती है, वे आमतौर पर product-जैसे हिस्से होते हैं, जैसे authentication, authorization, logging, database, middleware, infrastructure आदि। जैसे ही आंतरिक business logic abstraction को प्रभावित करने लगती है, चीज़ें फिर बिखर जाती हैं। कहीं-कहीं तो business लोगों को ही logic संभालने दिया गया, और नतीजा यह हुआ कि testing मुश्किल, समझना असंभव, यहाँ तक कि simulation भी संभव नहीं रहा। अंततः operator की ज़रूरत पड़ी, और junior developer को graphical tool से code लिखना पड़ा। कई बार rewrite करने के बाद भी 2-3 साल में सब फिर बेतरतीब हो जाता है

    • business लोग business logic को implement करने वालों को पूरी तरह समझा ही नहीं सकते। वे खुद समझते हों, फिर भी coding के नज़रिए से उसे व्यक्त नहीं कर पाते। उल्टा, implementer में कम-से-कम एक व्यक्ति ऐसा होना चाहिए जो user अनुभव को भीतर तक जी चुका हो। लेकिन वास्तविकता में कंपनियाँ विभागीय विभाजन थोपती हैं, और 'business logic' एक ऐसी जगह बन जाती है जहाँ कोई वास्तव में ध्यान नहीं देता; अंत में सिर्फ if-statement इधर-उधर किए जाते हैं

    • असली मुद्दा यह है कि वास्तविक दुनिया, यानी business itself, पहले से ही if-statement का ढेर है। अगर समस्या या domain स्पष्ट रूप से तकनीकी हो या generalize की जा सकती हो, तो abstraction से if-statement कम किए जा सकते हैं; लेकिन अगर domain खुद chaos है, तो abstraction में भी 'flexibility' को आधार बनाना ही पड़ेगा। कभी-कभी contradiction भी एक feature बन जाती है

    • अगर आप Codex CLI जैसे tools से खेलें, तो देखेंगे कि bug मिलने पर यह tool लगभग हमेशा किसी खास case के लिए if-statement patch बना देता है। जब तक आप इसे खुद pattern न बताएँ और नई abstraction न माँगें, यह लगातार 'heuristic' कहे जाने वाले if-statement जोड़ता रहता है। किसी खास प्रकार के 10 bug पर 10 patch बन जाते हैं, और 11वाँ मिलता-जुलता bug आते ही वह स्वाभाविक रूप से काम नहीं करता। Codex जो solution देता है, वह if-statement की पुनरावृत्ति का ढेर होता है

  • मुझे संदेह है कि पूरी तरह अनजान project में जाकर modification माँगे जाने वाली स्थिति वास्तविक दुनिया में कितनी आम है। अगर आप project बहुत बार नहीं बदलते, तो शायद दो साल में एक बार। मुझे लगता है कि अनुभव की कमी वाली नहीं, बल्कि सचमुच कठिन समस्याओं पर ध्यान देना अधिक बेहतर है

  • Microsoft की developer organization में 8 साल काम करते हुए, शुरुआती engineer-type modeling बहुत उपयोगी रही। तीन persona थे, जिन्हें बाद में अधिक जटिल framework ने replace कर दिया। फिर भी मूल persona आज तक मेरे करियर में दूसरे engineers से प्रभावी ढंग से संवाद करने में बहुत मददगार रहे हैं।

    • Mort: व्यावहारिक engineer, business result सर्वोपरि। if-statement का ढेर भी चलेगा अगर वह जल्दी काम कर दे।
    • Elvis: innovation पहले, latest tech का उपयोग, और चाहता है कि उसकी प्रतिभा सबको दिखे। नए framework लाना, unstable code, visibility और innovation के प्रति आसक्ति।
    • Einstein: performance, elegance और technical correctness के प्रति आसक्त। code consistency और तकनीकी पूर्णता को अधिक महत्व देता है। वास्तविकता में हर engineer इन तीनों का मिश्रण होता है। कुछ PR और design review देखकर उसकी प्रमुख प्रवृत्ति का मोटा अंदाज़ा लगाया जा सकता है
    • मुझे लगता है कि इसमें Amanda नाम की एक और engineer-type भी होनी चाहिए। 20 साल तक अपनी और दूसरों की उलझी हुई codebase की review करने के बाद, अब उसने यह भीतर तक समझ लिया है कि code सबसे पहले इंसानों के पढ़ने के लिए होता है। मैं तो चाहूँगा कि पूरी team सिर्फ ऐसी Amanda लोगों से बनी हो

    • Mort व्यावहारिक है, Einstein परफेक्शनिस्ट है, और Elvis... सच कहूँ तो project के लिए हानिकारक तत्व जैसा है। थोड़ी motivation देता है, लेकिन आदर्श team वह है जिसमें Mort और Einstein का सही मिश्रण हो। ज़रूरत भर की simplicity और पर्याप्त correctness दोनों चाहिए, ताकि maintenance कष्टदायक न बने। दिलचस्प बात यह है कि अगर Mort को किसी long-term project पर छोड़ दिया जाए, तो वह भी एक समय बाद Einstein की तरह सोचने लगता है। वैसे, हाल के automatic coding agents इतने ज़्यादा Mort-जैसे हैं कि अब मुझे खुद Mort बनकर उन्हें manage करना पड़ता है

    • persona एक अच्छा tool है। लेकिन मेरे अनुभव में समय के साथ यह गलत shortcut बन जाता है। Elvis वास्तव में आंतरिक politics का शब्द था, और Goodhart's law की तरह, क्योंकि यह तर्कसंगत लगता था, हर कोई इसे बहस में इस्तेमाल करने लगा और इसकी उपयोगिता घटती गई। Alan Cooper ने बहुत पहले Visual Basic development के साथ persona की अवधारणा पेश की थी। यह समझना महत्वपूर्ण है कि मेरे से अलग दृष्टिकोण वाले लोग—जैसे scientist और firmware developer—अलग मूल्य-प्रणालियाँ रखते हैं। संबंधित पुस्तक

    • मेरे हिसाब से सबसे अच्छे engineer वे हैं जो इन तीनों प्रवृत्तियों को project, परिस्थिति और व्यक्तिगत लक्ष्य के अनुसार समायोजित कर सकते हैं। भूमिका के अनुसार इनका अनुपात बदलता है। उदाहरण के लिए compiler optimization में Einstein और Mort अधिक उपयोगी होते हैं, जबकि game engine जैसे code में अनुपात अलग हो सकता है। इन विशेषताओं की सटीकता पर बहस हो सकती है, लेकिन मूल बात यह है कि हर किसी को समय और संदर्भ के अनुसार अलग ढंग से काम करना चाहिए

    • मुझे लगता है इस तरीके में सीमाएँ तय होनी चाहिए। लोगों को बहुत सरल श्रेणियों में बाँटना अन्यायपूर्ण और स्थायी stigma बन सकता है। मेरे अनुभव में management अक्सर Elvis से ज़्यादा Mort को पसंद करती है। असली समाधान leadership और management में है। अगर Mort के requirement में code quality standard भी शामिल कर दिए जाएँ, तो वह थोड़ा धीमा सही, ठीक-ठाक नतीजा देगा। Elvis को सीमाएँ चाहिए, और Einstein लोगों के लिए practical deadline condition साफ़-साफ़ बतानी चाहिए। इस तरीके की सीमा यह है कि यह मानव जटिलता को पर्याप्त रूप से नहीं पकड़ता

  • मुझे चिंता है कि AI software industry के लिए हानिकारक साबित हो सकता है। AI में मानवीय सीमाएँ नहीं हैं, इसलिए वह बेहद जटिल, पढ़ने में कठिन लेकिन चलने वाला code लिख सकता है, और जब वह आखिरकार टूटेगा, तब शायद कोई उसे ठीक नहीं कर पाएगा। इसलिए मैं junior engineers को सलाह देता हूँ कि AI पर ही निर्भर न रहें, बल्कि codebase की प्रकृति को समझें। नहीं तो वे खुद code लिख पाने की क्षमता खो देंगे

    • मुझे यह तर्क प्रभावी नहीं लगता, क्योंकि AI अगर काम करना बंद भी करे, तो उसे फिर से ठीक कराया जा सकता है

    • मेरे अनुभव में, मैं AI से तब तक code को simplify करने के लिए कहता रहता हूँ जब तक मैं उसे पूरी तरह समझ न लूँ। अगर वह तरीका जटिल हो, तो और आसान बनवाता हूँ; अगर बेकार की external library इस्तेमाल करे, तो उसे हटवाता हूँ; stdlib से करने को कहता हूँ या सिर्फ पहले से मौजूद dependency इस्तेमाल करने देता हूँ। AI मेरे लिए code लिख रही है, अपने लिए नहीं

    • उल्टा, AI की वजह से low-level design की cognitive load कम हो सकती है, जिससे हम higher-level architecture पर ज़्यादा ध्यान दे सकें; इसलिए software quality बेहतर भी हो सकती है

  • लेख में जिस 'smart developer की विशिष्ट आदत' का ज़िक्र है, उससे ऐसा लगता है मानो लेखक सिर्फ वही code समझ सकता है जो उसने खुद लिखा हो या उसके अपने style में लिखा गया हो। लेकिन cognitive load कम करने का असली रहस्य यह है कि पढ़ने लायक code की मात्रा कम से कम की जाए। मजबूत boundary और स्पष्ट API बदलाव करना आसान बनाते हैं; बात पूरे code की नहीं, बल्कि अच्छी तरह परिभाषित interface से निकली complexity की है जिस पर ध्यान देना पड़ता है। 'smart developer' की विशेषता शायद सिर्फ सतही समस्या है

    • microservices की अवधारणा का सबसे बड़ा लाभ यही है। अगर दो team केवल API के माध्यम से संवाद करें, और schema जैसे tools से boundary को सख्ती से परिभाषित किया जाए, तो लोग बदलाव के प्रति बहुत conservative हो जाते हैं और पहले से गहराई से सोचते हैं। मुझे यह उस जगह पर तकनीकी रूप से कृत्रिम friction जोड़ने जैसा लगता है जहाँ आप चाहते हैं कि चीज़ें आसानी से न बदलें

    • debugging करते समय मैंने अक्सर महसूस किया है कि call stack पर सीधे debug किए जाने वाले code में अगर बहुत ज़्यादा optimization ठूँस दी गई हो, तो वह बेहद थकाऊ होता है। इसलिए किसी खास हिस्से को function में निकालकर और commits अलग रखकर, अनचाहे code change को rollback करना आसान हो जाता है और code पर focus भी बेहतर रहता है। PR में भले सब एक साथ दिखे, लेकिन स्पष्ट boundary फिर भी बहुत मदद करती है

    • डेवलपर आम तौर पर 'contract और interface' के रूप में सोचना अच्छी तरह नहीं सीखते। उन्हें implementation details नहीं, बल्कि बाहर दिखाई देने वाले promise देखने चाहिए। लक्ष्य यह होना चाहिए कि code पढ़े बिना भी समझ आ जाए। अगर किसी को मेरा code समझने के लिए उसके अंदर उतरना पड़े, तो वह मेरी असफलता है

    • API चाहे जितना स्पष्ट हो, अंदरूनी code फिर भी आसानी से समझ में न आए, ऐसा हो सकता है। बाहर से सब ठीक काम करता दिखे, फिर भी कई बार उसके भीतर तक जाना पड़ता है

  • यह लेख मेरे अनुभव को बहुत अच्छी तरह समेटता है, इसलिए मुझे यह बहुत पसंद आया। जो अधिकतर programming methodology मैंने औपचारिक रूप से सीखी, वे तब उल्टा असर करती हैं जब किसी और को मेरा code पढ़ना पड़ता है। Rust और C++ की तरह अत्यधिक छिपाव वाला code कठिन लगता है; जबकि C जैसी संरचना, जहाँ template की छह परतों में code नहीं छिपाया जा सकता, उसे देखकर उल्टा राहत मिलती है

    • यह सुनकर अच्छा लगा कि यह तुम्हारे अनुभव से मेल खाता है। मुझे भी इसी कारण C पसंद था, और हाल में मैं Golang की ओर गया हूँ क्योंकि उसकी सादगी मुझे अच्छी लगती है
  • code accessibility को first-class concern की तरह लेना चाहिए—यह बात सच में असर करती है। नियमों को guideline की तरह लेना चाहिए, और असली कुशलता इस बात में है कि code को पढ़ने योग्य रखने के लिए संदर्भ के अनुसार कब नियम तोड़ना है या कब उन्हें पूरक बनाना है। आखिरकार code की cognitive load और trade-off को सहज रूप से पहचानने की क्षमता महत्वपूर्ण है। duplication हो या abstraction, हमेशा अगले व्यक्ति—जिसमें 6 महीने बाद वाला मैं भी शामिल हूँ—को ध्यान में रखना चाहिए। 'एक और नियम बना दो' की माँग अपने-आप में वही समस्या दोहराती है। बुनियादी guideline के बाद सब tacit knowledge होता है, यानी अनुभव से आने वाला अव्यक्त ज्ञान। समय के साथ आप खुद महसूस करने लगते हैं कि कौन-सा code अच्छा है और कौन-सा बुरा। अंततः इसे महसूस करना ही पड़ता है

    • मैं code accessibility के मूल विचार से सहमत हूँ, लेकिन अफ़सोस है कि लेखक ने germane overhead (ग्राहक/पाठक की cognitive resource खपत) को नज़रअंदाज़ किया। अंततः code accessibility बढ़ाने के लिए intrinsic, extraneous और germane—तीनों तरह के overhead को ध्यान में रखना चाहिए
  • अक्सर कहा जाता है कि "क्यों" को document करो, लेकिन मुझे "क्यों" और "क्या" को अलग करना कठिन लगता है, इसलिए मैं दोनों लिखता हूँ। सबसे खराब comment कुछ ऐसा होता है:

    x = 4 // assign 4 to x 
    

    इस तरह code और comment को मिलाने से पढ़ना मुश्किल हो जाता है और context switch बहुत होता है। इसकी जगह

    // यह क्यों कर रहे हैं, और क्या होने वाला है
    setup();
    t = setupThing();
    t.useThing(42);
    t.theWidget(need=true);
    ...
    

    इस तरह comment और code को साफ़-साफ़ अलग करना बेहतर है। फिर भी, सिर्फ "क्या" लिखना भी कुछ न लिखने से बेहतर है और cognitive load कम करता है

    • इस तरह के comment ज़्यादातर maintain करना मुश्किल होते हैं, और implementation साल में पाँच बार भी बदल सकती है, इसलिए वे जल्दी पुराने होकर भ्रम पैदा करते हैं। हाल के project में मैंने सिर्फ सचमुच कठिन logic और top-level documentation छोड़ी, बाकी अधिकांश comment हटा दिए

    • मुझे लगता है कई बार दोनों चीज़ें (why/what) document करनी पड़ती हैं। कभी कारण स्पष्ट करना ज़रूरी होता है, कभी व्यवहार। आजकल मुझे लगता है कि comments की value को कम आँका जाता है। हर line पर comment लगाने की ज़रूरत नहीं, लेकिन अधिकांश 'self-documenting code' भी उतना पढ़ने योग्य नहीं होता

    • आजकल मुझे सबसे कठिन यही तय करना लगता है कि क्या code में रहना चाहिए और क्या design doc/technical doc में। मेरा निष्कर्ष यह है कि code के अंदर comment का उपयोग non-intuitive या hidden intent समझाने के लिए करना चाहिए। उदाहरण: "इसे memoize करने का कारण X है"

    • ChatGPT-शैली वाले x=4 comment पर हँसी आ गई। लेकिन आपके सुझाए गए तरीके की कमी यह है कि comment पुराने होकर code से mismatch हो सकते हैं। जब code बदलें, तो comment भी ज़रूर अपडेट करने चाहिए

    • मैं पेशे से programmer नहीं, बल्कि physicist हूँ, इसलिए comment लिखते समय अब मैं कोशिश करता हूँ कि उन्हें इसी तरीके से ढालूँ। छात्र जीवन में अच्छे grades के लिए बहुत सारे comment लिखना लगभग अनिवार्य प्रथा थी