18 पॉइंट द्वारा GN⁺ 2025-04-22 | 11 टिप्पणियां | WhatsApp पर शेयर करें
  • Pipelining प्रोग्रामिंग भाषाओं में कोड की पठनीयता और maintainability बढ़ाने वाली एक महत्वपूर्ण सुविधा है
  • यह डेटा फ्लो को बाएँ से दाएँ, ऊपर से नीचे स्वाभाविक रूप से व्यक्त करने देता है
  • Rust जैसी भाषाओं में pipelining कोड के flow को स्पष्ट बनाती है, और IDE की autocomplete सुविधा के ज़रिए डेवलपर उत्पादकता बढ़ाती है
  • Haskell, Elm, SQL जैसी कई भाषाओं में इसका उपयोग होता है, और builder pattern या method chaining को भी pipelining का एक रूप माना जा सकता है
  • पठनीयता, संपादन की सुविधा, IDE support, version control tools (diff, blame) — इन सभी पर इसका सकारात्मक प्रभाव पड़ता है
  • nested functions की तुलना में यह अधिक संक्षिप्त और स्पष्ट कोड लिखने देता है, इसलिए collaboration और maintenance के लिहाज़ से भी फायदेमंद है

मेरा सबसे पसंदीदा प्रोग्रामिंग सिंटैक्स: Pipelining

Pipelining क्या है?

  • यह ऐसी सुविधा है जिसमें पिछले मान को आगे भेजकर parameter list में एक argument छोड़ा जा सकता है
  • यह कोड की पठनीयता बढ़ाती है और comments जोड़ना आसान बनाती है
  • यह data-केंद्रित लगातार होने वाले processing steps को क्रमवार लागू करने वाली syntax style है
  • functional style code में .map().filter().collect() जैसी method chaining के रूप में इसका खूब उपयोग होता है
  • Rust में नीचे दिया गया कोड इसका एक प्रतिनिधि उदाहरण है:
    data.iter()  
        .filter(|w| w.alive)  
        .map(|w| w.id)  
        .collect()  
    
  • इसके विपरीत, अगर सभी functions को nest कर दिया जाए, तो संरचना ऐसी बनती है जिसे अंदर से बाहर की ओर पढ़ना पड़ता है:
    collect(map(filter(iter(data), |w| w.alive), |w| w.id))  
    

Pipelining अच्छी क्यों है?

  • 1. पठनीयता और maintainability

    • ऊपर से नीचे पढ़ना आसान → डेटा फ्लो इंसान के पढ़ने के क्रम जैसा
    • हर लाइन पर comments लगाना आसान
    • लंबी लाइनों में parentheses nesting के बिना संक्षिप्त और स्पष्ट
  • 2. संपादन की सुविधा

    • बीच में .map() जैसी नई function को आसानी से एक लाइन में जोड़ा जा सकता है
    • git diff या git blame में भी बदलावों को साफ़-सुथरे ढंग से ट्रैक किया जा सकता है
  • 3. IDE / LSP support

    • . key दबाने पर autocomplete list दिखने वाली संरचना के साथ यह अच्छी तरह मेल खाती है
    • static analysis के लिए अनुकूल, क्योंकि उसमें types का स्पष्ट पता होना चाहिए
    • यह सुविधा सही से काम करे, इसके लिए भाषा का static type-based होना ज़रूरी है (e.g. Rust, TypeScript)

क्या SQL में भी pipelining है?

  • SQL की nested SELECT queries को pipeline style में बदलने का एक प्रस्ताव मौजूद है
  • उदाहरण:
    FROM customer  
    |> LEFT OUTER JOIN orders ON ...  
    |> AGGREGATE COUNT(...) GROUP BY ...  
    |> ORDER BY ...  
    
  • मौजूदा SQL की तुलना में अधिक स्पष्ट flow, बेहतर पठनीयता
  • कमी: SELECT statement ऊपर चले जाने से return type समझना मुश्किल हो सकता है → इसका समाधान संभव है

Builder pattern से संबंध

  • Rust में Builder::new().option().option().build() जैसी संरचना एक पारंपरिक pipeline structure है
  • optional settings को methods के रूप में बनाते हुए code tracking और change management आसान हो जाता है

Haskell में pipelining का सुधार

  • Haskell के $, &, |> जैसे operators function composition के बजाय pipeline का उपयोग संभव बनाते हैं
  • पहले और बाद की तुलना:
    -- 기존  
    checkPalindromes content = unlines $ map (show . isPalindrome) $ lines $ map toLower content  
    
    -- 개선  
    checkPalindromes content =  
      content  
        & map toLower  
        & lines  
        & map (show . isPalindrome)  
        & unlines  
    

Rust में pipelining के फायदे

  • method chaining, type inference, trait-आधारित structural extensibility — ये सब pipelining के साथ बहुत अच्छी तरह मेल खाते हैं
  • Rust की संरचना functional और object-oriented syntax के बेहतरीन पक्षों का मिश्रण जैसी लगती है, इसलिए pipelining का उपयोग इसमें सबसे स्वाभाविक लगता है

निष्कर्ष

  • Pipelining सिर्फ़ एक साधारण syntax नहीं, बल्कि कोड flow, editability और collaboration तक को प्रभावित करने वाली core सुविधा है
  • f(g(h(x))) जैसी nesting की जगह x |> h |> g |> f संरचना ज़्यादा human-friendly है
  • Pipelining, “एक लाइन में एक काम” जैसे सरल नियम के तहत, स्वाभाविक flow व्यक्त करने का सबसे बेहतरीन तरीका है

“pipeline का हर हिस्सा मुख्य data को लेकर एक काम करता है। अंत में उसे एक स्पष्ट नाम दे दिया जाए, तो वही सबसे आदर्श code structure है।”

11 टिप्पणियां

 
progdesigner 2025-04-23

किसी भी टेक्स्ट में
लाइन ब्रेक और इंडेंटेशन का पठनीयता के लिए महत्वपूर्ण होना
शायद कुछ वैसा ही संदर्भ है।

 
forgotdonkey456 2025-04-23

LINQ सबसे बेहतरीन है!

 
bus710 2025-04-23

Gleam भी इसे support करता है, इसलिए काफ़ी साफ़-सुथरे तरीके से code लिखा जा सकता है.

वैसे, शायद main text में code block होने की वजह से, mobile पर भी यह desktop layout में दिख रहा है.

 
bus710 2025-04-23

सोचता हूँ तो elm में भी यह होता है।

 
galadbran 2025-04-22

कम मात्रा के डेटा और ऊपर दिए गए उदाहरण जैसे सरल स्तर के कोड में, देखने में यह अच्छा लगता है और कोई खास बुराई भी नहीं लगती।

लेकिन map() के अंदर थोड़ा-थोड़ा करके कोड घुसने लगता है ... और कोड धीरे-धीरे फूला हुआ होता जाता है।
भाषा या implementation library के अनुसार असर अलग हो सकता है, लेकिन जब डेटा की मात्रा बढ़ जाती है, तो सिर्फ data structure में डेटा जमा करके या उसे manipulate करते हुए प्रोसेस करने की तुलना में यह आसानी से हज़ारों गुना धीमा भी हो सकता है।

और एक नया कारण भी जुड़ गया है जिसकी वजह से अब इसे पसंद नहीं करता हूँ। जब मैंने यह लेख फोन पर देखा, तो PC-स्तर की चौड़ाई वैसे की वैसे बनी रही, और नतीजा यह हुआ कि अक्षरों का आकार बहुत ही बारीक हो गया, इसलिए लेख पढ़ना बेहद मुश्किल था T.T

मूल रूप से मैं इसे पसंद नहीं करता, और जानबूझकर इसे इस तरह लिखने की कोशिश भी नहीं करता।

 
bichi 2025-04-22

थोड़ा js भी दे दीजिए |> विनम्र निवेदन

 
secret3056 2025-04-22

|> बहुत सुंदर है

 
howudoin 2025-04-22

यह मेरा सबसे नापसंद syntax है
stacktrace ज़रा सा भी उलझा हो तो debugging सबसे खराब हो जाती है

 
cosine20 2025-04-25

सच में

 
GN⁺ 2025-04-22
Hacker News की राय
  • लेखक इसे "pipelining" कहते हैं, लेकिन उनका मानना है कि सही शब्द "method chaining" है

    • Bash की साधारण pipeline से तुलना: हर component समानांतर चलता है और बीच के परिणाम streaming होते हैं
    • Ruby में हर line क्रमिक रूप से process होती है और हर चरण के बीच पूरा array बनता है
    • इससे debugging कठिन हो जाती है, इसलिए अब वे ज़्यादा explicit code लिखते हैं
    • explicit code देखने में कम साफ़ लग सकता है, लेकिन बीच की state को आसानी से inspect किया जा सकता है
  • व्यक्तिगत रूप से वे किसी language के feature set को छोटा रखने और जल्दी एक complete feature set तक पहुँचने के पक्ष में हैं

    • लेकिन वे चाहते हैं कि Elixir का |> syntax सभी languages अपनाएँ
  • Lisp macros एक general solution देते हैं, जो सिर्फ chained collection operators ही नहीं बल्कि call chain का क्रम भी तय कर सकता है

    • उदाहरण के लिए, (foo (bar (baz x))) को (-> x baz bar foo) की तरह लिखा जा सकता है
    • अतिरिक्त arguments होने पर भी इसे संभाला जा सकता है
    • अधिक जानकारी के लिए Clojure की threading macros guide देखें
  • उन्होंने यह शब्द fluent interface के रूप में सीखा था। pipelining कुछ और है

  • pipeline operator, partial application का एक प्रकार है, जिसमें कई arguments bind करके नया function बनाया जा सकता है और उसका output दूसरे function को दिया जा सकता है

    • partial application program लिखने में बहुत उपयोगी है, और किसी दिन (non-Haskell) languages इसे program composition की बुनियाद के रूप में इस्तेमाल करेंगी
  • R के tidyverse users इसे पहले से ही इस्तेमाल कर रहे हैं

  • pipelining में debugging कठिन है। exception handling मुश्किल होती है, इसलिए pipeline में branching जोड़नी पड़ती है

    • pipeline सिर्फ happy path programming में ही उपयोगी है
  • SQL syntax अनावश्यक रूप से जटिल है

    • SQL पहले से ही एक operator language है, लेकिन ऐतिहासिक कारणों से उस पर बहुत सीमाएँ हैं
    • अगर नया syntax स्वीकार करना है, तो उसे और सरल तरीके से लिखा जा सकता है
    • |> syntax में expressiveness की कमी है और यह visual noise बढ़ाता है
  • लेखक दावा करते हैं कि "semantics syntax पर भारी पड़ता है", लेकिन उनका ध्यान syntax की पसंद पर है

    • chain जितनी लंबी होती जाती है, pipelining में debugging उतनी कठिन हो जाती है
    • वे Python की आलोचना करते हैं, लेकिन ठोस कारण नहीं देते
    • "pipelining" की परिभाषा स्पष्ट नहीं है
  • effect-ts pipeline और imperative code दोनों लिखने की सुविधा देता है

    • pipeline लिखने और generators इस्तेमाल करने पर documentation उपलब्ध है
    • ज़्यादातर community ने imperative style generators को पसंद करना शुरू कर दिया है
    • इससे debugging और maintenance आसान लगते हैं