1 पॉइंट द्वारा GN⁺ 2025-01-12 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Makefile प्रभाव उस पैटर्न को दर्शाता है जिसमें किसी जटिल या अपरिचित टूल को शुरू से इस्तेमाल करने के बजाय, पहले से अच्छी तरह काम कर चुकी सेटिंग को कॉपी करके नई स्थिति के अनुसार बदला जाता है
  • समस्या हल करने के चरण में, सत्यापित उदाहरणों का पुन: उपयोग करने से बग का जोखिम घट सकता है, इसलिए यह एक तर्कसंगत इंजीनियरिंग प्रतिक्रिया हो सकती है
  • लेकिन डिज़ाइन के नज़रिए से, इसे usability signal माना जा सकता है कि टूल को शुरू से इस्तेमाल करना कठिन या झंझटभरा है, इसलिए कॉपी किए गए संस्करणों पर बदलाव लगातार जमा होते रहते हैं
  • Make के अलावा GitHub Actions, GitLab CI/CD, लिंटर·फॉर्मैटर सेटिंग्स, और build systems में भी ऐसा ही कॉपी-और-संशोधन वाला प्रवाह दिखाई देता है
  • टूल डिज़ाइनरों को जांचना चाहिए कि configuration और अपनी अलग syntax वास्तव में ज़रूरी हैं या नहीं, क्या परिचित CLI idioms को दोबारा इस्तेमाल किया जा सकता है, और क्या उपयोगकर्ता कॉपी-पेस्ट पर निर्भर होने के लिए मजबूर हो रहे हैं

Makefile प्रभाव क्या है

  • Makefile प्रभाव वह स्थिति है जिसमें कुछ हद तक जटिल या अपरिचित टूल के लिए नई फ़ाइल शुरू से लिखने के बजाय, पहले की किसी “अच्छी तरह काम कर चुकी” मिसाल को कॉपी करके उसमें बदलाव किया जाता है
  • इसका सामान्य प्रवाह कुछ इस प्रकार है
    • किसी सामान्य प्रकार का काम पूरा करना होता है, और बहुत मिलता-जुलता या वही काम पहले कभी किया जा चुका होता है
    • Make या उससे मिलता-जुलता कोई टूल उस काम के लिए चुना जाता है
    • इंजीनियर नया Makefile लिखने के बजाय, पिछले काम का Makefile कॉपी करता है और उसे तब तक ठीक करता है जब तक वह नए environment में चलने न लगे
  • Make सिर्फ एक प्रमुख उदाहरण है; टीम या व्यक्ति के अनुसार महारत वाले टूल अलग-अलग होते हैं, इसलिए कुछ टूल परिवार इस प्रभाव के प्रति अधिक संवेदनशील होते हैं और कुछ अपेक्षाकृत कम
  • “heritage Makefile” वाला मज़ाक उस स्थिति की ओर इशारा करता है जहाँ किसी senior engineer, professor आदि से मिला Makefile केवल छोटे-मोटे बदलावों के साथ पीढ़ी-दर-पीढ़ी चलता रहता है

बार-बार की कॉपी से उजागर होने वाली टूल डिज़ाइन समस्याएँ

  • जब समस्या को तुरंत हल करना हो, तब काम करने वाले उदाहरण का पुन: उपयोग एक संक्षिप्त और व्यावहारिक विकल्प हो सकता है
    • ज़्यादातर हिस्सा नहीं बदलता, इसलिए सिद्धांततः नए बग कम पैदा हो सकते हैं
    • Makefile प्रभाव अपने आप में न तो बुरा है और न ही अनिवार्य रूप से अक्षम
  • लेकिन डिज़ाइन के स्तर पर यह संकेत देता है कि टूल, या टूल को लागू करने का तरीका, बहुत जटिल या बोझिल है
    • उपयोगकर्ता समस्या को शुरू से हल करने के बजाय, मौजूदा समाधान को बार-बार कॉपी करते हैं
    • अगर साधारण उपयोग मामलों में भी यह प्रभाव दिखाई दे, तो उस प्रयोजन के लिए टूल शायद जरूरत से ज़्यादा जटिल है
  • यह पैटर्न Make के बाहर, दूसरे configuration-केंद्रित टूल्स में भी दिखता है
    • CI/CD configuration में GitHub Actions या GitLab CI/CD की YAML को आख़िरी बार काम कर चुकी configuration से कॉपी करके बार-बार चलाया और सुधारा जाता है
    • लिंटर और फॉर्मैटर की settings में base rules के समूहों को अलग-अलग projects के बीच कॉपी किया जाता है, फिर local conditions के हिसाब से उन्हें सख्त या ढीला किया जाता है
    • build systems की गैर-तुच्छ configuration अक्सर पिछले build system जैसी बनने लगती है

सीखने, debugging और security पर पड़ने वाली लागत

  • जिन टूल्स में Makefile प्रभाव बहुत मज़बूत होता है, वे व्यापक सीखने में बाधा बन सकते हैं
    • कुछ ही skilled लोग टूल को configure करते हैं, और बाकी लोग सिर्फ ज़रूरत भर समझ के साथ कॉपी करके बदलाव करते हैं
    • build system का dependency graph अपनी प्रकृति से जटिल हो सकता है, लेकिन Make में $< और $^ का अंतर याद रखना ऐसी अनिवार्य जटिलता नहीं है
  • अगर diagnostics और debugging support कमज़ोर हो, तो उपयोगकर्ता टूल को बार-बार चलाकर छोटे-छोटे संकेत इकट्ठा करने की पद्धति पर निर्भर हो जाते हैं
    • CI/CD में अक्सर network और बीच के VM orchestration layers से होकर print-आधारित debugging करनी पड़ती है
  • security के दृष्टिकोण से भी जोखिम बढ़ सकता है
    • सुरक्षा उपायों के लिए अक्सर इस बात की गहरी समझ चाहिए होती है कि कुछ काम “क्यों” हो रहा है
    • जिन systems में Makefile प्रभाव दिखाई देता है, वे अक्सर code और data के बीच भ्रम, या सामान्य in-band signaling के भ्रम की अनुमति देते हैं
    • GitHub Actions में template injection इसका एक प्रतिनिधि उदाहरण है

टूल डिज़ाइनरों को कौन से प्रश्न देखने चाहिए

  • नया टूल बनाते समय यह देखना चाहिए कि क्या उपयोगकर्ता उसे शुरू से लिख सकते हैं, या उन्हें “काम करने वाला उदाहरण” ढूँढकर कॉपी करना ही पड़ता है
  • जाँचने योग्य प्रश्न इस प्रकार हैं
    • क्या configurability वास्तव में आवश्यक है
    • क्या अपनी अलग syntax अनिवार्य है
    • क्या दूसरे टूल्स या CLI की परिचित syntax और idioms को दोबारा इस्तेमाल किया जा सकता है
    • क्या बनाने वाला स्वयं भी उपयोग का तरीका कॉपी-पेस्ट करता है, और यदि हाँ, तो क्या अन्य उपयोगकर्ताओं के साथ भी ऐसा होने की संभावना है
  • “cargo cult” शब्द के बारे में, Ken Shirriff की यह पोस्ट बताती है कि यह एक अनुपयुक्त तकनीकी शब्दावली की समस्या है

1 टिप्पणियां

 
GN⁺ 2025-01-12
Hacker News टिप्पणियाँ
  • “जो जटिल सिस्टम काम करते हैं, वे बिना किसी अपवाद के उन सरल सिस्टमों से विकसित हुए पाए जाते हैं जो काम कर रहे थे। कोई भी जटिल सिस्टम जो शुरू से डिज़ाइन किया गया हो, कभी काम नहीं करता, और उसे सुधारकर काम करने लायक भी नहीं बनाया जा सकता। आपको फिर से एक काम करने वाले सरल सिस्टम से शुरू करना पड़ता है”
    — John Gall (1975), Systemantics: How Systems Really Work and How They Fail
    https://en.wikipedia.org/wiki/John_Gall_(author)#Gall's_law

    • इसी वजह से मैं हमेशा नए language और framework को लेकर संदेह में रहता हूँ। PowerPoint स्लाइड्स में वे शानदार दिख सकते हैं, लेकिन जटिल और लंबे समय तक चलने वाले सिस्टमों में वे कैसे दिखेंगे, यह स्पष्ट नहीं होता
      आम तौर पर special cases को संभालने के लिए पैबंद-जैसी features जुड़नी शुरू हो जाती हैं, और वह इस बात का संकेत लगता है कि आगे भी ऐसे exceptions अंतहीन रूप से बढ़ते रहेंगे
      “अनुभव को लागू करना” और “किसी एक ऐसी चीज़ के इर्द-गिर्द पूरी तरह नया सिस्टम डिज़ाइन करना जो व्यक्तिगत रूप से खटकती हो” के बीच एक सूक्ष्म लेकिन महत्वपूर्ण अंतर है
  • एक और परिकल्पना है। लगभग 10% developers वास्तव में सिद्धांतों को समझते हैं और किसी चीज़ को शुरू से बना सकते हैं, और 40% लोग local code, Stack Overflow, GitHub, और LLM से copy-paste करते हुए इतना तो समझते हैं कि लगभग क्या हो रहा है, और उसी से रोज़मर्रा का काम चला लेते हैं
    बाकी 50% लोग LeetCode puzzles के कुछ सवालों से आगे ठीक से नहीं जानते, और जो copy-paste करते हैं उसकी वास्तविक समझ भी कम होती है
    अगर वितरण ऐसा है, तो संभव है कि आधे से ज़्यादा Makefile बस ऐसे copy-paste टुकड़े हों जो किसी तरह काम कर जाते हैं। अगर वे किसी ऐसी जगह से लाए गए हों जहाँ वे पहले से काम कर रहे थे, तो काम पूरा, और फिर अगला ticket
    मैं tool को दोष नहीं दे रहा। Makefile अच्छी तरह जाना-पहचाना है और छोटे projects में verbose भी नहीं होता। 10,000 files वाले monster में यह खराब विकल्प हो सकता है, लेकिन मैंने बहुत बड़े projects में भी साफ-सुथरे Makefile देखे हैं। यह शायद मेरी पहली पसंद न हो, लेकिन मुझे Makefile पसंद है और मैं इसे 30 साल से भी ज़्यादा समय से बीच-बीच में इस्तेमाल करता आया हूँ

    • मुझे लगता है लोग अक्सर इसलिए नहीं जानते क्योंकि पता लगाने का समय नहीं होता। एक दिन में आप जितनी लड़ाइयाँ लड़ सकते हैं, उनकी संख्या सीमित होती है
      उदाहरण के लिए, जब कोई C++ programmer एक ticket निपटा रहा हो, तो उसे stack की कितनी layers तक जानना चाहिए? क्या उसे CPU register के नाम तक पता होने चाहिए? जो AI researcher सिर्फ Jupyter इस्तेमाल करता है, उसे कहाँ तक समझ होना चाहिए? tools और stack को जितना हो सके सीखना अच्छा है, लेकिन समय सीमित है
    • 10,000 files वाले project में भी बहुत सरल Makefile का उपयोग करना वास्तव में मामूली बात है। open source projects में मैंने जो ज़्यादातर Makefile देखे हैं, वे अच्छे Makefile की तुलना में कहीं ज़्यादा जटिल थे
      अगर Makefile में किसी एक file को बनाने के लिए अलग-अलग explicit rules दिखें, तो मैं लगभग हमेशा उसे गलती मानता हूँ
      आम तौर पर केवल general build rules होने चाहिए, जो किसी खास type की सभी files को build करने के लिए उपयोग हों
      Makefile में source files या dependencies की सूची लगभग नहीं होनी चाहिए; सिर्फ उन directories की सूची होनी चाहिए जहाँ source files मौजूद हैं
      Make को source directories खोजकर files ढूँढनी चाहिए, उन्हें type के हिसाब से वर्गीकृत करना चाहिए, dependency lists बनानी चाहिए, और उपयुक्त build rules को call करना चाहिए। कम से कम GNU make में यह बहुत सरल है, और user manual में भी दिया गया है
      अगर इसे इस तरह लिखा जाए, तो project में 1 file हो या 10,000, Makefile को बनाने या बदलने की मेहनत लगभग समान रूप से नगण्य रहती है। source files के बनने, rename होने, move होने, या delete होने पर हर बार Makefile अपडेट करने की भी ज़रूरत नहीं पड़ती
    • मुझे Makefile पसंद है, लेकिन मैं इसे सिर्फ निजी उपयोग के लिए इस्तेमाल करता हूँ। जब भी मैं कोई नया personal project बनाता हूँ, मैं root में Makefile जोड़ देता हूँ, भले ही target उस language के सबसे बुनियादी build तक ही सीमित क्यों न हो
      क्योंकि हर language और framework का build “order” अलग होता है, और मैं उन्हें सब याद नहीं रख सकता। लेकिन $ make आसान है
    • चीज़ों को configure कर पाना और यह वास्तव में समझना कि वे कैसे काम करती हैं, ये काफ़ी अलग बातें हैं
      मैं इस बात से सहमत हूँ कि कई productive app developers शायद नया project बिलकुल शुरू से set up न कर पाएँ, लेकिन यह अक्सर गहरी समझ की तुलना में सही जादुई rules और spells जानने का मामला ज़्यादा होता है, जिनसे अलग-अलग tools अच्छी तरह एक-दूसरे से जुड़ जाते हैं
  • काम के दौरान देखा गया एक और कारण यह है कि tools और systems ऐसे होते हैं जिन्हें developers को कभी न कभी संभालना पड़ता है, लेकिन वे आमतौर पर उन्हें सीखने लायक कम समझते हैं
    उदाहरण के लिए build systems और CI configuration. ये ज़रूरी तो होते हैं, लेकिन developers यह नहीं मानते कि उन्हें रोज़ इससे जूझना चाहिए. CI को अक्सर ऐसे system की तरह देखा जाता है जिसे “एक बार सेट करो और भूल जाओ”, और फिर प्रतिक्रिया आती है कि app build करने के लिए क्या यह सब सीखना भी पड़ेगा
    developers उम्मीद करते हैं कि चीज़ें “बस काम करें”, और अगर complexity हो तो उसे कोई दूसरी team, यानी मेरी जैसी भूमिका वाला व्यक्ति संभाले. इसलिए जब भी developer इस system को छूता है, तो अक्सर उसकी प्रवृत्ति होती है कि आख़िरी बार चलने वाली setting को copy करके आगे बढ़ा दे और फिर “असली” काम पर लौट जाए
    सबसे अच्छा हल यह है कि developers के साथ बीच का रास्ता अपनाया जाए. काम के हिसाब से simple या complex tools दिए जाएँ, documentation हो, और “magic” वाली धारणा को न्यूनतम रखा जाए. Make जैसे tools अक्सर यहाँ विफल हो जाते हैं क्योंकि वे बहुत complex और black box जैसे लगते हैं

    • CI configuration की बड़ी समस्या आमतौर पर यह होती है: यह धीमा होता है, proprietary होता है, secrets संभालने की वजह से उस पर काम कर सकने वाले लोग सीमित होते हैं, और सामान्यतः local में चलाया नहीं जा सकता
      इसलिए feedback cycle बहुत लंबी हो जाती है, और काम खुद ही बहुत पीड़ादायक बन जाता है
    • जो सबसे अच्छा flow देखा गया, वह यह था कि CI/CD को repository के अंदर मौजूद scripts या Makefile के ऊपर एक बहुत पतले wrapper की तरह इस्तेमाल किया जाए
      अगर developer “CI/CD” काम का कुछ हिस्सा या पूरा काम local में चला सकता है, तो वह उसे देख, नियंत्रित और समझ सकता है. इससे “CI/CD कोई अलग ही दुनिया की चीज़ है” वाला एहसास कम होता है और ownership तथा भरोसे की भावना बढ़ती है
      यह हमेशा काम नहीं करता. ऐसा भी हुआ कि दो लोगों की team के पास thin-wrapper CI/CD था, फिर भी वे उसे किसी alien process की तरह मानते रहे और उसे छूने से इनकार करते रहे
    • दफ़्तर की coffee machine भी “set and forget” चीज़ नहीं है, लेकिन यह उम्मीद नहीं की जाती कि उसका इस्तेमाल करने वाला हर व्यक्ति maintenance की ज़िम्मेदारी बराबर बाँटे
      उसी तरह CI में ownership ज़रूरी है, और यह तरीका कि आख़िरी बार CI इस्तेमाल करने की कोशिश करने वाले developer पर ही ज़िम्मेदारी आ गिरे, काम करने का असरदार तरीका नहीं है
    • Make सबसे सरल build tools में से एक है. Grunt, Webpack जैसी चीज़ों से तुलना करें तो यह mining drill से ज़्यादा hammer के क़रीब है
      समाधान यह है कि सिर्फ इसलिए बड़े enterprise tools न उठा लाए जाएँ क्योंकि बड़ी कंपनियाँ उनका इस्तेमाल करती हैं. यह शायद अलोकप्रिय राय हो, लेकिन मेरा मानना है कि CI/CD अधिकांश जगहों पर ज़रूरी नहीं होता जहाँ इसे इस्तेमाल किया जा रहा है
      भले कुछ steps बढ़ जाएँ, build और deployment के लिए moving parts को पूरी तरह न्यूनतम रखने का तरीका खोजना चाहिए. उसके बाद किन हिस्सों को automate करना है, इसका cost सावधानी से तौलना चाहिए. सिर्फ simple काम करने के लिए बड़ा system ले आना लंबी अवधि में आमतौर पर मूल्यवान नहीं होता
      अगर सच में CI/CD की ज़रूरत है, तो आपको उसका पता दर्द वाले बिंदुओं से चल जाएगा. अगर वह system developers को ही तकलीफ़ दे रहा है, तो वह सही tool नहीं है
    • अगर make आपको “बहुत complex और black box जैसा” लगता है, तो फिर आपने cmake अभी देखा ही नहीं है
  • Make और Makefile, अगर autoconf ने उन्हें auto-generate नहीं किया है, तो बेहद सरल होते हैं. और अगर वे autoconf द्वारा बनाए गए हैं, तो उन्हें बदलना नहीं चाहिए, क्योंकि वे build artifacts हैं. हो सके तो autoconf को भी छोड़ देना बेहतर है
    व्यापक रूप से देखें तो यह effect वास्तव में मौजूद है. आप इसका शिकार भी हो सकते हैं और इसका उपयोग भी कर सकते हैं. इसका उपयोग करने का तरीका यह है: थोड़ा code लिखें या कहीं से copy-paste करें, उसे project में इस्तेमाल करके देखें, और ज़रूरत के हिसाब से सुधारें. अगला project शुरू करते समय उसी code को फिर copy करें और दूसरे project के मुताबिक़ बदलें. फिर देखें कि क्या इन बदलावों को पहले project में वापस लागू किया जा सकता है. अगर दोनों काम करते हैं और sync में रहते हैं, तो उस code को निकालकर library बना दें. कभी-कभी उसे सचमुच library-जैला रूप देने के लिए और projects की ज़रूरत पड़ती है. सबसे अच्छे मामले में उसे open source के रूप में जारी किया जाता है ताकि दूसरे लोग भी उसका इस्तेमाल कर सकें

    • Makefile अत्यंत सीमित भी है. timestamp-आधारित freshness checking आधुनिक version control systems में अक्सर टूट जाती है
      Git अंदरूनी रूप से timestamps रिकॉर्ड नहीं करता, इसलिए content एक जैसा होने पर भी file का mtime अपडेट हो सकता है, और व्यवहार में अक्सर ऐसा होता भी है, जिससे अनावश्यक rebuilds शुरू हो जाते हैं
      आधुनिक tools, जिनमें input या output पूरी directories होती हैं, या ऐसे tools जिनके output का नाम execution से पहले पता नहीं होता, उन्हें भी यह बिल्कुल ठीक से handle नहीं कर पाता
      मुझे make पसंद है और उसकी कमियों के बावजूद मैंने उसका अच्छा इस्तेमाल किया है, और मुझे उसके workarounds तथा workarounds के भी workarounds पता हैं. लेकिन जैसे ही tool, make की अपेक्षाओं से पूरी तरह मेल खाना बंद करता है, सही Makefile बनाने की कठिनाई और complexity तेज़ी से बढ़ जाती है
    • Makefile सरल है, लेकिन बहुत बार ग़लत होता है. ऐसा Makefile लिखना जो सिर्फ “scratch से build” ही नहीं बल्कि उसके अलावा भी सही तरह से काम करे, चौंकाने वाली हद तक मुश्किल है
      यह मज़ाक नहीं है. make clean जैसा concept मौजूद होना ही इसका निर्णायक सबूत है
  • शायद Makefile एक ग़लत उपमा हो. ज़्यादातर लोगों को Makefile के साथ जो समस्या होती है, वह यह है कि वे उसे बहुत कम लिखते हैं. उन्हें मोटे तौर पर अंदाज़ा होता है कि make क्या करता है, लेकिन शुरू से लिखने की muscle memory नहीं होती
    फिर भी मुख्य बात सही है. मैंने web से copy किए गए code में बहुत सा dead code पड़ा देखा है जो वास्तव में इस्तेमाल ही नहीं होता. अच्छी आदत यह है कि चीज़ें टूटने तक हटाते रहें, और फिर सिर्फ वही हिस्सा वापस लाएँ जो टूट गया हो. जितना हो सके उतना हटाना चाहिए, और जो इस समय इस्तेमाल में नहीं है, उसे निश्चित रूप से हटा देना चाहिए

    • Makefile, KVM settings, Docker configuration, CI/CD pipelines जैसी बहुत सी चीज़ों में मुझे यही समस्या मिली है
      अब तक का समाधान यह रहा है कि ऐसे tools, libraries और frameworks पर notes, साथ में shell script example programs, जमा करके एक अलग repository बनाई जाए
      जब भी किसी tool को फिर इस्तेमाल करना हो, notes देखकर याद ताज़ा कर ली जाए, और कुछ नया सीखा हो तो notes अपडेट कर दिए जाएँ. अब तो LLM को उस repository की ओर इशारा करके सवाल भी पूछे जा सकते हैं
      वह repository व्यक्तिगत उपयोग के लिए होती है और सार्वजनिक रूप से उपलब्ध tools के बारे में जानकारी रखती है. संगठन-विशेष ज्ञान भी इसी तरह, लेकिन अलग repository में रखा जाता है, और किसी client या employer के साथ contract खत्म होने पर उसे नष्ट कर दिया जाता है
  • इसे सबसे अच्छी तरह cargo cult development कहा जा सकता है। cargo cult द्वितीय विश्व युद्ध के दौरान प्रशांत क्षेत्र में पैदा हुआ था, जब द्वीपों के मूल निवासियों ने खाने, शराब और सामान से भरे चमत्कार जैसे हवाई जहाज़ आते देखे, और सैनिकों के व्यवहार की नकल करते हुए बाँस के विमान और नारियल के उपकरण बनाए ताकि देवता प्रसन्न हों और सामान फिर से आए
    समस्या यह थी कि द्वीपवासी विमान, रेडियो, बंदूक जैसी चीज़ों के विज्ञान को समझते नहीं थे
    उसी तरह cargo cult शैली का डेवलपर संभावित परिणाम तो देखता है, लेकिन first principles नहीं समझता, और तकनीक के उच्च पुरोहित जो करते हैं उसकी नकल करके सफलता की प्रतिलिपि बनाने की आशा करता है
    इसलिए वह copy, paste, try, छेड़छाड़, search, pull, push, tune करना दोहराता रहता है, इस उम्मीद में कि इस बार कम से कम मंगलवार शाम के किसी खास data पर यह लगभग चल जाए

    • मैं इसे cargo cult development नहीं मानता। cargo cult उस चीज़ के ज़्यादा करीब है जहाँ व्यापक संदर्भ गायब हो चुका हो, फिर भी बिना समझे उन प्रथाओं की नकल की जाए जो सिर्फ उसी संदर्भ में काम करती थीं
      व्यवहार में इसका मतलब अक्सर ऐसे कामों या अनुष्ठानों को दोहराना होता है जिनका अपने आप में कोई प्रभाव नहीं होता, इस आशा में कि वही अनुष्ठान करने वाली किसी दूसरी कंपनी को जो परिणाम मिला था, वह मिल जाए
      मूल लेख में जो कहा गया है वह अलग है। यहाँ जिसकी नकल हो रही है, वह code स्वयं प्रभावी है। उसे test करके देखा जा सकता है कि वह काम करता है या नहीं
      यह भेद महत्वपूर्ण है। मूल लेख का Makefile effect और cargo cult के लक्षण अलग हैं, इसलिए दोनों को एक जैसा मानने से निदान कठिन हो जाता है। cargo cult में अंधविश्वास के कारण लोग ऐसी चीज़ों पर समय बर्बाद करते हैं जो वास्तव में काम नहीं करतीं। Makefile effect में काम करना सिद्ध हो चुका होता है, लेकिन vestigial अंग जैसे टुकड़े कॉपी होते रहते हैं और धीरे-धीरे maintenance कठिन हो जाती है
    • मैं ही लेख का लेखक हूँ। यह बात footnote 1 में है
      विशेष रूप से, मैं नहीं मानता कि यह cargo cult के बिल्कुल समान है। cargo cult में समझ की कमी निहित होती है। लेकिन कोई व्यक्ति किसी system को अच्छी तरह समझते हुए भी मुख्यतः copy-paste के सहारे जी सकता है, क्योंकि उस system की अंतर्निहित जटिलता copy-paste को प्रेरित करती है। यही लेख का मुख्य बिंदु था
    • मैं अक्सर वही चीज़ copy-paste करता हूँ जो मैंने खुद अतीत में लिखी थी। ऐसा तब होता है जब कोई tool बहुत झंझट वाला हो और संज्ञानात्मक context switching की लागत उठाना मुश्किल लगे
      आम तौर पर मैं समझता हूँ कि अंदर क्या हो रहा है, लेकिन उस “mode” में जाना ही संज्ञानात्मक रूप से भारी होता है, इसलिए यथासंभव उससे बचता हूँ
      इस श्रेणी में अक्सर CI/CD, k8s, Docker जैसे ऑपरेशंस टूल आते हैं, जिनकी जटिलता बहुत अधिक है लेकिन वे उस मुख्य समस्या का हिस्सा नहीं हैं जिसे मैं हल कर रहा हूँ। Make में खास तौर पर context switching से बचना कठिन है, इसलिए इन दिनों मैं उससे बचता ही हूँ
      इसका चमत्कारी मंत्रों से कोई संबंध नहीं है, और मैं जानता हूँ कि मैं कौन-सा trade-off कर रहा हूँ। फिर भी इसके Makefile effect में बदल जाने का जोखिम है
    • लेख में footnote 1 में इसे कुछ हद तक छुआ भी गया है:
      “Makefile effect cargo cult, normalization of deviance, और ‘write-only language’ जैसी अन्य घटनाओं से मिलता-जुलता है। इस लेख में मैं तर्क दूँगा कि यह इनमें से हर एक से थोड़ा अलग है, क्योंकि यह स्वभावतः अक्षम या बुरा नहीं है, बल्कि किसी खास design के परिणाम से संबंधित है”
    • मुझे लगता है कि प्रोग्रामिंग की मेरी समझ “शुरुआती में भी बहुत शुरुआती” स्तर के करीब है। तो क्या इसका मतलब है कि “cargo cult” मानसिकता से बचने के लिए education → learning → execution → failure → repeat जैसा कोई structured flow चाहिए?
      फिर क्या इसका मतलब है कि अगर कोई सचमुच “द्वीप से निकलकर खुद विमान उड़ाना” चाहता है, तो आखिरकार विश्वविद्यालय ही सबसे “वास्तविक” रास्ता है?
      मैं जानता हूँ कि इसे पूरी तरह निर्णायक रूप से कहना कठिन है, अपवाद बहुत हैं, और लोगों के पास “मैं वह नहीं कर सकता” कहने के अनेक औचित्य होते हैं। यहाँ मैं इसे optimal theory के नज़रिए से पूछ रहा हूँ। अगर cult-जैसे व्यवहार से बचने का सर्वोत्तम रास्ता पूरे तंत्र को समझना है, तो क्या वह “पूरा” मुख्यतः उच्च शिक्षा से नहीं आता?
      तार्किक रूप से, भले कोई किताबों से ईमानदारी से पढ़कर विश्वविद्यालय की “पूर्णता” को पकड़ने या पार करने की कोशिश करे, फिर भी यह किसी जानकार शिक्षक और कक्षा में बिताए गए समय की तुलना में कुछ मायनों में कमतर लगता है। यह मान लेने पर भी कि वही व्यक्ति दोनों रास्तों पर समान मेहनत करे
  • एक और कारण इस्तेमाल की आवृत्ति है। LaTeX में कोई बड़ा लेख लिखना साल में एक बार से भी कम होता है
    मैं जिस स्तर पर LaTeX इस्तेमाल करता हूँ, वह कोई कठिन tool नहीं है, लेकिन अगर उसे साल में सिर्फ कुछ हफ्ते ही इस्तेमाल करूँ, तो उसके उपयोग की बारीकियाँ कभी याद नहीं रह सकतीं, इसलिए मैं आम तौर पर पुराने दस्तावेज़ को copy-paste करके नया दस्तावेज़ शुरू करता हूँ

    • Makefile, shell script जैसी अपेक्षाकृत बार-बार इस्तेमाल होने वाली तकनीकों को मैं सीखने की कोशिश करता हूँ ताकि “Makefile effect” से बच सकूँ
      लेकिन LaTeX को पहले बहुत ज़्यादा इस्तेमाल करने के बावजूद भी मैं हमेशा template से copy-paste करता था। beamer presentations और TikZ diagrams में तो यह और भी ज़्यादा था; template के बजाय मैं पिछली presentations या diagrams से कॉपी करता था
      मुझे लगता है कि TikZ स्वयं एक स्वभावतः जटिल tool है और मैंने उसे पर्याप्त रूप से नहीं सीखा
      LaTeX के बारे में मुझे लगता है कि मैंने उसे पर्याप्त सीखा है, इसलिए कारण कुछ और हो सकता है
      मेरे विचार से यह sane defaults की समस्या हो सकती है। एक अच्छे tool को अच्छे defaults देने चाहिए। लेकिन LaTeX इस कसौटी पर अच्छा tool नहीं है। मेरे दस्तावेज़ आम तौर पर कुछ इस तरह शुरू होते हैं
      \documentclass[paper=a4, DIV9, 12pt, abstracton, headings=normal,  
      captions=tableheading]{scrartcl}  
      \usepackage[T1]{fontenc}  
      \usepackage[utf8]{inputenc}  
      \usepackage[english,german,ngerman]{babel}  
      \usepackage[english,german]{fancyref}  
      % ...  
      \usepackage{microtype}  
      \usepackage{hyperref}  
      
      इनमें से ज़्यादातर सिर्फ मेरी मातृभाषा के लिए बुनियादी non-ASCII support पाने या A4 paper, microtype जैसे sane defaults चालू करने के लिए होते हैं। pandoc/Markdown जैसे आधुनिक tools में शायद इसकी ज़रूरत न पड़े
      इसलिए ऐसी चीज़ों को copy-paste करने का उद्देश्य अक्सर वे बेहतर defaults पाना होता है जो कोई बेहतर tool शुरू से देता
    • मैं LaTeX ज़्यादा बार इस्तेमाल करता हूँ, फिर भी मैं भी copy-paste किए हुए header से ही शुरू करता हूँ। उसमें मेरी भाषा के लिए ज़रूरी packages (fontenc, babel, स्थानीय typesetting package), लगभग हमेशा चाहिए होने वाले graphicx/fancyhdr/hyperref/geometry packages, और मेरे क्षेत्र में उपयोगी symbols और names की definitions होती हैं
      अगर आप गणित नहीं लिख रहे या सिर्फ शुद्ध अंग्रेज़ी plain text नहीं लिख रहे, तो LaTeX लगभग “batteries not included” जैसा है
  • यह copy-paste driven development है [0], और यह सिर्फ Makefile की बात भी नहीं है। यह पूरे उद्योग में बिना यह समझे कि वे क्या कॉपी कर रहे हैं, कोड को इधर-उधर कॉपी करने की प्रवृत्ति से जुड़ा है
    सच कहूँ तो मुझे लगता है कि Copilot ने इसे और बदतर बना दिया है। क्योंकि लोग codebase में code के टुकड़ों को आँख बंद करके स्वीकार कर रहे हैं
    [0] https://andrew.grahamyooll.com/blog/copy-pasta-driven-develo...

    • दोष business side के लोगों का है। मैंने शायद कम-से-कम 7 बार लगातार make expert बनने की कोशिश की, लेकिन मुझे कभी इतना समय नहीं मिला कि उसे रोज़ाना इस्तेमाल करके पूरी तरह याद कर सकूँ
      एक बिंदु पर आकर मैंने बस हार मान ली। मैं muscle memory बना नहीं पाया, और हर बार ज़रूरत पड़ने पर इसे फिर से शुरुआत से सीखना पड़ता था, जैसे कोई गूढ़ vision knowledge हो। इसलिए मैं और सरल tools पर चला गया
      deep work का नुकसान अच्छे programmers की गलती नहीं, business side के लोगों की गलती है
  • मैंने बहुत बार देखा है कि लोग दूसरे project से Makefile ज्यों-का-त्यों कॉपी करते हैं, फिर उसे “चलने लायक” बनाने के लिए बदलते हैं, लेकिन उससे पूरी तरह असंबंधित बेकार build steps और targets वैसे ही छोड़ देते हैं
    व्यक्तिगत रूप से यह मुझे बहुत खटकता है

    • अगर documentation बिल्कुल नहीं है, तो यह कैसे पता चले कि क्या relevant है और क्या नहीं?
      trial and error से? तो फिर मज़े कीजिए :p
  • यह सही है कि ज़रूरत से ज़्यादा जटिल tools बहुत हैं, लेकिन मुझे नहीं लगता कि Make इसका उपयुक्त उदाहरण है
    आधुनिक tools में complexity की समस्या अक्सर खराब documentation, cookbook-style documentation, ऐसी documentation जो यह नहीं समझाती कि tool कैसे काम करता है इसे समझने के लिए कौन-सा conceptual model चाहिए, और ऐसी documentation जिसमें पर्याप्त detail और सटीक spec न हो—इन वजहों से और बढ़ जाती है
    Make ऐसा नहीं है। इसकी documentation अच्छी है, और अगर आप वास्तव में documentation पढ़ने के लिए समय दें, तो इसे समझना मुश्किल नहीं है
    ऊपर वाला cookbook-style approach ऐसी संस्कृति को बढ़ावा देता है जो अपने इस्तेमाल के tools को सीखने और समझने के महत्व को कम करके देखती है, और उस thorough documentation के महत्व को भी, जो इसे संभव बनाती है। या शायद कारण-परिणाम का रिश्ता उल्टा हो
    जो भी हो, मुझे लगता है कि समस्या यह है कि व्यापक और up-to-date tool documentation बनाने में बहुत कम समय लगाया जाता है, tools को शुरुआत से इस तरह डिजाइन करने में भी कमी है कि ऐसी documentation संभव हो सके, और ज़रूरी tools को सिखाने-सीखने के लिए भी बहुत कम resources दिए जाते हैं