3 पॉइंट द्वारा GN⁺ 2025-11-01 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • John Carmack ने mutable variable के उपयोग पर अपने निजी विचार साझा किए
  • उन्होंने कहा कि Python का उपयोग करते हुए ‘single assignment’ सिद्धांत को नज़रअंदाज़ करने की आदत पड़ गई है, और इससे खुद को सावधान रखना चाहिए
  • उन्होंने ज़ोर देकर कहा कि loop की iteration में होने वाली गणना को छोड़कर variable को दोबारा assign या update करने से बचना चाहिए
  • अगर बीच के सभी calculation steps बने रहें, तो debugging में मदद मिलती है, और code block को स्थानांतरित करते समय अनजाने में पुराने value के इस्तेमाल की समस्या रोकी जा सकती है
  • उन्होंने समझाया कि C/C++ में लगभग सभी variables को initialization के समय const के रूप में declare करना एक अच्छी आदत है
  • अंत में उन्होंने यह कहते हुए ज़ोर दिया, “काश mutable एक keyword होता,” ताकि immutability default बन सके

1 टिप्पणियां

 
GN⁺ 2025-11-01
Hacker News राय
  • 2 साल तक Clojure इस्तेमाल करने के बाद मुझे एहसास हुआ कि अन्य डेवलपर्स को immutable होने से मिलने वाली स्पष्टता समझाना वास्तव में बहुत कठिन है
    जो लोग state change के ज़रिए effects पैदा करने वाली सोच के आदी हैं, उनके लिए इसे खुद अनुभव करने से पहले समझना मुश्किल होता है

    • variable बदलने से implicit order dependency बन जाती है
      उदाहरण के लिए, अगर आप x = 7; x = x + 3; x = x / 2 लिखते हैं, तो क्रम बदलने पर error नहीं आएगी, लेकिन result बदल जाएगा
      वहीं x1, x2 जैसे नए variables इस्तेमाल करने पर गलत क्रम में error आएगी और समस्या साफ़ दिखेगी
      आखिरकार single assignment ऐसी dependencies को स्पष्ट रूप से व्यक्त करने का तरीका है
    • मेरा Scheme में भी ऐसा ही अनुभव रहा
      जिन सहकर्मियों ने functional language कभी नहीं इस्तेमाल की थी, उन्हें यह समझाने की कोशिश की कि function-केंद्रित सोच कितनी आसानी से test की जा सकती है और कितनी साफ़-सुथरी है, लेकिन बात ठीक से पहुँचती नहीं थी
      Python में functional style को पढ़ने लायक तरीके से लिखना कठिन है, और JS इस मामले में बेहतर लगता है
      आखिर में केवल जिज्ञासु डेवलपर्स ही Clojure जैसी भाषाएँ आज़माते हैं
    • अगर immutable data और pure functions को default मान लिया जाए, तो functions को पूरी तरह black box की तरह संभाला जा सकता है
      function को external state जानने की ज़रूरत नहीं होती, और बाहर की दुनिया को भी function के अंदर की जानकारी नहीं चाहिए
      पूरे program state को जाने बिना भी किसी खास function को स्वतंत्र रूप से test या debug किया जा सकता है
    • immutability और mutability को बस एक-दूसरे के विरोध में रखना जटिलता से बचने जैसा है
      Haskell community आखिरकार type system के भीतर mutability को फिर से गढ़ने की कोशिश करती दिखती है, यह दिलचस्प है
      असली बात है side effects को न्यूनतम लागत पर नियंत्रित करना
    • Clojure उन भाषाओं में सबसे प्रभावशाली भाषा रही है जिन्हें मैंने सीखा
      Haskell में type system की वजह से entry barrier ऊँचा था, और F# इतना समझौतावादी लगा कि आखिर में C# syntax में ही coding होने लगती थी
      Clojure की homoiconicity और शक्तिशाली data structures की वजह से पहली बार यह विचार साफ़ हुआ कि ‘values के साथ काम करना’ क्या होता है
      मैं इसे पेशेवर रूप से शायद इस्तेमाल न करूँ, लेकिन जिन लोगों के पास functional language या Lisp का अनुभव नहीं है, उन्हें मैं इसे ज़रूर recommend करना चाहूँगा
  • काश variables default रूप से immutable होते और हर चीज़ expression होती
    लेकिन हक़ीक़त यह है कि Clojure डेवलपर के रूप में मैं Python के आक्रमण से जूझ रहा हूँ

    • मैं भी Python डेवलपर हूँ, लेकिन Clojure सिर्फ personal projects में इस्तेमाल किया है
      अब मैं TypeScript के आक्रमण से जूझ रहा हूँ, इसलिए यह बात समझ में आती है
    • Rust सीखने के बाद मुझे समझ आया कि कोई language शुद्ध functional न भी हो, तब भी हर चीज़ expression हो सकती है
      यह तरीका परिवर्तन के दायरे को सीमित करने में वास्तव में उपयोगी है
    • Clojure हमेशा Python से तेज़ है, यह कुछ सांत्वना देता है
    • आप बस Clojure इस्तेमाल करने वाले व्यक्ति हैं, खुद को “Clojure programmer” के रूप में परिभाषित करने की ज़रूरत नहीं है
      languages के बीच होने वाले tribal wars में फँसने की कोई ज़रूरत नहीं
      productivity बढ़ाने के इस दौर में सीमाएँ अर्थहीन हैं
      Don’t Call Yourself a Programmer लेख recommend करता हूँ
  • मैं variable reassignment को कम से कम रखने की कोशिश करता हूँ, लेकिन अक्सर variable shadowing का इस्तेमाल करता हूँ
    result = result.process() जैसा pattern संक्षिप्त होने की वजह से पसंद है

    • शायद यह abstract example होने की वजह से हो, लेकिन ज़्यादातर मामलों में हर चरण को स्पष्ट नाम दिया जा सकता है
    • इस तरह का pattern security bug पैदा कर सकता है
      उदाहरण के लिए, अगर process() एक validation function है, तो यह अस्पष्ट हो सकता है कि किसी बिंदु पर value processed थी या नहीं
      इसलिए नामों के ज़रिए state को साफ़ तौर पर अलग रखना बेहतर है
    • functional style में इसे ऐसे intermediate variables के बिना function chaining से हल किया जा सकता है
      उदाहरण: result = x |> foo |> bar |> baz या (-> x foo bar baz)
    • result.process()? आखिर कौन-सा result और कौन-सा process?”
      बाद में code पढ़ने वाला व्यक्ति उलझ सकता है
    • जब वह पहले से ही result है, तो उसे फिर process करना तार्किक रूप से अटपटा लगता है
  • “variable” शब्द खुद भी हमेशा थोड़ा खटकता है
    अगर वह immutable है, तो उसे variable क्यों कहा जाए?

    • variable execution के दौरान नहीं बदलता, लेकिन हर call पर उसका value अलग हो सकता है
      Rust में केवल mut को स्पष्ट रूप से लिखने पर ही बदलाव संभव होता है
      वहीं C में constant बनाने के लिए preprocessor का सहारा लेना पड़ता है, जो भ्रम पैदा करता है
    • function का argument x हर call पर अलग value लेता है, इसलिए वह अपने आप में बदलने वाला value है
      reassignment न होने पर भी उसे variable कहा जा सकता है
    • गणित में भी variable किसी खास वस्तु नहीं, बल्कि मनमाने value की ओर इशारा करने वाला प्रतीक है
      programming ने यही विचार अपनाया है
    • आखिरकार variable इसलिए variable है क्योंकि execution दर execution उसका value बदल सकता है
      constant हर execution में वही value रखता है
      Variable (mathematics) देखें
    • ‘variable’ का अर्थ समय के साथ बदलना नहीं, बल्कि संदर्भ के अनुसार अलग होना है
  • अच्छा होगा अगर IDE variable के बदलने या न बदलने को दृश्य रूप में दिखाए
    जैसे, बदले गए variables को बस हल्का-सा mark कर दे

    • IntelliJ में reassigned variables के नीचे underline आती है, और mouse hover करने पर ‘Reassigned local variable’ का hint दिखता है
      जहाँ तक संभव हो final का अधिक इस्तेमाल करने से code पढ़ने और maintain करने में आसान हो जाता है
    • लेकिन automatic inference से बेहतर स्पष्ट opt-in लगता है
      IDE warning दे, और केवल सच में ज़रूरत होने पर ही बदलाव की अनुमति हो
      Rich Hickey की set vs list वाली बात की तरह, ऐसा structure चुनना चाहिए जो अर्थ को स्पष्ट रूप से व्यक्त करे
    • Swift में compiler variable के mutation को पहचानकर, अगर बदलाव अनावश्यक हो तो उसे constant में बदलने का सुझाव देता है
    • JetBrains IDEs में variable की read/write locations खोजने की सुविधा पहले से मौजूद है
    • अगर इस काम के लिए कोई linter बनाया जाए, तो उसका नाम “mutalator” अच्छा लगेगा
  • पहले मैंने thread safety के लिए immutability को बहुत सख्ती से लागू करने वाला एक project किया था
    इसकी वजह से code पढ़ना आसान हुआ, और यह ट्रैक करना भी आसान हुआ कि क्या बदल सकता है
    तब से मैं immutability का कट्टर प्रशंसक बन गया हूँ

    • अगर ऐसा है, तो मैं ज़रूर Rust आज़माने की सलाह दूँगा
  • बड़े Haskell codebase पर काम करने के बाद जब फिर C पर लौटा, तो लगा कि immutability default होनी चाहिए
    const काफ़ी नहीं है

    • C में वास्तव में सीधे mutation नहीं, बल्कि केवल value reassignment संभव है
      mutation के लिए pointers का सहारा लेना पड़ता है, और C++ में तो केवल function call से भी arguments बदल सकते हैं, जिससे चीज़ें अपारदर्शी हो जाती हैं
    • यह जानने की जिज्ञासा है कि क्या Rust का default काफ़ी सुरक्षित immutability देता है
  • “लगभग सभी variables को const घोषित करना अच्छा है” — इस बात से सहमत हूँ
    यहाँ Rust का ज़िक्र होना स्वाभाविक है

    • इस संदर्भ में John Carmack का ट्वीट देखना उपयोगी है
    • और Zig भी इसी दर्शन का पालन करता है
  • मैं ऐसी syntax की कल्पना करता हूँ जहाँ default immutable हो, और केवल किसी खास block के अंदर ही mutable की अनुमति हो
    जैसे Python के with block की तरह

    with mutable(x, items):
        x = 3
        items.append(4)
    

    block से बाहर निकलते ही फिर से immutable हो जाए

    • यह असल में mutable borrow की अवधारणा ही है
      Rust के borrow checker को देखें तो पता चलता है कि यह विचार कितना जटिल है
    • अगर borrow checking न हो, तो block के बाहर भी reference बची रह सकती है और mutation हो सकता है
  • एक कहावत है, “State is the enemy
    state जितनी बढ़ती है, test करने वाली conditions उतनी ही गुणात्मक रूप से बढ़ती जाती हैं
    immutability इस तरह के state explosion को रोकने का एक तरीका है

    • इसलिए functional programmers Church और state की separation में विश्वास करते हैं
      Separation of Church and State