36 पॉइंट द्वारा GN⁺ 2025-02-17 | 6 टिप्पणियां | WhatsApp पर शेयर करें
  • NASA के software development के 10 नियमों का आलोचनात्मक विश्लेषण
    • ये नियम अत्यंत महत्वपूर्ण embedded systems (जैसे spacecraft software) के लिए हैं
    • लेकिन यह चर्चा ज़रूरी है कि क्या ये नियम दूसरे development environments में भी उपयुक्त हैं, या दूसरी languages (C के अलावा) पर भी लागू किए जा सकते हैं

1. सरल control flow बनाए रखें (goto, setjmp/longjmp, recursion निषिद्ध)

  • यह नियम exception handling (setjmp()/longjmp()) और recursion को प्रतिबंधित करता है।
  • recursion अनिवार्य रूप से अक्षम नहीं होती। उचित तरीके अपनाने पर recursion में भी termination सुनिश्चित किया जा सकता है।
  • ज़बरदस्ती recursion को loop में बदलने से code के maintenance में कठिनाई बढ़ने का जोखिम होता है।

आलोचना:

  • termination की गारंटी महत्वपूर्ण है, लेकिन अत्यधिक प्रतिबंध readability और maintainability को नुकसान पहुँचा सकते हैं।
  • बिना शर्त recursion पर प्रतिबंध अनावश्यक जटिलता पैदा कर सकता है।

2. हर loop की स्पष्ट upper bound होनी चाहिए

  • compiler को loop iteration count का static analysis कर पाना चाहिए।
  • लेकिन केवल upper bound तय कर देने से वास्तविक execution time की गारंटी देना कठिन है।
  • recursion depth limit रखना, loop upper bound तय करने जितना ही सुरक्षित हो सकता है।

आलोचना:

  • सिर्फ upper bound होने से व्यावहारिक execution time की गारंटी नहीं मिलती।
  • अगर upper bound बहुत बड़ी हो, तो वह व्यवहार में infinite loop से बहुत अलग नहीं रहती।

3. initialization के बाद dynamic memory allocation निषिद्ध

  • embedded systems में memory सीमित होती है, इसलिए memory shortage से होने वाले crash को रोकना इसका उद्देश्य है।
  • लेकिन manual memory management की तुलना में predictable dynamic allocation अधिक सुरक्षित हो सकता है।
  • उदाहरण के लिए, real-time garbage collector (RTGC) का उपयोग करने पर dynamic allocation को भी predictable बनाया जा सकता है।

आलोचना:

  • dynamic allocation को पूरी तरह प्रतिबंधित करने के बजाय, memory usage patterns का analysis करके safety सुनिश्चित करना बेहतर तरीका हो सकता है।
  • आधुनिक static analysis tools (SPlint आदि) का उपयोग कर dynamic memory से जुड़ी त्रुटियाँ पहले ही पकड़ी जा सकती हैं।

4. function का आकार A4 कागज़ के एक पन्ने के भीतर सीमित हो (लगभग 60 lines)

  • तर्क यह है कि function बहुत लंबा हो तो readability घटती है।
  • लेकिन आधुनिक development environments में code folding जैसी सुविधाएँ हैं, इसलिए function length से अधिक logical unit का आकार महत्वपूर्ण है।

आलोचना:

  • भौतिक आकार (line count) के बजाय logical complexity को आधार बनाना चाहिए।
  • functions को छोटे-छोटे हिस्सों में बाँटना अपने आप में लक्ष्य नहीं होना चाहिए → इससे उल्टा maintenance कठिन हो सकता है।

5. हर function में कम से कम दो assert statements का उपयोग

  • assert debugging और documentation दोनों के लिए बहुत उपयोगी है।
  • लेकिन संख्या को बिना शर्त तय कर देना अक्षम हो सकता है।

आलोचना:

  • assert की संख्या से अधिक महत्वपूर्ण यह है कि data validation किन स्थानों पर ज़रूरी है, यह स्पष्ट हो।
  • सभी arguments और external inputs को validate करना अधिक व्यावहारिक है।

6. data objects का scope न्यूनतम रखें

  • local variables के उपयोग को बढ़ावा देने वाला यह एक अच्छा सिद्धांत है।
  • लेकिन केवल functions ही नहीं, types और functions के scope भी न्यूनतम होने चाहिए।

आलोचना:

  • Ada, Pascal, JavaScript और functional languages में types और functions भी locally declare किए जा सकते हैं → यह NASA नियमों से बेहतर दृष्टिकोण है।

7. function return values और parameters की validity check करना अनिवार्य

  • return values को अवश्य जाँचना चाहिए।
  • लेकिन हर स्थिति को check करना व्यवहार में कठिन है।

आलोचना:

  • runtime errors को रोकने के लिए जितनी संभव हो उतनी checks ज़रूरी हैं, लेकिन व्यावहारिक सीमाओं को भी ध्यान में रखना चाहिए।
  • विशेषकर C में return value checking महत्वपूर्ण है, लेकिन आधुनिक languages (Java, Rust आदि) में type system का उपयोग कर इसे अधिक सुरक्षित तरीके से संभाला जा सकता है।

8. preprocessor के उपयोग पर सीमा (केवल header include और simple macros की अनुमति)

  • complex macros, token pasting, variadic macros (...) निषिद्ध।
  • लेकिन variadic macros debugging tools के रूप में उपयोगी हो सकते हैं।

आलोचना:

  • preprocessor के उपयोग को सीमित करने से बेहतर है कि readable macro style को प्रोत्साहित किया जाए।
  • #ifdef जैसी conditional compilation को रोकने पर platform-independent code लिखना कठिन हो सकता है।

9. pointer उपयोग पर सीमा (double pointer निषिद्ध, function pointer निषिद्ध)

  • function pointers के उपयोग पर रोक → उद्देश्य उच्च स्थिरता प्राप्त करना है।
  • लेकिन function pointers callback, strategy pattern और device drivers में आवश्यक होते हैं।

आलोचना:

  • function pointers के बिना switch-case से function चुनने को मजबूर करने पर code readability घटती है और maintenance कठिन हो जाता है।
  • operating systems, network stacks और driver development में function pointers अनिवार्य हैं।
  • pointer restrictions की तुलना में pointer safety सुनिश्चित करने के तरीके (C++ smart pointers, Rust आदि) बेहतर समाधान हैं।

10. सभी code के लिए compiler warnings को अधिकतम स्तर पर सेट करें, और static analysis tools का उपयोग करें

  • यह नियम बहुत अच्छी recommendation है।
  • compiler warnings हटाना + static analysis tools का उपयोग = stability में सुधार।

आलोचना:

  • NASA के अन्य नियम (जैसे pointer प्रतिबंध, function size limit) का उद्देश्य केवल static analysis tools की सीमाओं को पार करना भी है।
  • लेकिन आधुनिक static analysis tools बहुत विकसित हो चुके हैं, इसलिए अत्यधिक प्रतिबंधों के बजाय अधिक परिष्कृत analysis techniques का उपयोग करना अधिक उपयोगी है।

6 टिप्पणियां

 
regentag 2025-02-18

ये सब रीयल-टाइम और embedded नज़रिए से देखें तो समझ में आने वाले और ज़रूरी नियम लगते हैं। क्या static analyzer इन नियमों की जगह ले सकता है?

उदाहरण के लिए, अगर dynamic allocation की अनुमति दी जाए, तो क्या यह गारंटी दी जा सकती है कि हर उपयोग परिदृश्य में memory allocation सफल होगा?

Software testing पढ़ते समय कुछ कथन ऐसे होते हैं जिनका ज़िक्र हमेशा पहले दिन के पहले घंटे में किया जाता है। उनमें से एक है, "पूर्ण testing असंभव है"।

 
smboy86 2025-02-18

लगता है कि मुझे उलटी बात ही ज़्यादा ध्यान खींचती है
इसलिए शायद ये नियम मेरे साथ फिट नहीं बैठते, हा हा

 
rtyu1120 2025-02-17

लगता है कि सिर्फ NASA ही नहीं, बल्कि aviation/automotive जैसे उन industries में भी, जहाँ ज़िंदगी सीधे दांव पर होती है, इसी तरह के coding rules अक्सर लागू किए जाते हैं haha

 
ssssut 2025-02-17

https://github.com/kubernetes/kubernetes/…
Kubernetes के source code में वह space shuttle style code block याद आ गया, जिसके बारे में कहा जाता है कि इसे NASA Space Shuttle application source code लिखने के तरीके में लिखा गया था।
संबंधित HN Thread: https://news.ycombinator.com/item?id=18772873

 
GN⁺ 2025-02-17
Hacker News राय
  • मूल लेख पढ़ने पर पता चलता है कि हर बिंदु का उद्देश्य समझाया गया है
  • मूल लेख मुख्य रूप से C भाषा पर केंद्रित है, और C में लिखे गए महत्वपूर्ण अनुप्रयोगों की विश्वसनीयता की अधिक कठोर जांच के लिए उसे optimize करने की कोशिश करता है
  • मूल लेखक को स्पष्ट रूप से पता है कि वह क्या कर रहा है, और वह C code को verify करने के कई तरीके समझाता है
  • मूल लेख में दिया गया तर्क पूरी तरह समझ में आता है
    • शायद इसलिए क्योंकि मैंने C छोटे systems पर सीखी थी
    • मैंने implant medical devices के hardware के लिए C सीखी थी, और lab में भी हमने इसी तरह के दिशानिर्देश अपनाए थे
  • आख़िरी पैराग्राफ़ शानदार है
    • नियम शुरुआत में कड़े लग सकते हैं, लेकिन उन स्थितियों पर विचार करना चाहिए जहाँ code की शुद्धता पर जीवन निर्भर हो सकता है
    • कार की seatbelt की तरह, यह शुरुआत में असुविधाजनक लग सकता है, लेकिन समय के साथ इसका उपयोग स्वाभाविक हो जाता है
  • इन नियमों पर मेरी आलोचना OP से काफ़ी अलग होगी
    • शुरू से ही setjmp/longjmp का बचाव करने वाली बात को गंभीरता से लेना मुश्किल था
    • इस pattern में, जिसने भी कभी इसे अपनाने की कोशिश की है, उसके लिए समस्याएँ साफ़ दिखाई देती हैं
    • लेख दावा करता है कि setjmp/longjmp exception handling है
    • और यह भी दावा करता है कि exception handling अच्छी है
    • दूसरी premise में गंभीर समस्या है
  • इसका मतलब है कि loop के लिए अधिकतम iteration count तय किया जाए
    • 10^90 मूर्खतापूर्ण है और अप्रासंगिक है
    • इस बिंदु के बाद मैंने लेख नहीं पढ़ा
  • अगर मैं नियमों की आलोचना करूँ, तो मैं इन बिंदुओं पर ध्यान दूँगा
    • function body की लंबाई का समझ की सरलता से कोई संबंध नहीं है, बल्कि यह नियम जिस बात का संकेत देता है उसका उल्टा भी हो सकता है
    • 2 assertions पूरी तरह मनमानी हैं, और जो कुछ assert किया जा सकता है, सब assert किया जाना चाहिए
    • Ada, Pascal (Delphi), JavaScript, या functional languages इस्तेमाल करने वालों को type और function declarations को जितना संभव हो उतना local रखना चाहिए
  • JavaScript में मेरा निजी तरीका यह है कि जब तक मैं स्पष्ट रूप से values capture नहीं करना चाहता, functions को nested तरीके से define नहीं करता
    • यह शायद पुराने mental model की वजह से है
    • performance profiling में दिखता था कि function हर call पर फिर से define होता है
    • मुझे नहीं लगता कि modern JavaScript interpreters अब भी ऐसे काम करते हैं
    • arrow functions आने के बाद काफ़ी गहरे optimization हुए होंगे
    • पुरानी आदतें आसानी से नहीं जातीं
    • named functions जो local variables capture नहीं करते, मैं उन्हें file/module scope में रखता हूँ
  • कई और टिप्पणियाँ दिलचस्प हैं और बहुत बारीक विवरण में जाती हैं
    • यह वैसा है जैसा पुराने engineers को पसंद आता है: "तकनीकी रूप से सही होना ही सबसे अच्छी सही बात है"
    • मुझे लगता है कि NASA rules जिस सावधानी का सामान्य tone देना चाहते हैं, वह बहुत अच्छा है, और मैं अधिकांश बातों का समर्थन करता हूँ
  • संदर्भ के अनुसार, ये "rules" से ज़्यादा सुझाई गई practices हैं
    • औपचारिक "rules" तो "NPR" जैसे नाम वाले documents में होते हैं
    • developers पर इन "rules" को मानने या न मानने की कोई बाध्यता नहीं है
  • GCC compile के बाद stack usage और caller-callee संबंध निकाल सकता है
    • setjmp() और longjmp() exceptions संभालने का खराब तरीका हैं
    • cleanup code execute नहीं होता
    • अगर नियमों की भावना का पालन किया जाए, तो ऐसे resources होने ही नहीं चाहिए जिन्हें cleanup की ज़रूरत पड़े
  • मुख्य समस्या हर application में अलग तरह से सामने आती है
    • अगर iteration limit पार हो जाए, या startup पर allocate किए गए fixed resources पर्याप्त न हों, तो क्या किया जाए
  • आजकल programmers code को screen पर पढ़ते हैं, इसलिए यह स्पष्ट नहीं है कि paper size अब भी क्यों relevant माना जाए
    • standard page और character size का बार-बार उल्लेख था
    • यह सिर्फ कागज़ की सीमाओं के कारण नहीं, बल्कि इंसानी सीमाओं के कारण भी है
  • recursion पर नियम का उद्देश्य ज़रूरी stack space की statically known boundary सुनिश्चित करना है
    • compiler पर निर्भर होने वाली आलोचना सही है, लेकिन runtime की upper bound निकालने के लिए यह एक पूर्वशर्त है
    • safety-critical systems में guaranteed response time चाहिए
  • शीर्षक में यह बताना चाहिए कि यह rules की आलोचना है
  • strict typing के इस्तेमाल की सिफारिश की जाती है
    • सभी scalar types के लिए strict typing
    • imperial units और metric units को मिलाना नहीं चाहिए
 
roxie 2025-02-21

शीर्षक से यह संकेत मिलना चाहिए कि यह नियमों की आलोचना है

222