Haskell को पीछे छोड़कर आगे बढ़ना
(journal.infinitenegativeutility.com)- लगभग 2009 से 2019 तक Haskell को मुख्य भाषा के रूप में इस्तेमाल करने वाले एक programmer ने अब personal projects और job search में Haskell को default choice के रूप में रखना छोड़ दिया है
- Haskell का आकर्षण monads या DSL अपने-आप में नहीं, बल्कि algebraic code reasoning, strong type system से मिलने वाली safe refactoring और invariants को express करने में था
- इससे दूर होने की वजहें थीं advanced type features को पसंद करने वाली culture, smooth न लगने वाले tools, और GHC व standard library में लगातार incompatible changes का जमा होता असर
- फिर भी higher-order functions,
donotation, lenses, declarative libraries और advanced type abstractions ऐसी खूबियां बनी हुई हैं जिन्हें दूसरी languages आसानी से replace नहीं कर पातीं - बेहतर programmer बनने के लिए Haskell सीखना बहुत valuable है, लेकिन किसी organization की default language बनाने के लिए tool quality और language stability की cost उठानी पड़ती है
Haskell को default language की तरह इस्तेमाल करने का दौर और आज की स्थिति
- करीब 10 साल तक Haskell नए projects की default language रही
- लगभग 2009 में Haskell से परिचय होने के बाद, 2019 के आसपास Ruby और C++ का मुख्य रूप से इस्तेमाल करने वाली job में जाने तक, लेखक खुद को Haskell programmer मानता था
- command-line tools, web services, graphics applications, छोटी scripts जैसे कई use cases में Haskell का इस्तेमाल किया गया
- अब Haskell को पूरी तरह reject नहीं किया गया है, लेकिन personal projects में भी यह default language नहीं है और पहले की तरह जानबूझकर “Haskell job” भी नहीं खोजी जाती
- यह फैसला Haskell खराब है, ऐसा निष्कर्ष नहीं है; बल्कि personally Haskell से दूर होने की वजहों के ज्यादा करीब है
Haskell की ओर आकर्षित करने वाली बातें
-
code को algebraic तरीके से handle कर पाने की प्रकृति
- Haskell का सबसे बड़ा आकर्षण यह था कि code के बारे में symbolic और algebraic तरीके से reason किया जा सकता है
- उदाहरण के लिए, अगर
double n = n + nनाम का function है, तोdouble xकोx + xमें बदलना Haskell में हमेशा सही transformation है - कई imperative languages में
double(i++)और(i++) + (i++)अलग तरह से काम कर सकते हैं- पहला
iको एक बार increment करता है - दूसरा
iको दो बार increment करता है
- पहला
- इस गुण के कारण छोटे mechanical transformations को जोड़कर बड़ी refactoring ज्यादा safely की जा सकती है
- Ruby codebase की बड़ी refactoring बहुत अस्थिर/डरावनी लग सकती है, लेकिन Haskell codebase में यह काफी आसान हो सकती है
-
सख्त लेकिन बहुत ज्यादा noisy नहीं type system
- Haskell का type system strict है, लेकिन type inference की वजह से Java की तरह बहुत ज्यादा type annotations नहीं चाहिए होते
- typeclasses उन situations में भी झंझट कम करते हैं जहां types का ध्यान रखना पड़ता है
- अच्छा Haskell code “अच्छी तरह टूटने वाला (brittle)” गुण रखता है
- गलत abstraction चुपचाप मुड़कर गलत program को allow नहीं करता
- समस्या होने पर compilation fail हो जाता है
NonEmptytype ऐसी list को represent करता है जिसमें कम से कम एक element होता हैmapजैसी length-preserving operationsNonEmptyreturn करती हैंappendजैसी length बढ़ाने वाली operations भीNonEmptyreturn करती हैंfilterजैसी operations, जिनका result empty हो सकता है, normal list return करती हैं
- जिस function को file paths की list
NonEmptyचाहिए, उसमें command-line arguments सीधे pass नहीं किए जा सकते; पहले यह check करना पड़ता है कि वे empty नहीं हैं - बाद में extension filtering step जोड़ने पर result empty हो सकता है, इसलिए फिर से check करना पड़ेगा, और compiler गलती से empty list pass करने वाले path को रोक देता है
-
types के जरिए invariants बनाए रखने का तरीका
- Haskell लंबे समय तक इस्तेमाल करने पर program के invariants को types में express कराकर compiler से verify करवाने की आदत हो जाती है
- इसका मतलब केवल complex type-level computation नहीं है
- SQL escaping हुआ है या नहीं, इसे
RawStringऔरSanitizedStringजैसे wrapper types से अलग किया जा सकता है- web API भले ही
RawStringदे, database layer को केवलSanitizedStringaccept करने के लिए बनाया जा सकता है
- web API भले ही
- कई
Maybefields वाली surface representation को ऐसी internal representation में बदला जा सकता है जहां required information मौजूद होने की guarantee हो - इतना ही generic बनाना भी संभव है कि independent testing हो सके
-
DSL और higher-order functions के लिए natural language
- Haskell में macros के बिना भी concise domain-specific languages बनाना आसान है
- config-ini INI configuration files handle करने वाली library का उदाहरण है
- imperative parsing interface के बजाय declarative interface इस्तेमाल करता है
- configuration type के किसी खास हिस्से को INI file structure के किसी खास हिस्से से map करता है
- उसी interface से reading, writing और diff-minimal update करता है
- Ruby DSL dynamic metaprogramming और global monkeypatching पर depend कर सकते हैं, लेकिन Haskell DSL flexible syntax और monad overloading जैसी capabilities से किसी खास file या code area तक सीमित रखना आसान बनाते हैं
- Haskell higher-order functions के साथ काम करना भी natural बनाता है
(+)को सीधे दो numeric arguments लेकर उन्हें add करने वाले function की तरह इस्तेमाल किया जा सकता हैpairwiseProduct = zipWith (*)की तरह दो lists के element-wise multiplication को बहुत short form में express किया जा सकता है
- Haskell के लिए यह analogy सही लगती है कि जैसे Perl strings को handle करना आसान बनाता है, वैसे Haskell functions को handle करना आसान बनाता है
Haskell से दूर होने के तीन कारण
-
कठिन/जटिल style को पसंद करने वाला माहौल
- पहला कारण style में नई तकनीकों को प्राथमिकता देना है
- Haskell community लगातार नई abstractions के साथ experiment और build करती रहती है
- abstract algebra या category theory से लिए गए approaches
- ज्यादा computation को type level पर उठाकर invalid states को restrict करने का approach
- Servant का type-level web API या comonad से menu system express करने का case, problem domain को नए तरीके से express करने के experiments हैं
- लेकिन everyday code में ऐसे experimental approaches शुरुआती तौर पर दिखने वाले benefits से ज्यादा problems पैदा कर सकते हैं
- compiler project के एक उदाहरण में AST nodes के पास expression type type parameter के रूप में था
- type error वाला syntax tree बनाने पर compiler खुद compile नहीं होता था
- शुरुआत में इसने कुछ bugs पकड़े
- जब कई optimization passes type discipline से match नहीं करते थे, तो casting और GHC को मनाने से code complex हो गया
- आखिर में AST से type parameter हटा दिया गया
- “fancy types” approach आजमाने वाले projects में से लगभग तीन-चौथाई में value पर्याप्त नहीं लगी
- Simple Haskell movement इस विचार पर आधारित है कि experimental features से बचकर minimal extensions तक रहने पर language के benefits सबसे ज्यादा मिलते हैं
- ज्यादा complex type features community और libraries में व्यापक रूप से फैले हुए हैं
- complex type abstractions changes और maintenance को मुश्किल बना सकती हैं, और simplified abstraction को फिर से latest type-level abstraction में बदलने की कोशिश code size बढ़ने, performance घटने और readability कम होने तक पहुंची है
- हालांकि Trees that Grow जैसी compiler stages के हिसाब से indexed data structures एक useful “fancy type-level feature” example के रूप में बची हुई हैं
-
रोजमर्रा के काम में चमक न दिखा पाए tools
- दूसरा कारण awkward tooling system है
- Haskell में standard के करीब माने जाने वाले कई build systems और development tools हैं
- ये tools आम तौर पर जरूरी काम तो कर देते हैं, लेकिन “प्यार करने लायक” level के नहीं थे
ormoluजैसे कुछ tools minimal hassle के साथ अपना काम करते थे, लेकिन कुछ tools में लगातार bugs और workarounds चाहिए होते थे- Haskell tooling 10 साल में बेहतर हुई, लेकिन 2019 तक Rust Cargo की usability और stability के करीब कोई tool नहीं था
- कुछ नया और बेहतर बनाते रहने की Not-Invented-Here tendency भी समस्या थी
- package text format तक को hpack से दोबारा handle करने का trend है
- ऐसे प्रयासों का कई सालों तक 95% complete state में रहना frustrate करता है
- Haskell tools बेहद खराब हैं, ऐसा आकलन नहीं है, लेकिन “ठीक-ठाक” बढ़े हुए standards को पूरा नहीं करता
-
लगातार incompatible changes
- तीसरा कारण Haskell language और GHC में होने वाला लगातार बदलाव है
- GHC को practically Haskell की एकमात्र reasonable public implementation माना जाता है
- Haskell standard library और language के basic parts में भी past mistakes और inconsistencies को धीरे-धीरे ठीक करने की कोशिश करता है
- ऐसे changes language को ज्यादा clean और consistent basic elements की तरफ ले जा सकते हैं, लेकिन users के लिए लगातार छोटे friction बनाते हैं
- 2015 के Foldable-Traversable Prelude changes ऐसे बदलाव का example हैं
- पुराने Haskell projects external dependencies न होने पर भी latest GHC में build नहीं हो सकते
- superclass जोड़ना
- import हटाना
- ambiguity बढ़ी polymorphism की वजह से type signatures जोड़ना
- fixes आम तौर पर छोटे होते हैं, लेकिन जमा होते रहते हैं, और पहले से थोड़ा-थोड़ा अलग हुए हिस्से user का ध्यान मांगते हैं
- Rust का epochs update approach stable features के लिए backward-compatibility contract को explicit करता है और intentional breaking changes को epoch के पीछे छिपाने के तरीके के रूप में contrast करता है
Haskell की वे खूबियां जो अब भी याद आती हैं
- Haskell की algebraic code writing और refactoring अब भी strength है
- Rust भी Haskell के साथ कई strengths share करता है, लेकिन छोटे mechanical refactorings program semantics preserve करेंगे, यह confidence Haskell जितना आसान नहीं है
- type system भी ऐसी capabilities देता है जो दूसरी languages में आम तौर पर नहीं होतीं
- 2023 की mainstream languages में static typing capabilities 2009 की तुलना में काफी आगे बढ़ चुकी हैं
- फिर भी higher-kinded types पर abstractions जैसी capabilities Haskell की differentiator हैं
- Haskell library ecosystem mixed है
- आधी-अधूरी maintain की जाने वाली open-source libraries
- individual authors की अपनी तरह से दुनिया फिर से बनाने वाली छोटी kingdoms
- जरूरी लेकिन अलग-अलग string-like types
- फिर भी Haskell में ऐसी शानदार libraries और abstractions हैं जो दूसरी languages में आधे-अधूरे रूप में ही संभव हैं
- lenses एक powerful abstraction हैं, जिनके benefits पर्याप्त इस्तेमाल किए बिना साफ नहीं दिखते
- Brick declarative blocks से बहुत अच्छी terminal UI library देता है
- diagrams और music-suite भी declarative APIs के अच्छे examples हैं
donotation भी बहुत याद आने वाली capability है- core point
doखुद से ज्यादा वह notation है जिसमें bindings जोड़ने पर indentation level लगातार नहीं बढ़ता - Ruby का nested
flat_mapहर axis बढ़ने पर indentation को गहरा कर देता है - Haskell की
donotation उसी combination को flat तरीके से express करती है
- core point
donotationasync/awaitstyle structured concurrency, concurrent transactions, probabilistic programs को उसी lightweight syntax से embed करना संभव बनाती है
Haskell सीखनी चाहिए या इस्तेमाल करनी चाहिए?
- “क्या यह language सीखनी चाहिए, क्या इस्तेमाल करनी चाहिए” का जवाब goal पर depend करता है
- अगर लक्ष्य बेहतर programmer बनना है, तो Haskell सीखना बहुत valuable है
- Haskell एक interesting और powerful language है
- Haskell सीखने के अनुभव ने programming ability बढ़ाई, ऐसा आकलन है
- अगर लक्ष्य real-world use है, तो ज्यादा सावधानी चाहिए
- Haskell के advantages सच में मौजूद हैं
- इन्हें इस बात से compare करना चाहिए कि individual या organization ऊपर बताए frictions कितना सह सकता है
- ऐसे individuals और organizations भी मौजूद हैं जो Haskell से पर्याप्त benefit पाकर छोटी inconveniences को minor wounds तक सीमित रखते हैं
- अगर साफ हां/नहीं पूछा जाए, तो जवाब “Haskell इस्तेमाल न करें” के करीब है
- अगर engineering organization बनाई जाए, तो Haskell को default language के रूप में नहीं रखा जाएगा
- क्योंकि अच्छे tools की value और खराब tools की cost, दोनों पता हैं
- ऐसी language prefer की जाएगी जो stable language, clear code ecosystem और excellent tooling तुरंत दे सके
- फिर भी Haskell program safety और correctness के लिए शानदार tools देता है
- कुछ contexts में खराब tooling और unnecessary type family को रोकने वाली linting को tolerate करना worth it हो सकता है
- Haskell अब personally suitable language नहीं है, लेकिन निष्कर्ष यह है कि अगर Haskell दुनिया में मौजूद न होता, तो दुनिया ज्यादा खराब होती
1 टिप्पणियां
Hacker News की टिप्पणियां
Haskell को करीब 10 साल इस्तेमाल करने के बाद हाल ही में रोज़ी-रोटी के तौर पर उससे बाहर निकला हूं, और लेखक की पहली बात से मैं निश्चित रूप से सहमत हूं: Haskell समुदाय सीखने को बहुत गहराई से महत्व देता है
जिज्ञासु लोगों के साथ काम करते हुए हमेशा सिखाने और सीखने के लिए कुछ न कुछ होना अच्छी बात है, लेकिन आज़माए गए ideas को छोड़ने में यह समुदाय थोड़ा कमजोर है, इसलिए professional Haskell codebase में, अगर सख्ती से रखरखाव न किया जाए, तो “कर तो सकते हैं, लेकिन न करना बेहतर है” जैसी चीजें बहुत जमा हो जाती हैं
हालांकि toolchain को लेकर मेरी राय अलग है। यह सही है कि Haskell tools खास अच्छे नहीं हैं, लेकिन Python, JS, Java, Rust, Elm इस्तेमाल करके देखा तो ज्यादातर tools भी खास अच्छे नहीं थे, और उलटे Haskell toolchain की याद आई। cargo शानदार है, लेकिन वह अपवाद जैसा है, और यह जानने की उत्सुकता है कि Rust के पुराना हो जाने के बाद भी क्या वह इस स्थिति से बच पाएगा
एक project है जिस पर कभी-कभार काम करता हूं, और 100% यकीन है कि अगली बार खोलूंगा तो वह फिर नहीं चलेगा। Python का dependency और virtual environment management भी इसी तरह खराब है, लेकिन Poetry काफी ठीक लगा, और Ruby में chruby/rbenv/rvm में से कुछ भी इस्तेमाल करें, लगभग अच्छी तरह काम करता है और Bundler भी ठीक चलता है। Java में कमियां हैं, फिर भी IDE experience top स्तर का है, और refactoring Haskell जितनी सुरक्षित न सही, लेकिन बहुत आसानी से की जा सकती है
Bundler कुल मिलाकर बुरा नहीं है, और भले ही कुछ design choices से असहमति हो, सही रास्ते पर चलें तो बहुत कुछ सही बैठ जाता है। language tools भी पर्याप्त रूप से कम टूटे हुए तरीके से बनाए जा सकते हैं, और cargo को मैंने खुद बहुत ज्यादा इस्तेमाल नहीं किया है, लेकिन अगर वह सचमुच अपनी श्रेणी में सबसे अच्छा है, तो उसका वैसा बने रहना आश्चर्यजनक नहीं होगा
tools के मामले में Haskell के पास, जहां तक मुझे पता है, एक ऐसी चीज है जिससे दूसरी भाषाओं का मुकाबला करना मुश्किल है: Hoogle
Hoogle हैरान कर देने वाला शानदार है। आप Haskell में बताते हैं कि क्या चाहते हैं, और यह बताता है कि Haskell में क्या किया जा सकता है। Rust में भी इसी तरह की कोशिशें हुई थीं और Nim के लिए Noogle बनाने की भी कोशिश की थी, लेकिन जिन भाषाओं में “function को arguments पास करना” और “function को call करना” साफ तौर पर अलग हैं, वहां यह उसी तरह काम नहीं करता
Result,Boxसे उलझे Rust code को हर बार देखते हुए लगता है कि Hoogle जितना उपयोगी Roogle होता तो अच्छा होता। इसके अलावा Haskell tools में कोई खास मजबूती नहीं है। काफी हद तक यह समुदाय की उस प्रवृत्ति की वजह से लगता है कि मौजूदा चीजों को सुधारने के बजाय कोई “innovative” चीज बनाई जाएयह perfect नहीं है, लेकिन 5 साल पहले की तुलना में बहुत बेहतर है
अच्छा होगा अगर और projects इस दिशा को अपनाएं
मुझे लगता है सबसे बड़ी समस्या यह है कि GHC standard library के किसी खास
baseversion से बंधा हुआ हैजब
baseबदलता है और नया GHC version सिर्फ उसी version को support करता है, तो नया GHC इस्तेमाल करने के लिए असल में लगभग सभी dependencies बदलनी पड़ती हैं। मैं अब भी नहीं समझ पाया कि GHC 9.6 से compile किया गया codebase4.18.0.0 ही क्यों इस्तेमाल करे। GHC binary को compile होने वाले code केData.Listmodule के version से क्या फर्क पड़ना चाहिएbaseजो GHC-specific elements expose करता है उनका किसी खास GHC version से बंधना समझ में आता है, लेकिन बाकी सबको भी वैसा होना चाहिए या नहीं, पता नहीं। हालांकि मेरी समझ है कि इसे ठीक करने के लिएbaseको कई packages में बांटने का काम चल रहा है: https://gitlab.haskell.org/ghc/ghc-wiki-mirror/-/blob/master...basecode को invalid बताकर reject कर सकता हैbaseimplementations से linked librariesData.Listinstances एक-दूसरे को पास करें, तो समस्या होगीउदाहरण के लिए, जब
Data.Listकी list हो, तो क्या आप दो अलग-अलग library functions के results को उस list में जोड़ पाएंगेbaseवह लक्ष्य है जिसे सभी चाहते हैं। मौजूदा स्थिति की बड़ी वजह historical reasons और compiler internals से बंधे primitive elements का non-primitive elements के साथ जुड़ जाना है, और पर्याप्त प्रयास से इसमें सुधार हो सकता हैHaskell में दिलचस्पी धीरे-धीरे कम होने के तीन बड़े कारण अगर बताने हों, तो वे थे: style में novelty को तरजीह जो उलझे हुए code की तारीफ कर maintenance को मुश्किल बनाती है, रोज़मर्रा के काम को और सुस्त बनाने वाले अटपटे tools, और कभी-कभार लेकिन लगातार ध्यान मांगने वाले, नियमित रूप से चीज़ें तोड़ देने वाले निरंतर बदलाव
यह वाजिब बात है। 2010–2012 में मैंने Haskell काफी सीखा था; भाषा खुद शानदार थी, लेकिन documentation और tools संभालना मुश्किल था। Community Cabal और कुख्यात Cabal hell से Stack पर गई, फिर वापस Cabal पर लौट आई, और कुल मिलाकर चीज़ें बेहतर हुईं
दूसरी तरफ, दूसरी programming languages ने भी functional programming के तत्व अपना लिए। उदाहरण के लिए Java ने Streams, functions, lambdas, algebraic data types, records और pattern matching जोड़े, और syntax भले Haskell जितना elegant न हो, functional programming की basic concepts उसमें मौजूद हैं
इस तरह उन्होंने अपने लिए अंतहीन पीड़ा का गड्ढा बना लिया, और यह बस इसलिए किसी तरह सहने लायक हो पाया क्योंकि रोशनी की किरण इतनी नीचे नहीं आती कि खिड़की के बाहर पेड़ पर रोशनी से बनते रंग दिख सकें। बाहर से आने वाले लोग अपनी बनाई अंधेरी जगहों के अनुरूप बोली और रोशनी में फल-फूल सकने वाली, लेकिन वहां दम घोंट देने वाली बोली के बीच फटते हुए जल्दी ही अपना होश खो बैठते हैं
अगर community फिर Cabal पर लौट आई है, तो जानना चाहूंगा कि मुझसे क्या छूट गया
इन्हीं वजहों से मैं F# पर चला गया और फिर ज्यादा पीछे मुड़कर नहीं देखा। कभी-कभी higher-kinded types की कमी खलती है, लेकिन F# में भी generics हैं, और सच कहूं तो यह Haskell की तुलना में ज्यादा simple code लिखने पर मजबूर करता है, जिससे आम तौर पर नतीजा बेहतर होता है
हालांकि F# Haskell जैसा “expert वाला एहसास” नहीं देता। यह Haskell जैसा है, लेकिन पूरी तरह practical है। F# से मैं बहुत काम निपटाता हूं और इसे मज़े से इस्तेमाल करता हूं, लेकिन कभी-कभी उदासी से सोचता हूं कि Haskell के साथ बात क्यों नहीं बनी
अक्सर सोचता था कि Haskell न इस्तेमाल करने से कहीं कुछ miss तो नहीं कर रहा, लेकिन मेरे मकसद के लिए शायद ऐसा नहीं है
Haskell सीखना किसी alien भाषा को decode करने जैसा है। अगर आप सामान्य if-else loops और simple variable assignment के आदी हैं, तो दिमाग उलझने के लिए तैयार रहिए
monad कोई cosmic monster नहीं, बल्कि एक अजीब abstraction है, जो आपको सिर खुजलाते हुए अपने जीवन के फैसलों पर शक करवा सकता है। Libraries में भी जो चाहिए उसे ढूंढना किसी आधी खाली second-hand दुकान में खंगालने जैसा लगता है, और documentation का आधा हिस्सा hieroglyphs जैसा पढ़ता है
Performance भी असल दुनिया में lazy evaluation की वजह से उम्मीद से ज्यादा memory खा सकती है, और आप देर तक सोचते रह सकते हैं कि यह धीमा क्यों हो रहा है। Jobs भी मिलना मुश्किल है, जब तक कोई बहुत niche कंपनी न हो जो Haskell पर पूरी तरह all-in हो, और debugging functional hieroglyphs के ढेर में सुई ढूंढने जैसी लगती है
मैं Scala इस्तेमाल करता रहा हूं, और मुझे लगता है कि यह दोनों दुनिया की खूबियां दे सकता है। आप algebraic तरीके से reasoning कर सकते हैं, और refactoring के बाद compile हो जाए तो आम तौर पर काम करता है
Type inference और monads भी अच्छी तरह काम करते हैं, और Java ecosystem के फायदे भी मिलते हैं। जब चीज़ें बहुत obscure होने लगें, तो rules तोड़कर Java के करीब code भी लिख सकते हैं। जानना चाहूंगा कि बाकी लोग क्या सोचते हैं
हालांकि sbt पागल कर देता है, और developer experience में शायद यही हिस्सा मुझे सबसे कम पसंद है
Haskell के governing bodies और maintainers सच में ऐसा लगते हैं कि वे इस language को research, experimentation और academic exploration के अनुकूल रखना चाहते हैं
अपने-आप में यह ठीक है, लेकिन किसी बिंदु पर यह Haskell को practical और stable tool की तरह इस्तेमाल करने वाले programmers के हितों से टकराएगा ही। जरूरत यह लगती है कि experimental और cutting-edge चीज़ों को अलग track के रूप में mark करने की क्षमता हो। चाहे pragma हो या package-level declaration, package देखते ही पता चलना चाहिए कि उसे खींचना है या नहीं
तब practice-oriented developers “हम केवल stable Haskell इस्तेमाल करते हैं” जैसी policy अपना सकते हैं। “Avoid success at all costs” वाली dynamics को मानते हुए कि अगर Haskell adoption बहुत बढ़ जाए तो language inertia में फंसकर cutting-edge concepts को आगे नहीं बढ़ा पाएगी, रोज़मर्रा के developers के लिए Haskell के ज्यादा limited और stable subset में रहने का official track चाहिए
Java को ऐसी चीज़ कभी नहीं मिलेगी। https://www.stackage.org/
आखिर में simplicity देखने वाले पर निर्भर करती है। Fancy type features भी, अगर आपने उनके काम करने का तरीका आत्मसात कर लिया है, तो types को ज्यादा expressive बनाने, code को ज्यादा safe और यहां तक कि ज्यादा simple बनाने में इस्तेमाल हो सकते हैं
काफ़ी अच्छा लेख है। बस इसकी कमज़ोर बात यह है कि अगर मैं नहीं चाहता, तो किसी खास नए और चमकदार type feature को इस्तेमाल करने के लिए धक्का दिए जाने जैसा दबाव मुझे कभी महसूस नहीं हुआ
अगर आपको Servant का type-level HTTP API पसंद नहीं है, तो एक स्तर नीचे जाकर warp इस्तेमाल कर सकते हैं। लाइब्रेरीज़ समझती हैं कि बहुत ज़्यादा जटिल types जाल बन सकते हैं, इसलिए वे अक्सर इसी तरह layers में बनी होती हैं। कहाँ तक जाना है, इसकी intuition चाहिए, और इस प्रक्रिया में गलतियाँ भी शामिल होती हैं
मैंने Servant docs पढ़े थे, लेकिन स्वाभाविक रूप से वे मेरी तुलना में ज़्यादा Haskell समझ को मानकर चल रहे थे
यह लेख सचमुच मेरे अनुभव से मेल खाता है। मैं करीब 1.5 साल से एक काफ़ी industrial application में Haskell इस्तेमाल कर रहा हूँ, और उससे पहले भी https://github.com/mattgreen/hython जैसे अनुभव काफ़ी थे
20 साल के करियर में लंबे समय बाद मुझे काफ़ी कुछ सीखना पड़ा, और यह domain और language के संयोजन का नतीजा है। यह रोमांचक भी है और थकाने वाला भी, और व्यस्त पारिवारिक जीवन के साथ संभालने के लिए शायद काफ़ी बड़ा हिस्सा है
फिर भी language शानदार है। मेरे manager आम तौर पर इसे top-down तरीके से लिखने की सलाह देते हैं; मतलब यह कि Haskell की flexibility development intent को अच्छी तरह व्यक्त करती है, इसलिए गहराई से सोचो कि इसे कैसे पढ़ा जाना चाहिए और वहीं से शुरू करो। ज़्यादातर languages में बार-बार
functionटाइप करते हुए दिमाग़ के power-saving mode में चले जाने की तुलना में यह सोचने का बड़ा बदलाव है, और सचमुच लगता है कि इसे लिखने के लिए friendly बनाया गया हैलेकिन controlled effects को monad से संभालने पर भी syntax अब भी सरसरी तौर पर पढ़ना मुश्किल है। शायद इसकी वजह यह है कि एक line बहुत dense हो सकती है। early return की बहुत याद आती है, और Rust का शानदार LSP भी याद आता है। Haskell ने 9.x internal changes की वजह से pattern match भरने वाला feature भी हाल में खो दिया है, और monads को stack करना अब भी मुझे नापसंद है और उसमें अक्सर गलती हो जाती है। compile time खासकर lens library से सामना होने पर काफ़ी कठोर हो सकता है
default lazy evaluation भी मुझे पसंद नहीं है। community भी कुछ हद तक मान चुकी है कि इस default की वजह से Haskell programs space leaks के लिए कहीं ज़्यादा susceptible होते हैं, और कई programs में ये काफ़ी लंबे समय तक detect नहीं हो सकते। system programmer के तौर पर यह चीख निकलवा देता है
फिर भी community उन सबसे मजबूत programmer groups में से एक है जिन्हें मैंने देखा है। मैं meme की तरह उनके बहुत smart होने की बातें नहीं करना चाहता; बड़ी बात यह है कि वे सचमुच गहराई से सोचते हैं और आगे धकेलते हैं। हमारे domain, यानी program analysis, में Haskell बिल्कुल glove की तरह fit बैठता है, लेकिन बाकी क्षेत्रों में मैं अब भी थोड़ा सतर्क हूँ। मूल रूप से OCaml जैसा लेकिन बेहतर syntax वाला programming language पाने की प्यास अब भी है
interface में ExceptT expose करने की ज़रूरत भी नहीं है; इसे सिर्फ़ internally early return के लिए इस्तेमाल करके function से Either return करवा सकते हैं
अंत में उसे बड़ी traction न मिल पाना अफ़सोस की बात है
OCaml की तुलना में object-oriented और functional programming का integration बेहतर है, और idiomatic OCaml code इतना मिलता-जुलता है कि simple conversion से port करना आसान है