- ClojureScript 1.12.145 में compiler को इस तरह बदला गया है कि
^:async hint लगे functions को JavaScript async function के रूप में emit किया जाए
- अब
await के साथ Promise value का इंतज़ार करने वाले ClojureScript functions लिखे जा सकते हैं, जिससे JavaScript interop बेहतर होता है
- टेस्ट में भी
^:async का उपयोग किया जा सकता है, और await के साथ asynchronous function call के परिणामों को verify किया जा सकता है
- हालिया Clojure survey में JavaScript interop से जुड़े ClojureScript सुधार अनुरोधों में async functions support की हिस्सेदारी सबसे अधिक रही
- आधुनिक browser API और लोकप्रिय libraries के साथ काम करने वाले सामान्य मामलों में अतिरिक्त dependency जोड़ने की ज़रूरत कम हो जाती है, और पूरी change list ClojureScript changelog के 1.12.145 section में देखी जा सकती है
^:async और await का उपयोग
- ClojureScript 1.12.145 में compiler को इस तरह बदला गया है कि
^:async hint लगे functions को JavaScript async function के रूप में emit किया जाए
- ClojureScript के ECMAScript 2016 को target करने के बाद JavaScript interop सुधार के क्षेत्रों को अधिक सावधानी से चुनना संभव हुआ
- अब
await का उपयोग करके Promise values का इंतज़ार करने वाले ClojureScript functions लिखे जा सकते हैं
(refer-global :only '[Promise])
(defn ^:async foo [n]
(let [x (await (Promise/resolve 10))
y (let [y (await (Promise/resolve 20))]
(inc y))
;; not async
f (fn [] 20)]
(+ n x y (f))))
- टेस्ट में भी
^:async का उपयोग किया जा सकता है, और await के साथ asynchronous function call के परिणामों को verify किया जा सकता है
(deftest ^:async defn-test
(try
(let [v (await (foo 10))]
(is (= 61 v)))
(let [v (await (apply foo [10]))]
(is (= 61 v)))
(catch :default _ (is false))))
पृष्ठभूमि और बदलावों की सूची
- हालिया Clojure survey में JavaScript interop से जुड़े ClojureScript सुधार अनुरोधों में async functions support की हिस्सेदारी सबसे अधिक रही
- इस सुधार से आधुनिक browser API और लोकप्रिय libraries के साथ काम करने वाले सामान्य मामलों में अतिरिक्त dependency जोड़ने की ज़रूरत कम हो जाती है
- सभी fixes, changes और improvements की सूची ClojureScript changelog के 1.12.145 section में देखी जा सकती है
- ClojureScript 1.12.145 में community member Michiel Borkent ने योगदान दिया
1 टिप्पणियां
Hacker News की राय
borkdude ने यह थ्रेड पोस्ट किया था, और देखा कि इस रिलीज़ के contributors में उनका नाम भी है
काफ़ी समय से async/await support के ख़िलाफ़ तर्क आम तौर पर दो थे: CLJS compiler में गहरे स्तर के बदलावों की ज़रूरत होगी, और Promesa जैसी libraries के macros पहले से मिलती-जुलती सुविधा दे देते हैं
इसके अलावा यह भी कहा जाता था कि core.async इस्तेमाल कर लो, या expression-oriented भाषा async/await के साथ अच्छी तरह फिट नहीं बैठती, लेकिन ये forum में बार-बार दोहराए जाने वाले मुख्य तर्क कम और व्यक्तिगत राय ज़्यादा थे
Clojurians Slack में borkdude ने कभी कहा था कि उन्हें support जोड़ना अवास्तविक नहीं लगता, और अब लगता है कि उन्होंने सच में समय लगाकर इसे बना दिया, उसके लिए सच में आभारी हूँ
दिलचस्प बात यह है कि ClojureScript ने JavaScript में async/await आने से बहुत पहले ही core.async library के ज़रिए asynchronous paradigm को support किया था
यह इस रिलीज़ की अहमियत कम करने के लिए बिल्कुल नहीं कह रहा, बल्कि यह कह रहा हूँ कि सिर्फ़ dependency में एक library जोड़कर host language में अभी मौजूद न होने वाला नया language feature इस्तेमाल कर पाना काफ़ी शानदार है. Clojure कमाल है
शायद David Nolen की एक talk देखकर मुझे इसका पता चला था
उसके बाद मैं frontend में JavaScript को न्यूनतम रखने की दिशा में चला गया, और SSE one-way है, यही बात इसे सुंदर बनाती है. आजकल अलग-अलग भाषा समुदायों के developers को SSE में रुचि लेते देखना अच्छा लगता है
David Nolen की हाल की talk “A ClojureScript Survival Kit” भी अच्छी थी: https://youtu.be/BeE00vGC36E
David “Swannodette” Nolen ने ClojureScript और core.async के शुरुआती दिनों से जो काम किया है, उसके लिए जितना धन्यवाद दें कम है. इस talk में खास तौर पर चौंकाने वाली बात यह है कि वह ClojureScript को छोड़कर server-side pure Clojure, server-sent events, और बहुत थोड़े JavaScript वाली दिशा को लेकर भी वास्तव में उत्साहित दिखते हैं
असली demo लगभग 26:30 पर शुरू होता है. वह पहले client पर चलने वाले webapp का resource usage दिखाते हैं, फिर वही webapp server पर चलाकर SSE से client तक one-way push करते हैं, और resource usage लगभग 0 के करीब पहुँच जाती है, जो काफ़ी प्रभावशाली है
यह हर case में फिट नहीं बैठेगा, लेकिन minimal DOM mutation library के साथ webapp और state को समझना आसान हो गया. पहले मुझे Clojure के लिए REPL और ClojureScript के लिए REPL दोनों चलाने पड़ते थे, साथ में बहुत सा two-way traffic और मुश्किल से reproduce होने वाली state संभालनी पड़ती थी, जबकि अब चीज़ें कहीं तेज़ हैं और reproduce करना भी आसान है
JavaScript output बड़ा हो जाता है, इसमें built-in error model नहीं है, और दिक्कत आने पर यह ऐसी state machine code में बदल जाता है जिसे पढ़ना और debug करना मुश्किल होता है
ऊपर से
gomacro अपने S-expression के बाहर के code को transform नहीं कर सकता, इसलिए यह functions को बेवजह बड़ा करने की तरफ़ धकेलता हैजैसा किसी Cognitect वाले ने कहा था, “core.async is beautiful nonsense”
हाल में social पर Clojure/ClojureScript को अचानक ज़्यादा देखना थोड़ा हैरान करने वाला है
मैंने 2012 के आसपास कुछ साल काम में इसका इस्तेमाल किया था, लेकिन बहुत से लोगों की तरह JVM छोड़कर typed functional languages की तरफ़ चला गया
क्या आजकल बढ़ी हुई रुचि agentic coding की वजह से है? क्या type checks न होना, और syntax errors या reserved words कम होना code skim करना तेज़ बनाता है? क्या S-expression की वापसी आ रही है?
जिन गंभीर Clojure codebases को मैं जानता हूँ वे test suites में काफ़ी निवेश करते हैं, इसलिए अगर AI को test suite सबसे असरदार तरीके से इस्तेमाल करना सिखाने की तकनीक जुड़ जाए तो उसे काफ़ी अच्छी रफ़्तार मिल सकती है
मेरे कुछ सहकर्मी agents को REPL के साथ interact करने देते हैं, और कहते हैं कि हर बार startup cost न देने से चीज़ें तेज़ हो जाती हैं. मैं इतना परिश्रमी नहीं रहा, लेकिन अभी भी यह काफ़ी तेज़ है
Clojure में रुकावटें कम हैं.
falseऔरnilको छोड़कर सब truthy है, operator precedence table नहीं है, और core language immutable, persistent data structures को default support देती हैसब कुछ expression है, operator और expression के मिले-जुले ढाँचे जैसा नहीं.
map,reduce,filterbuilt-in हैं और सामान्य code में स्वाभाविक रूप से इस्तेमाल होते हैं10 साल पहले लिखा Clojure code आज भी अक्सर चलने की अच्छी संभावना रखता है, और ecosystem व language designers code तोड़ने को लगभग वर्जित चीज़ मानते हैं
मैंने जितनी भाषाएँ इस्तेमाल की हैं उनमें ideas व्यक्त करने की सबसे ज़्यादा आज़ादी और सबसे कम सिरदर्द इसी में मिला. Flowstorm, जो एक तरह का reverse debugger है, प्रोग्रामिंग का सपना जैसा tool है
अगर आप संतुष्ट रहना चाहते हैं तो यह बहुत अच्छी भाषा है. उल्टा, ज़्यादातर users इसे इतना स्वाभाविक मान लेते हैं कि इसके बारे में ज़्यादा शोर नहीं मचाते
Clojure को commercial तौर पर इस्तेमाल करने वाले कई programmers ऐसे भी हैं जो भाषा को ठीक से समझ नहीं पाए, इसलिए बहुत खुश नहीं हैं. कई बार उन्होंने इसे ख़ुद नहीं चुना होता, या अभी उसके लिए तैयार नहीं होते, और मेरा मानना है कि Clojure अपनाने से पहले दूसरी भाषाओं की कुछ परेशानियों को लगभग 10 साल झेलना पड़ता है
Clojure के creator Rich Hickey के software पर videos मशहूर और प्रभावशाली हैं, लेकिन इसका मतलब यह नहीं कि सहकर्मियों ने उन्हें देखा हो या परवाह की हो
बड़े, untyped Python codebase को AI के साथ संभालना मुश्किल था. जिन हिस्सों पर tests नहीं थे, वे टूटे नहीं हैं यह जाँचना बहुत उबाऊ हो जाता है
type system जितना मज़बूत हो, उतना अच्छा. साथ ही AI models code पर train होते हैं, इसलिए भाषा जितनी mainstream होगी, performance उतनी बेहतर होने की संभावना है. ClojureScript अच्छा है, लेकिन यह mainstream भाषा नहीं है, इसलिए मुझे लगता है AI इसमें JavaScript से कम अच्छा होगा
आख़िरकार अगर AI को ध्यान में रख रहे हैं, तो typed language चुनना बेहतर है, या dynamic language हो तो कम-से-कम type hints वाली
यह सच में बड़ा है. Jank की घोषणा के बाद Clojure ecosystem में मैं इतनी उत्सुकता कम ही देखी है
frontend में JavaScript alternatives का सिर्फ़ obscure स्तर से आगे बढ़कर सच में जगह बनाना अच्छा लगेगा
मैं ClojureScript जैसा कुछ आज़माना चाहता हूँ, लेकिन personal side project के अलावा इसे कहाँ इस्तेमाल कर सकता हूँ, यह कल्पना करना कठिन है. अगर किसी organization का backend पहले से Clojure में हो तो शायद adoption आसान होगा
मैंने production में इसे इस्तेमाल नहीं किया, लेकिन कुछ side projects और परिवार के लिए बनी चीज़ें deploy की हैं. ClojureScript का React wrapper Reagent मुझे ईमानदारी से React से भी ज़्यादा तार्किक लगा
आप Hiccup से HTML बनाते हैं, और components बस Hiccup DSL के अंदर functions होते हैं, और यह DSL ख़ुद भी मूलतः list ही है, इसलिए नतीजा बहुत साफ़-सुथरा लगता है. static चीज़ें static दिखती हैं, dynamic चीज़ें साफ़ तौर पर dynamic दिखती हैं, और साधारण React की तुलना में इसमें जादू-टोना काफ़ी कम लगता है
बुरा तब लगा जब NPM से मिले non-functional components इस्तेमाल करने की कोशिश की. घातक नहीं था, लेकिन code बदसूरत हो गया. wrappers से इसे ठीक किया जा सकता था, लेकिन कुछ JS libraries का cljs में default अनुभव काफ़ी अव्यवस्थित होता है
community भी बहुत मददगार और mature है
पहले अपनी personal scripts बदलकर हाथ साफ़ कीजिए, फिर उसके फ़ायदे महसूस कीजिए. हर case में यह बेहतर नहीं होगा, लेकिन बाद में लोग आपसे सलाह लेने आ सकते हैं, इसलिए ख़ुद का आश्वस्त होना ज़रूरी है
अनजान tech को लाते समय कम महत्वपूर्ण चीज़ चुनकर उसे दोबारा लिख देना और छोड़ देना अच्छी रणनीति है. दिक्कत हो तो rollback आसान रहता है, और लोगों को पसंद आने लगे तो धीरे-धीरे बढ़ाइए
मैंने भी कभी .NET organization में F# को चुपचाप लाने के लिए कम महत्वपूर्ण tests पहले F# में लिखने शुरू किए थे
https://blisswriter.app/
https://blog.nestful.app/p/how-we-dropped-vue-for-gleam-and
मैंने cljs को लंबे समय से follow नहीं किया, लेकिन मुझे याद है कि इसे मूल रूप से “JavaScript पर Clojure” जैसा बताया जाता था. कम-से-कम शुरुआत में Rich इसे कुछ ऐसा ही समझाते थे
मेरी समझ यह थी कि इरादा इसे जितना हो सके एक और runtime जैसा बनाने का था
लेकिन यह बदलाव तो cljs-विशेष feature जोड़ने जैसा लगता है, और
awaitतो पहले सेclojure.coreमें keyword है, इसलिए यह Clojure ख़ुद से भी टकराता हैक्या समय के साथ दोनों implementations अलग रास्ते पर निकल गई हैं, या यह feature users के लिए इतना महत्वपूर्ण था कि यह फ़र्क स्वीकार्य हो गया?
यह इस मायने में महत्वपूर्ण है कि बिना अतिरिक्त library डाले JavaScript interop संभाला जा सकता है
यह लंबे समय से गायब feature था, इसलिए इस रिलीज़ का आना काफ़ी सुखद है
async/await functions को CSP में wrap करना बेहतर handling लगता है. Clojure में पहले से इससे अच्छा pattern मौजूद था
core.async कहीं जा नहीं रहा, और अगर async/await Promise-आधारित implementation से बेहतर फिट बैठता है तो core.async का
.cljsहिस्सा भी अपडेट हो सकता हैइस नए function hint के आने से भी वह तरीका गायब नहीं होगा
https://clojurescript.org/guides/promise-interop#using-promi...
समझ नहीं आ रहा इसे कैसे लिया जाए. core.async का एक बड़ा मक़सद क्या ऐसी सारी चीज़ों को channels में डालना नहीं था?
JavaScript-style
asynckeyword होना upgrade है, इस पर यक़ीन नहीं हो रहाइसे इस्तेमाल करना ज़रूरी नहीं है, आप अब भी core.async इस्तेमाल कर सकते हैं. हालिया ClojureScript survey में यह सबसे ज़्यादा माँगा गया feature भी था