2 पॉइंट द्वारा GN⁺ 2023-12-07 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Jepsen एक ऐसा टूल है जो डेटाबेस जैसे concurrency systems को verify करता है, इसलिए implementation language चुनते समय concurrency model और real thread support अहम मानदंड थे
  • Clojure की immutable·persistent data structures और JVM concurrency tools टेस्ट कोड में गलती की संभावना कम करते हैं और Java-आधारित database clients के साथ भी अच्छी तरह फिट बैठते हैं
  • Jepsen का काम तयशुदा product development से ज़्यादा प्रयोग और खोज के करीब था, इसलिए REPL, macros, threading macro, EDN जैसी Clojure features complex data processing में फायदेमंद थीं
  • performance सबसे ऊपरी स्तर की नहीं है, लेकिन idiomatic Clojure आम तौर पर Java से एक-दो अंकों के भीतर ही धीमा होता है, और ज़रूरी जगहों पर optimization और JVM profiling tools से इसे संभाला जा सकता है
  • छोटी community, व्यापक रूप से सफल static type system की कमी, primitive handling में असुविधा, और error messages जैसी कमजोरियाँ हैं, लेकिन 1~3 लोगों द्वारा maintain और use किए जाने वाले Jepsen के लिए यह स्वीकार्य trade-off था

concurrency testing tool के लिए उपयुक्त language की शर्तें

  • Jepsen concurrency systems को test करने के लिए बनाया गया था, और जिन systems को यह test करता है वे ज़्यादातर databases हैं
  • Clojure concurrency test code लिखने के लिए ज़रूरी बुनियादी शर्तों को अच्छी तरह पूरा करता है
    • immutable·persistent data structures shared state संभालने वाले code में गलती की संभावना कम करती हैं
    • real threads, promise, future, atom, lock, queue, cyclic barrier, java.util.concurrent आदि का उपयोग किया जा सकता है
    • Haskell जैसे और अधिक सख्ती से side effects नियंत्रित करने वाले languages पर भी विचार किया गया था, लेकिन Clojure का कम dogmatic approach Jepsen के लिए अधिक उपयुक्त था
  • database testing में अलग-अलग clients से कनेक्ट होना ज़रूरी होता है
    • लगभग हर database आम तौर पर Java में लिखा हुआ JVM client देता है
    • Clojure की Java interoperability अच्छी है, इसलिए ऐसे clients का उपयोग करना आसान है

प्रयोग और data exploration के लिए फायदेमंद Clojure features

  • Jepsen tests प्रयोगात्मक काम हैं, इसलिए ऐसी language चाहिए थी जो संक्षिप्त हो, आसानी से बदली जा सके और prototyping के लिए उपयुक्त हो
    • Clojure का संक्षिप्त syntax और macro system इस तरह के workflow के लिए अच्छी तरह फिट बैठते हैं
    • threading macro chained transformations को पढ़ना आसान बनाता है
    • macros reusable error handling और resource scope control को implement करना आसान बनाते हैं
    • Clojure REPL test execution result data को तुरंत explore करने में उपयोगी है
  • testing process में complex और nested data structures को represent, transform और inspect करना पड़ता है
    • Clojure की data structures और standard library functions इस काम में मजबूत हैं
    • console और files में structured data बड़ी मात्रा में output करते समय EDN data syntax अच्छी तरह फिट बैठती है

performance और long-term maintenance के बीच trade-off

  • Jepsen बहुत बड़ा system नहीं है, लेकिन यह ठीक-ठाक मात्रा में data संभालता है, इसलिए “काफ़ी अच्छा” performance चाहिए
    • Clojure सबसे तेज़ language नहीं है
    • idiomatic Clojure आम तौर पर Java की तुलना में एक-दो अंकों के भीतर performance अंतर पर रहती है
    • महत्वपूर्ण bottlenecks में इस अंतर को कम किया जा सकता है
    • JVM के profiling tools Clojure के साथ अच्छी तरह काम करते हैं
  • Jepsen लगभग 10 साल पुराना project है, इसलिए mature core और stability महत्वपूर्ण थे
    • Clojure JVM target और language दोनों के रूप में स्थिर है
    • इसकी libraries Scala या Ruby जितनी तेज़ी से “खराब” नहीं होतीं

Clojure की वे कमजोरियाँ जिन्हें स्वीकार करना पड़ता है

  • Clojure में कुछ कमियाँ हैं जो Jepsen के आकार पर तो संभाली जा सकती हैं, लेकिन बड़ी teams के लिए बोझ बन सकती हैं
    • engineering community छोटी है
    • व्यापक रूप से स्वीकार और सफल static type system नहीं है
    • Jepsen को एक समय में केवल 1~3 लोग maintain और use करते हैं, इसलिए यह सीमा अपेक्षाकृत कम प्रभाव डालती है
  • JVM primitive को संभालते समय Java तक नीचे जाए बिना काम करना मुश्किल हो सकता है, और वास्तव में कभी-कभी Java का उपयोग किया जाता है
  • polymorphism system के कुछ हिस्से कमजोर हैं, लेकिन libraries से उनका workaround किया जा सकता है, और error messages भी अच्छे नहीं हैं
  • Jepsen का prototype कई languages में बनाया गया था, फिर Clojure चुनी गई, और 10 साल बाद भी यह काफ़ी अच्छा trade-off बना हुआ है

1 टिप्पणियां

 
GN⁺ 2023-12-07
Hacker News टिप्पणियाँ
  • Clojure/ClojureScript के साथ SaaS को लगभग 10 साल चलाने के अनुभव से मैं Kyle की बात से पूरी तरह सहमत हूँ
    इसके अलावा बहुत बड़ी वैल्यू इस बात की रही कि ज़्यादातर domain code को cljc files में रखा जा सकता है, ताकि उसे server और client दोनों के लिए compile किया जा सके; यह भी कि transducer और transducer pipelines को performance, composability और reusability के मामले में कम आंका गया है; और Rich Hickey द्वारा डिज़ाइन की गई भाषा होने के कारण इसकी stability और long-term compatibility बेहतरीन है
    backward compatibility बहुत महत्वपूर्ण है, इसलिए लगातार बदलते tools के पीछे भागने के बजाय application पर ध्यान दिया जा सकता है, और औसत Clojure programmer का 12 साल से अधिक अनुभव होना और top quartile compensation पाना भी मुझे संयोग नहीं लगता

    • मेरी स्थिति भी मिलती-जुलती है। मेरा SaaS भी Clojure पर चलता है, और दूसरी भाषाओं की तुलना में maintenance सपने जैसा आसान है
      यह लगभग कभी टूटता नहीं और upgrade भी आसान है। HMR, REPL और cljc files की वजह से developer experience भी शानदार है, और Clojure code लिखने में मज़ा आता है
    • कुल फायदों में से कितना हिस्सा JVM की वजह से है, और कितना Clojure भाषा की वजह से?
    • क्या Clojure में इस्तेमाल करने लायक web frameworks हैं?
    • अगर backward compatibility इतनी महत्वपूर्ण है, तो यह सिर्फ C और C++ पर लागू होने पर अपवाद जैसा क्यों माना जाता है, यह जानने की उत्सुकता है
      अगर काम कर रही चीज़ों को न तोड़ने के लिए भाषा और systems को पीछे की ओर मोड़ना ठीक है, तो फिर वास्तव में चल रहे software के बड़े हिस्से को संभालने वाली इन दो भाषाओं से उनके गौरवशाली अतीत और वर्तमान को काट फेंकने की उम्मीद क्यों की जाती है, समझ नहीं आता
  • Clojure की सबसे बड़ी समस्या निश्चित रूप से इसका ecosystem है
    उपलब्ध और उपयोगी tools के distribution को देखें तो या तो वे बहुत बाएँ छोर पर होते हैं—भयानक लेकिन आसानी से पहुँच में—या फिर इतने दाएँ छोर पर कि README में Lord of the Rings के उद्धरण मिलते हैं, सब कुछ nth order तक data होता है, और केवल वही dragon इन्हें छू सकता है जो आँखों पर पट्टी बाँधकर उल्टा लटकते हुए Emacs plugin लिख सके
    भाषा स्वयं शानदार है और Java interoperability भी Aphyr के कहने से कहीं बेहतर है, लेकिन अगर Clojure के पास Rails या Django, या उससे भी बेहतर Phoenix जैसा कुछ होता, तो इसे समझाना बहुत आसान होता और शायद यह कहीं अधिक व्यापक रूप से इस्तेमाल होती
    खासकर अगर आपको Algol-family imperative language से किसी टीम को Lisp की ओर लाना है, तो मिलने वाला लाभ झेले गए कष्ट से बड़ा होना चाहिए, लेकिन अभी HTTP routing जैसे बुनियादी हिस्सों को छोड़ दें तो लगभग हर project में पहिया फिर से बनाना पड़ता है
    फिर भी, किसी भी Maven package का इस्तेमाल कर पाना और jar के रूप में compile होना एक बहुत बड़ा फायदा है, क्योंकि जहाँ jar चल सकता है, वहाँ Clojure भी चल सकता है

    • VSCode के लिए शानदार plugin Calva ज़रूर देखना चाहिए। यह सिर्फ REPL ही नहीं, live docs जैसी सुविधाएँ भी देता है, इसलिए Clojure को आसानी से इस्तेमाल किया जा सकता है, और मैं इसे रोज़ काम में इस्तेमाल करता हूँ
      https://calva.io
    • लगता नहीं कि आपने Clojure में रोज़गार के लिए coding की है। Clojure ecosystem और community अच्छी तरह maintained हैं
      Clojure के कई रूप हैं, और मुख्य रूप से Clojure और ClojureScript का इस्तेमाल होता है; Babashka, Scittle आदि भी हैं, लेकिन सब clj या cljs से निकले हुए हैं
      development tools platform और IDE पसंद के अनुसार बदलते हैं, इसलिए Emacs, Neovim, VSCode और IntelliJ के लिए अलग tools हैं, और build systems भी ज़रूरत के हिसाब से बदलते हैं
      clj में deps.edn अभी सबसे ज़्यादा इस्तेमाल होता है और उसके बाद leiningen आता है; cljs में shadow-cljs के अलावा भी कई विकल्प हैं
      नए लोगों के लिए यह भारी पड़ सकता है, लेकिन community अच्छी है और हमेशा मदद करती है। मैंने कई भाषाओं में पेशेवर programming की है, लेकिन Clojure मुझे सबसे ज़्यादा पसंद है
    • “भयानक लेकिन आसानी से पहुँच में” tools के उदाहरण जानने की उत्सुकता है
      मैं 2013 के आसपास से Clojure इस्तेमाल कर रहा हूँ, लेकिन ऐसा कोई tool याद नहीं आता। ज़्यादातर लोकप्रिय libraries शानदार हैं, और stability, backward compatibility और simplicity के मामले में वे मेरे जानने वाले अधिकांश ecosystems से बहुत आगे हैं
    • यह Jepsen या लेख के मुख्य भाग से जुड़ी टिप्पणी कम, और कोई मनमानी Clojure टिप्पणी ज़्यादा लगती है
    • Clojure को अच्छी तरह न जानने वालों के लिए जोड़ दूँ कि, जैसा इस thread में /u/jwr ने कहा, ClojureScript की वजह से Clojure वहाँ भी चलती है जहाँ browser है
      .cljc source files की वजह से, जिन्हें Clojure और ClojureScript दोनों में share किया जा सकता है, वही Clojure code frontend और backend दोनों पर चलाया जा सकता है
      Rich Hickey के शब्दों में, यह सिर्फ JVM तक “reach” नहीं करती, बल्कि JavaScript तक भी पहुँचती है
      मैं लंबे समय से Emacs इस्तेमाल करता रहा हूँ और इसे अपनी पसंद के अनुसार configure कर सकता हूँ, या ज़रूरत पड़ने पर elisp code भी अंततः बना सकता हूँ, लेकिन मैं यह बिल्कुल नहीं कहूँगा कि मैं elisp में अच्छा हूँ
      यह मानता हूँ कि जिसने कभी कोई Lisp dialect नहीं सीखी, उसके लिए Emacs, elisp और Clojure को एक साथ सीखना मुश्किल है और समझाना भी बहुत कठिन है
      अब Clojure LSP server मौजूद है और यह सिर्फ Emacs ही नहीं, दूसरे IDEs में भी काम करता है, इसलिए भले ही बहुत से Clojure developers Emacs इस्तेमाल करते हों, Clojure development के लिए Emacs अनिवार्य नहीं है
  • मैंने 7 साल तक सिर्फ Clojure इस्तेमाल की है और 5 लाख से ज़्यादा lines वाली Clojure + ClojureScript codebase पर सक्रिय रूप से काम किया है, और सबसे बड़ी शिकायत यह है कि इसमें मजबूत type system नहीं है
    मैं इस बात से सहमत हूँ कि Clojure expressive है, तेज़ी से आगे बढ़ने देती है और रास्ते में बाधा नहीं बनती, लेकिन यह ऐसे गंदे runtime errors की भी अनुमति देती है जिन्हें reproduce करना और debug करना मुश्किल होता है
    अगर कोई व्यापक रूप से स्वीकार किया गया और सफल static type system होता, तो Clojure कमाल की होती। अभी मुझे यह Ruby या Python पसंद करने वालों के लिए, लेकिन कुछ अधिक मजबूत चाहने पर, काफ़ी अच्छी लगती है; और अब मैं सोचने लगा हूँ कि शायद Go सही रास्ता है

    • जिन हिस्सों में static types मददगार साबित हुए हैं, वहाँ Kotlin जैसी दूसरी JVM languages को Clojure project में integrate किया जा सकता है
  • मैं पूरी तरह सहमत हूँ कि Clojure(Script) सचमुच किसी वरदान के करीब है, और छोटे हों या बड़े, बहुत-से प्रोजेक्ट्स के लिए एक बेहतरीन विकल्प है
    C, Python, PowerShell, Java, Bash, और SQL को मैंने कॉलेज असाइनमेंट, सिस्टम एडमिनिस्ट्रेशन, ट्रैफिक डंप विश्लेषण आदि में थोड़ा-बहुत इस्तेमाल किया था, और प्रोफेशनल तौर पर मेरी पहली प्रोग्रामिंग भाषा Clojure थी
    मैं OrgPad को Clojure+ClojureScript में बना रहा हूँ, और कोड 100k lines से ऊपर जाने के बाद भी मुझे लगता है कि यह एक अच्छा फ़ैसला था
    इसमें प्रवेश करना आसान है, और थोड़ा-सा कोड लिखने के बाद मुझे काफ़ी भरोसा रहता है कि यह वैसे ही काम करेगा जैसा मैंने सोचा है. Python, PowerShell, या Bash में मुझे ऐसा स्तर नहीं मिला; यह पूरी तरह अलग स्तर जैसा लगता है
    REPL workflow भी सचमुच बहुत अच्छा है, और मेरे एक सहकर्मी ने इस पर एक वीडियो बनाया है: https://www.youtube.com/watch?v=4igO7Qbyj9o
    आजकल ऐसे functions, छोटे tasks, और छोटे projects, जिनके लिए पहले Bash से Python पर जाने का सोचते, उन्हें भी Babashka/nbb से किया जा सकता है

  • जब मैंने पहले Clojure और ClojureScript में कुछ हज़ार lines लिखने की कोशिश की थी, तो सबसे बड़ी समस्या यह थी कि ज़्यादातर tools की error states काफ़ी बिखरी हुई थीं
    Python में भी कुछ ऐसा ही है, इसलिए ज़्यादातर Python programs को Ctrl+C से रोकने पर अनजान चीज़ों से भरा stack trace आ जाता है, लेकिन शुरुआत करने वाले के तौर पर आगे बढ़ना मुश्किल लग रहा था
    मुझे लगता है कि इस भाषा और ecosystem में बहुत-से नवाचारी और दिलचस्प ideas हैं. कम-से-कम Clojure के history paper को पढ़ना और उसके ज़्यादातर सबक आत्मसात करना काफ़ी मूल्यवान है
    यह सबको विधर्मी लगेगा, लेकिन मुझे लगता है कि एक छोटे ecosystem space में ऐसी scripting language की जगह है जो Clojure जितनी performance और code ergonomics को गंभीरता से ले, लेकिन जिसमें parentheses न हों
    nil को विशेष रूप से संभालने की परंपरा भी न हो तो अच्छा है, लेकिन कम-से-कम उसके पीछे कुछ आधार तो है
    मैं समझता हूँ कि (f x y) , f(x, y) से बेहतर है, लेकिन मेरी समस्या ज़्यादा उस स्थिति के करीब है जहाँ let forms indentation को मजबूर करते हैं. सिर्फ़ values को नाम देने के लिए indentation और parentheses, दोनों की कीमत चुकानी पड़े, ऐसा मुझे नहीं लगता
    अगर आप Python जैसी भाषा से आते हैं, जहाँ जो indentation आप वैसे भी कोड में डालते, वही जानकारी के रूप में इस्तेमाल होती है, तो कभी-कभी ये चीज़ें बस शोर जैसी लगती हैं

    • let forms का indentation पैदा करना ज़्यादा इस बात का संकेत है कि आप let का बहुत अधिक उपयोग कर रहे हैं
      functional style में functions के बीच पास होने वाले intermediate arguments को नाम देने की ज़रूरत अक्सर नहीं पड़ती
      आम तौर पर threading macros ->, ->> के ज़रिए arguments को implicitly अगले function में पास कर दिया जाता है, या transformations को pure functions के रूप में define करके top-level पर रखा जाता है
      हालाँकि, कुछ interop code में let की ज़रूरत ज़्यादा पड़ती है, यह मैं समझ सकता हूँ. खासकर उन Java JWT libraries में जो procedural chains में arguments को mutate करती हैं
    • Clojure या Python में REPL workflow इस्तेमाल करते समय कुछ चीज़ें गलती से सीखने को मिलती हैं
      जैसे लंबे समय तक debug करने के बाद यह समझ आना कि आपने reload या reinitialize ही नहीं किया था
      मुझे लगता है कि ज़्यादातर लोग इसे “ऐसा हो ही नहीं सकता” वाली स्थितियों में जाँचने की सूची में जोड़ लेते हैं. जैसे, “मेरे code changes सच में call हो रहे हैं या नहीं, यह देखने के लिए debug output डालते हैं”
      बेशक यह सिर्फ़ एक safety net है, और आम तौर पर मैं ऐसी स्थितियों से बचने के लिए दूसरी REPL आदतें अपनाने की कोशिश करता हूँ
    • इसे (+ clojure clojurescript) की तरह पढ़ा जाना चाहिए, ऐसा लगता है, और मेरा दिमाग़ इससे परेशान हो जाता है
  • Clojure बहुत-सी चीज़ें सही करता है, और इसी वजह से मुझे यह काफ़ी पसंद है
    लेकिन जब कोई वास्तविक टीम Clojure में वास्तविक web काम बनाती है, तो एक चीज़ जो गति कम करती है, वह है लगभग सिद्धांतवादी इच्छा कि ढेर सारी libraries को, जिनकी अपनी-अपनी शैली होती है, जोड़कर सब कुछ एक साथ बाँध दिया जाए
    मुझे लगता है कि अगर समुदाय अपने मौजूदा approach के अलावा, actively maintained, batteries-included, और सामान्य उपयोग के लिए उपयुक्त web framework भी रखे, तो Clojure कहीं ज़्यादा लोकप्रिय और इस्तेमाल में आसान हो सकता है. सोचता हूँ क्या Biff वह भूमिका निभाता है
    अच्छा होगा अगर उन लोगों के लिए भी एक वैकल्पिक रास्ता हो जो भाषा को पसंद करते हैं, लेकिन अपना खुद का monster जोड़कर बनाना पसंद नहीं करते
    शायद यह Ruby on Rails की आदत का असर भी है

    • बहुत-से लोगों के लिए Clojure की खूबी यही है कि वह चीज़ों को बेवजह बाँधता नहीं है
      यह वैसा ही approach है जैसा Rich Hickey की मशहूर talk में है: complect मत करो, compose करो: (https://github.com/matthiasn/talk-transcripts/blob/master/Hi...)
    • Biff batteries-included के काफ़ी करीब है, लेकिन इसके कुछ defaults मुख्यधारा से थोड़ा अलग हैं. यह SQL की जगह XTDB और HTMX/Hyperscript का उपयोग करता है, इसलिए नए लोगों के लिए यह फिर भी कठिन हो सकता है
      Clojure, graph database, और कुछ मामलों में HTMX तक सीखना काफ़ी कुछ है. फिर भी, बहुत-सी configuration पहले से की हुई मिलती है, authentication सोच-समझकर और आसान है, और server config files में comments भी अच्छे से लिखे गए हैं
      इसमें Linux server सेट करने और production REPL में SSH के ज़रिए प्रवेश करने के लिए deployment scripts भी हैं. अगर आप XTDB इस्तेमाल करना चाहते हैं, तो Biff का document validation configuration approach सचमुच बहुत अच्छा है
      निजी तौर पर, मुझे यह ClojureScript से चलने वाले apps से ज़्यादा पसंद है. React को wrap करने वाले ClojureScript wrappers बहुत हैं और यह लगभग meme बन चुका है, लेकिन एक React developer के रूप में मुझे इनमें से कोई भी React से आसान नहीं लगा
      उल्टा, ये ज़्यादा जटिल और कम स्वाभाविक लगे. वहीं HTMX/Hyperscript Clojure के साथ बहुत अच्छी तरह मेल खाते हैं, क्योंकि HTML syntax बस arrays और objects हैं जिन्हें संभालना आसान है
      यह पहली बार था जब Clojure प्रेमियों की बार-बार कही जाने वाली कहावत “code is data” सचमुच वास्तविक लगी
    • जैसा ऊपर भी लिखा, Luminus या Kit को देखना अच्छा रहेगा
    • जिन चीज़ों का मैंने उपयोग किया है, उनमें Biff मुझे सबसे ज़्यादा पसंद आया
  • पहले मैंने कई बार थोड़ा-थोड़ा OCaml इस्तेमाल करने की कोशिश की थी, लेकिन उसका बेहद सख्त type system मुझे पसंद नहीं आया।
    कोड लिखने से ज़्यादा समय compiler को संतुष्ट करने में जाता था। Clojure, Common Lisp, और C में compiler या type system को अपनी ज़रूरत के मुताबिक मोड़ने की आज़ादी ज़्यादा होती है।
    बेशक इसके फायदे और नुकसान दोनों हैं, लेकिन मैं कोड लिखते समय बाधित महसूस नहीं करना चाहता। यह शायद मेरी शैली हो, लेकिन ऐसे बहुत लोग मिले हैं जो ऐसा ही सोचते हैं।
    मेरा मानना है कि static type system पसंद का मामला है, और दूसरी तरफ़ के लोग अलग सोचते हैं। फिर भी, जब दो विरोधी खेमे होते हैं तो वे एक-दूसरे से बहुत कुछ सीखते हैं, इसलिए यह अच्छी बात है।
    Rich Hickey ने कई बार कहा है कि Clojure एक host language है, इसलिए ज़रूरत पड़ने पर Java या JavaScript तक नीचे जाना ठीक है।
    व्यक्तिगत रूप से, मुझे लगता है कि यही Clojure ecosystem की सबसे शक्तिशाली खूबियों में से एक है, क्योंकि यह बहुत अधिक व्यावहारिक है।
    मैंने बहुत बार देखा है कि लोग सिर्फ़ इसलिए उसी चीज़ को अपनी पसंद की भाषा में फिर से implement करने की कोशिश करते हैं क्योंकि वे “उस गंदी दूसरी भाषा में लिखी library” को छूना नहीं चाहते। वजहें अलग-अलग होती हैं: धीमी है, सुरक्षित नहीं है, लचीली नहीं है, वगैरह।
    ऐसा Common Lisp में भी अक्सर हुआ है, Rust community में भी हुआ है, और अब भी होता है।

    • type checking वास्तव में पसंद का मामला है। व्यक्तिगत रूप से, मुझे यह काफी पसंद है कि भाषा छोटी-मोटी गलतियों को रोक दे, इसलिए मैं Common Lisp कोड में बहुत से type declaration लिखता हूँ।
      SBCL उन declarations को जितना हो सके उतना enforce करता है, और शायद हर project में कुछ मिनटों का सिरदर्द बचा देता है।
      और CL बहुत व्यावहारिक है; उदाहरण के लिए, woo का C library पर आधारित होना किसी को भी ज़रा सा अजीब नहीं लगता।
    • Big Tech में high-reliability team का नेतृत्व करते समय मैं चाहता था कि काश कल ही हर जगह सख्त static types लगा दिए जाएँ।
      production की समस्याएँ सब छोटी और सूक्ष्म बातों से जुड़ी थीं। जैसे runtime upgrade के बाद JSON key order बदल गया और JSON को हाथ से parse करने वाला पुराना client टूट गया, या stack के गहरे हिस्से में कोई library HTTP code को string की बजाय integer में लौटाने लगी और error parsing टूट गई।
      हमारे scale पर यदि ग्राहकों का छोटा-सा प्रतिशत भी प्रभावित होता, तो सैकड़ों issue reports आ जातीं, इसलिए हर outage बहुत बड़ा मामला बन जाता था।
      अब मैं एक छोटे startup में काम करता हूँ और वहाँ स्थिति पूरी तरह अलग है। ध्यान और manpower उसी दिशा में थी, इसलिए हमने static language चुनी, लेकिन dynamic language के साथ काम करने के दिन याद आते हैं।
      जल्दी-जल्दी ship करने के चक्कर में code quality सच में खराब हो जाती है। समय की कमी के कारण type system से जूझने और साफ़ refactoring करने के बजाय, लोग एक ही object structure के थोड़ा-थोड़ा अलग कई copies बनाकर जगह-जगह इस्तेमाल करते हैं।
      type shape की वजह से generalization मुश्किल हो जाता है, इसलिए functionality को अलग करके कई जगह refer करने की बजाय वही logic 10 जगह copy/paste कर दी जाती है।
      मुझे लगता है कि अलग-अलग problem domains के लिए अलग समाधान सही होते हैं। अगर सूक्ष्म bugs के कारण रात में pager call आ सकती है, तो सख्त static types ज़्यादा सही होने की संभावना है।
      अगर तेज़ी से iterate करना है और समस्या एक email या Slack message से सुलझ सकती है, तो dynamic types बेहतर हो सकते हैं।
      असली हुनर यह है कि dynamic paradigm में इतना debt जमा न होने दिया जाए कि बाद में बढ़ने पर static paradigm में जाना मुश्किल हो जाए।
      अफ़सोस की बात है कि जिन भाषाओं के बहुत उत्साही प्रशंसक होते हैं, वे अक्सर “दूसरी भाषाओं की libraries इस्तेमाल नहीं करनी” वाले रवैये की ओर बह जाती हैं।
  • Clojure निस्संदेह मेरी सबसे पसंदीदा भाषा है और यह बहुत स्वाभाविक लगती है।
    लेकिन दूसरी भाषाओं की दो चीज़ें मुझे सच में बहुत याद आती हैं: समझ में आने वाले error messages और type hints।
    कंपनी में मुझे बड़े codebase को refactor करना पड़ा था, और वह काफ़ी दर्दनाक था। यह जानना मुश्किल होता है कि कौन-सा function exception फेंकेगा और कौन बस nil लौटाएगा; और यह भी समझना कठिन होता है कि कोई core function vector लौटाएगा, sequence लौटाएगा, या कोई और collection।
    spec, malli, और typed clojure जैसी projects इस समस्या को हल करने की कोशिश करती हैं, लेकिन वे मुझे Python या TypeScript के types के बराबर का विकल्प नहीं लगीं।

    • हो सकता है यह इसलिए हो कि मैं ऐसी आधुनिक भाषाओं का आदी हो चुका हूँ जिनमें ये सुविधाएँ हैं, या इसलिए कि जिन भाषाओं में ये नहीं थीं वे अब Python/TypeScript की तरह इन्हें बाद में जोड़ रही हैं, लेकिन मैं सच में सोचता हूँ कि लोग इसके बिना कैसे काम चला लेते हैं।
      जो भाषा यह नहीं बता सकती कि function में क्या जाता है और उससे क्या निकलता है, वह कुछ files से बड़े codebase में लगभग बेकार-सी लगती है।
      मौजूदा code को देखकर यह infer करने की कोशिश करना कि object के साथ क्या-क्या किया जा सकता है, अपने ऊपर खुद यातना लादने जैसा है।
  • अगर आप पहली बार Clojure देख रहे हैं, तो यह interactive tutorial देखना अच्छा रहेगा: https://tryclojure.org

    • https://4clojure.oxal.org/
      यह आसान स्तर से मध्यम और कठिन स्तर तक जाने वाला एक और बेहतर interactive learning set है।
  • Clojure मज़ेदार है

    • इस बात को कम आंका जाता है। यह शायद गैर-पेशेवर लगे, लेकिन मज़ा भी वही वजह है कि Basecamp और Ruby on Rails, Ruby में बनाए गए।
      Rails ने 2010 के दशक में web development पर राज किया, और उसी के ऊपर बहुत से बेहद सफल startups खड़े हुए।
      बहुत लोग engineers का मज़ाक उड़ाते हैं कि वे “खिलौनों से खेल रहे हैं”, लेकिन आज हमारे पास जो बहुत-सी अच्छी चीज़ें हैं, वे कभी न कभी खिलौने मानी जाती थीं। Linux भी इसका अच्छा उदाहरण है।
    • यह उस एहसास को पूरी तरह पकड़ लेने वाली बात है। मैंने पहले भी उस भावना पर लिखा है [1]
      बहुत “मज़ेदार” भाषा की मुश्किल यह है कि आप मानने लगते हैं कि हर समस्या उसी भाषा से हल की जा सकती है।
      नतीजा यह होता है कि आप बहुत सारा code लिखते जाते हैं, जबकि बाद में देखने पर शायद code न लिखना भी काफ़ी ठीक समाधान होता।
      [1] https://franz.hamburg/writing/clojure-makes-happy.html