2 पॉइंट द्वारा GN⁺ 2024-04-22 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Racket एक परिपक्व भाषा है जो language-oriented programming को केंद्र में रखती है, और सामान्य application development व नई भाषाओं के निर्माण को एक ही ecosystem में संभालती है
  • इसका मूल macros और #lang है, जिससे नई syntax, domain-specific languages और मौजूदा surface syntax को library की तरह बनाया जा सकता है और module स्तर पर इस्तेमाल किया जा सकता है
  • web server, database, math/statistics, GUI और scientific simulation तक शामिल करने वाली standard library और हजारों packages general-purpose development का दायरा बढ़ाते हैं
  • Typed Racket, contracts, object system और DrRacket IDE साथ में मिलते हैं, जिससे functional code, object-oriented components और gradual types को जरूरत के हिसाब से जोड़ा जा सकता है
  • Racket सिर्फ Lisp परिवार की एक भाषा नहीं है; यह एक ऐसे development environment के ज्यादा करीब है जो हर problem domain के लिए उपयुक्त भाषा बनाकर उसे execution, editing और tool support से जोड़ना चाहता है

Language-oriented programming के लिए Racket

  • Racket एक programming language है जो “Racket, the Programming Language” और “Racket, the Language-Oriented Programming Language” दोनों को आगे रखती है
  • Racket version 9.2 उपलब्ध है
  • यह शुरुआत से ही Windows, macOS और Linux पर cross-platform graphics programming को support करने वाला परिपक्व product रहा है
  • बुनियादी development features में package management, GUI, standalone binaries और foreign interface तक शामिल हैं

सामान्य application development का दायरा

  • Racket के पास libraries का collection है जो web server applications से लेकर math और scientific simulation software तक कवर करता है
  • प्रमुख documentation और library scope इस प्रकार हैं
  • cross-platform GUI toolkit और web server default ecosystem में शामिल हैं
  • हजारों अतिरिक्त packages एक single command से install किए जा सकते हैं
    • उदाहरण के लिए 3D graphics, Bluetooth socket connector, color maps, data structures, educational software, games, quantum-random number generator, scientific simulations, web script testing आदि शामिल हैं
  • #lang racket/gui का example GUI dialect में एक छोटा number-guessing game implement करता है और कई language features को साथ में इस्तेमाल करता है

Macros से extend होने वाली भाषा

  • Racket programmers macros के जरिए अपने खुद के loops और नई syntax define कर सकते हैं
  • नई syntax procedures, methods और classes की तरह जोड़ी जाती है; इसके लिए custom syntax को Racket expressions या definitions में rewrite करने वाले rules बनाने होते हैं
  • छोटे macros ऐसी repetitive code removal में मदद करते हैं जिसे अन्य features से संभालना मुश्किल हो सकता है
    • किसी task का execution time मापने वाली time-it syntax define की जा सकती है
    • बार-बार lambda इस्तेमाल करने से बचा जा सकता है
    • macros को सामान्य functions की तरह modules से export किया जाता है
  • पूरा macro system ऐसी संरचना भी बना सकता है जिसमें कई macros मिलकर काम करें
  • Racket एक functional language है, लेकिन शुरुआत से ही classes and objects, mixins and traits sublanguage प्रदान करती है
  • Java जैसा class system macro-based library के रूप में implement किया गया है, इसलिए यह core language के अलग support के बिना काम करता है

#lang और domain-specific languages

  • Racket का लक्ष्य भाषा बनाने वाली भाषा होना है, ताकि programmers हर module को उपयुक्त भाषा में लिख सकें
  • #lang typed/racket example String और Number के union type, occurrence typing और list filtering का इस्तेमाल करता है
  • #lang scribble/base example PDF या HTML documents generate करने वाली documentation language को संभालता है
  • #lang datalog example parent और ancestor relations को define और query करने वाली Datalog syntax का इस्तेमाल करता है
  • नई भाषा IDE window में बनाई जा सकती है और दूसरी IDE window में उस भाषा के modules run किए जा सकते हैं; इसके लिए settings, project files या external tools की जरूरत नहीं होती
  • Racket users मुख्य रूप से parentheses syntax इस्तेमाल करते हैं, लेकिन Datalog की तरह comma और curly braces की जरूरत वाली मौजूदा surface syntax भी बनाई जा सकती है
  • parsing packages का इस्तेमाल करके arbitrary grammar को parentheses-based language में map किया जा सकता है और Racket macro system से उसे सामान्य Racket में compile किया जा सकता है

DrRacket और development ecosystem

  • Racket अपना IDE DrRacket प्रदान करता है, जिसमें identifier पर mouse hover करने पर definition location तक arrow draw करने की सुविधा है
  • Typed Racket जैसी alternative languages इस्तेमाल करते समय भी DrRacket की editing support का उपयोग किया जा सकता है
  • Racket macros जटिल macros या नई language बनाने वाले macros में भी पर्याप्त source information record और propagate करते हैं, जिससे DrRacket ऐसा behave कर सकता है मानो वह नई language features को समझता हो
  • प्रमुख development support इस प्रकार है
  • ecosystem resources में download, source code, bug reports, nightly snapshot builds और package repository शामिल हैं
  • learning materials और documentation के रूप में Quick Introduction, The Racket Guide, The Racket Reference और All Documentation उपलब्ध हैं
  • community channels में Discourse, Discord, Slack, Reddit, mailing lists, Mastodon, Twitter, Blog, Wiki, YouTube शामिल हैं, और Team व Contributing documentation भी उपलब्ध है

1 टिप्पणियां

 
GN⁺ 2024-04-22
Hacker News की राय
  • Racket को पहले पेज पर देखकर अच्छा लगा। 1982 से रिसर्च प्रोग्रामिंग के लिए मैं मुख्यतः Common Lisp इस्तेमाल करता आया हूं, लेकिन आजकल Racket की तरफ ज्यादा खिंचता हूं।
    Racket में कुछ चीजें पसंद नहीं हैं—compiler, package management system, GUI IDE, Emacs bindings, और लिखने में मजेदार भाषा होने को छोड़कर लगभग सब कुछ।
    Programming language research वाले ecosystem में मेरी खास दिलचस्पी नहीं है, और शायद project को लीड करने वाले computer science professors इसी हिस्से को सबसे ज्यादा अहम मानते होंगे। फिर भी मैं चाहता हूं कि वे सफल हों।
    इसलिए Racket project पर free-ride करने जैसा भी लगता है। इसके बस छोटे-छोटे पसंदीदा हिस्सों का आनंद लेता हूं, बाकी को नजरअंदाज करता हूं, और contribution भी लगभग नहीं करता। हालांकि मेरी लिखी छोटी-सी Racket book शायद एक exception हो सकती है।

    • इस बात से मैं लगभग पूरी तरह सहमत हूं। Package management system, step-by-step debugger वाला GUI IDE, Racket core team द्वारा सीधे maintain किया गया cross-platform IDE लिखने की क्षमता, और executable binaries आसानी से बनाने की सुविधा—इनकी वजह से Racket मेरा पसंदीदा Lisp है।
      ये features सचमुच उपयोगी और महत्वपूर्ण हैं। मुझे Lisp पसंद है, लेकिन काम पर मैं कोई भाषा तभी इस्तेमाल करता हूं जब वह उस काम के लिए सबसे सही tool हो। इन्हीं features की वजह से Racket वह इकलौता Lisp रहा जिसे मैं वास्तविक इस्तेमाल के लिए justify कर पाया।
      Community, tools और learning resources की वजह से Racket मेरे लिए दूसरों को recommend करना आसान language है। मैंने CL और Clojure भी काफी इस्तेमाल किए हैं और उनमें पसंद आने वाली बातें हैं, लेकिन दोनों में बड़े drawbacks हैं, इसलिए मैं उन्हें दूसरों को recommend नहीं करता।
      मैं भी भाषा के research वाले हिस्सों या lang feature से ज्यादा जुड़ नहीं पाता, और HtDP भी मुझे खास पसंद नहीं है। लेकिन मेरे हिसाब से वे बस मेरी पसंद की भाषा में बने ऐसे projects हैं जिनमें मेरी रुचि नहीं, language की अपनी कमी नहीं। क्योंकि असल में उनसे टकराने की नौबत बहुत कम आती है।
    • https://leanpub.com/racket-ai/read
      इसे तो काफी बड़ा contribution माना जा सकता है :)
    • मैं CL रोजमर्रा में इस्तेमाल करता हूं, और यह research या programming language research क्षेत्र नहीं है। अभी तक Racket नहीं आजमाया है, इसलिए जानना चाहूंगा कि CL की तुलना में Racket में आपको क्या पसंद नहीं है, थोड़ा और समझा सकते हैं?
    • Programming language research ecosystem से ठीक-ठीक क्या मतलब है, यह जानना चाहूंगा। Racket distribution में सीधे programming language research कहा जा सके, ऐसा मुझे Redex के अलावा ज्यादा कुछ नहीं दिखता।
      भाषा में metaprogramming features जरूर हैं, लेकिन आधुनिक भाषाओं में metaprogramming तो होती ही है।
      Community में मेरा अनुभव ज्यादातर वास्तविक समस्याओं पर बात करने वाले लोगों का रहा है।
      Racket programming language research या अन्य research में इस्तेमाल होता है, इसलिए संबंधित papers और conference presentations में Racket का जिक्र आता है, लेकिन वह discussion पर हावी नहीं होता।
      उदाहरण: https://racket.discourse.group/t/levin-tree-search-with-cont...
    • University में programming language ecosystem class में Racket इस्तेमाल किया था, और वह पहलू मुझे भी ज्यादा मजेदार नहीं लगा। फिर भी Racket शुरू करने में आसान है और अपना काम निश्चित रूप से अच्छी तरह करता है। Lisp में कदम रखना हो तो व्यक्तिगत रूप से मुझे लगता है कि Racket अच्छा starting point है।
      हालांकि Clojure की community बड़ी और ज्यादा मजबूत है। बदले में वह JVM इस्तेमाल करता है, इसलिए setup थोड़ा ज्यादा झंझट वाला है और कुछ subtle बातों पर ज्यादा ध्यान देना पड़ता है।
  • Racket एक बहुत practical language है। अगर यह सिर्फ academic oddity जैसा लगता है, तो देखिए Bogdan Popa Racket से क्या कर रहे हैं: https://defn.io/
    व्यक्तिगत रूप से जब मुझे native GUI वाला binary चाहिए होता है, तो मैं Racket इस्तेमाल करता हूं। JSON, XML, text file formats जैसी चीजें parse करने के लिए भी यह काफी अच्छा है।
    साथ में पढ़ने लायक किताब How to Design Programs, https://htdp.org/2023-8-14/Book/index.html भी अच्छी है। यह बिल्कुल Racket सिखाने वाली किताब नहीं है और Racket में implement की गई कुछ educational languages इस्तेमाल करती है, लेकिन इसमें कभी-कभी दोबारा सोचने लायक मूल्यवान ideas मिलते हैं।
    Macro system CL जैसी जगहों से आने वालों को अजीब लग सकता है, लेकिन इसकी आदत पड़ने के बाद metaprogramming करते हुए भी अपेक्षाकृत sanity बनाए रखना आसान लगा।
    कुछ और उपयोगी resources:
    https://www.greghendershott.com/fear-of-macros/
    https://beautifulracket.com/

    • Bogdan वाली चीजों में खास तौर पर क्या ध्यान खींचता है? सरसरी तौर पर देखने पर मुझे कुछ खास असरदार नहीं लगा।
  • Racket नाम की भाषा वाकई पसंद है, लेकिन थोपा हुआ वर्कफ़्लो स्वीकार करना मुश्किल है। Python में कोडिंग करते समय मैं editor में कोड लिखता हूं और shell में चलाता हूं
    Racket का start-up time इतना लंबा है कि यह तरीका उतना ठीक से काम नहीं करता। इसके बजाय लोग कहते हैं कि लंबे समय तक चलने वाली virtual machine और REPL के साथ interact करना चाहिए
    लेकिन फिर जिस code पर आप काम कर रहे हैं, वह clean state से शुरू नहीं होता, बल्कि उस पल virtual machine के पास जो state है, वहीं से शुरू होता है। Jupyter notebook जैसी चीज़ों के लिए यह बेहतरीन flow है, लेकिन बड़े programs के लिए मुझे यह ठीक नहीं लगता

    • editor में code लिखकर shell में चलाने का तरीका भी Racket में पूरी तरह valid है। मेरे अनुभव में start-up time Python जैसा ही काफी करीब है। धीमा है, लेकिन घातक नहीं, और pre-compile करने पर खास तौर पर ठीक रहता है। जिस file पर अभी काम पूरा हुआ हो, उसके लिए उपयोगी है
      racket के बजाय racket/base #lang इस्तेमाल करने से भी बड़ा फर्क पड़ता है। ज्यादा जानकारी https://docs.racket-lang.org/style/Language_and_Performance.... में है
      “clean state” से शुरू न होना Racket से ज्यादा Common Lisp-स्टाइल REPL जैसा लगता है। Racket में आम तौर पर file या module को फिर से load करते समय Racket को restart करना पड़ता है, इसलिए fresh environment मिलता है। लोग इसकी शिकायत करते हैं, लेकिन मैं CL की तुलना में Racket के clean state वाले तरीके को पसंद करता हूं
    • “clean state” से शुरू न होने वाली बात में documentation के हिसाब से लगता है कि user backup file save करने से साफ तौर पर मना कर सकता है
      https://docs.racket-lang.org/drracket/drracket-files.html#(p...
      शायद restore suggestion को भी reject किया जा सकता होगा
      “DrRacket पहली बार start होने पर जांचता है कि कोई backup file बची हुई है या नहीं, और अगर है तो backup file restore करने का सुझाव देता है”
    • Smalltalk एक बार आज़मा कर देखिए :-))
    • Guile दिलचस्प हो सकता है। खासकर debugging करते समय यह Racket की तुलना में ज्यादा immersive जैसा है, और मुझे यह Common Lisp(SBCL) से भी ज्यादा मिलता-जुलता लगता है
    • Smalltalk और Lisp Machines की दुनिया में आपका स्वागत है। modern IDE भी अभी hot reload, काम की state save करना, और single language से पूरे development stack को control करने की capabilities पूरी तरह ठीक से support नहीं कर पाते
  • University of British Columbia में पढ़ते समय, computer science के introductory course में Racket पढ़ाया जाता था। मुझे यह शानदार language लगी, और जिन students को पहले programming experience था, उनमें से भी बहुत कम ने Lisp किया था, इसलिए इसने सबको एक ही starting line पर ला दिया
    छोटी games या visualizations आसानी से बनाने देने वाली libraries भी प्रभावशाली थीं

    • मैंने भी UBC में वह class ली थी, लेकिन मेरा impression बिल्कुल अलग था। यह भयानक था, और खासकर imperative languages में होने वाली बाद की data structures और algorithms classes के लिए introductory students को बहुत खराब तरीके से तैयार करता था
      TA रहते हुए, दूसरे साल में पहुंचे students में से काफी लोग अभी भी for loop भी नहीं कर पाते थे, और basic algorithms में बहुत पीछे थे
      functional languages के लिए गहरी appreciation मुझे चौथे साल की computation theory class के बाद ही हुई
  • Racket की इन सभी “languages” को एक application में कैसे integrate करना चाहिए, समझ नहीं आता। typed/racket, racket/gui, scribble/base जैसी languages दिखती हैं, लेकिन typed code से GUI application बनाते हुए PDF भी generate करना हो तो कैसे करें, इसका अंदाज़ा नहीं लगता
    मैंने Racket tutorials कई बार follow किए हैं, लेकिन आपस में असंबंधित लगने वाली “languages” को कैसे जोड़ा जाए, यह अभी भी confuse करता है
    व्यक्तिगत रूप से लगता है कि tutorial का हर chapter बस किसी असंबंधित “language” को समझाता है, और कभी नहीं दिखाता कि वे साथ कैसे काम करती हैं। एक chapter web server पर है लेकिन class system पर नहीं, और दूसरा chapter classes support करने वाली दूसरी “language” पर है लेकिन उसमें web server नहीं लिखा जाता

    • #lang line को उस file तक scoped एक तरह का compiler directive मान सकते हैं। असल में यह उससे कहीं ज्यादा है, लेकिन शुरुआत के लिए ठीक है। अगर application में types जोड़ना चाहते हैं तो file-by-file strategy अच्छी है
      #lang line के अलावा require से libraries import कर सकते हैं, इसलिए एक ही file में GUI code और web server code साथ रख सकते हैं। #lang भी एक समय में केवल एक language तक सीमित नहीं है; अगर conflict न हो तो उस line में और चीज़ें add कर सकते हैं
    • मुझे यह valid सवाल लगता है। अगर आप बड़ा application develop कर रहे हैं, तो लगभग सारा code "racket" language में लिखे जाने की संभावना है। अगर types में बहुत दिलचस्पी है तो काफी हिस्सा "typed/racket" हो सकता है
      यह सही है कि सभी languages एक common foundation share करती हैं और कुछ हद तक interoperable हैं, लेकिन program को पांच बराबर हिस्सों में बांटकर हर हिस्से के लिए अलग language इस्तेमाल करने जैसी स्थिति बनने की संभावना बिल्कुल भी ज्यादा नहीं है। documentation शायद scribble में लिखी जाएगी
      अलग-अलग languages इस्तेमाल करने से मूल रूप से अलग programming models मिल सकते हैं, और Typed Racket जैसी development संभव होने की यही पृष्ठभूमि भी है, लेकिन यह शुरू करने में बाधा नहीं बनना चाहिए
      संक्षेप में, बस Racket इस्तेमाल करें। जब सच में लगे कि किसी अलग feature या programming style की जरूरत है, तब देखें कि पहले से कोई language उपलब्ध है या नहीं। बेशक, यह सब मेरी राय है
    • मेरी समझ में हर module के लिए उस module की language चुनने की सुविधा है
  • यह website, Hacker News, Arc में लिखी गई है और Racket के ऊपर run होती है: https://en.wikipedia.org/wiki/Arc_(programming_language)

  • Racket की सबसे बड़ी समस्या भाषा या ecosystem नहीं है: https://news.ycombinator.com/item?id=27531508

    • लिंक में जिन 2018 Racket school के छात्र का ज़िक्र है, वह मैं ही था। Felleisen और Butterick सहित सभी instructors classroom के अंदर और बाहर सचमुच मददगार और विनम्र थे
      भले ही उस लिंक को पूरी तरह ज्यों-का-त्यों मान लिया जाए और यह माना जाए कि Felleisen किसी खास व्यक्तिगत बातचीत में Torvalds-स्टाइल में रूखे/बुरे तरह से पेश आते हैं, फिर भी How To Design Programs सहित उनके काम ने मेरी ज़िंदगी और दूसरों की ज़िंदगी पर बहुत सकारात्मक असर डाला है। इसलिए मैं लोगों से यह नहीं कहूँगा कि वे उसका इस्तेमाल न करें
    • वह मशहूर community सदस्यों के बीच का बेहद निजी विवाद है। व्यापक Racket community, core team सहित, बहुत विनम्र है
    • Felleisen को झेलना मुश्किल इंसान है, लेकिन उनसे बचना भी आसान है। मुझे यह Racket खुद की बजाय academia की pathology का symptom ज़्यादा लगता है
      community में मजबूत राय रखने वाले “अजीब nerds” भी हैं, इसलिए उनकी मौजूदगी ज़्यादा महसूस होती है और वे ज़्यादा चिढ़ा सकते हैं। लेकिन जिन कई social spaces में पैसा व्यवस्था को पकड़े नहीं रखता, वे आम तौर पर ऐसे ही होते हैं
  • Racket मेरी सबसे पसंदीदा भाषा है। यह तेज़ और practical है, इसकी बुनियाद मजबूत है, और इसका concurrency model भी बहुत अच्छा है। यह Concurrent ML से उधार लिए और आगे बढ़ाए गए concepts पर आधारित है
    documentation system भी शानदार है और package ecosystem के साथ integrated है, इसलिए ज़्यादातर packages में cross-references वाली high-quality documentation होती है। backward compatibility भी बेहतरीन है; मेरे हिसाब से यह मेरी मौजूदा day job में इस्तेमाल होने वाले Python से कहीं बेहतर है
    इसलिए जो लोग कहते हैं कि Racket बहुत academic है या practical नहीं है, मुझे लगता है कि उन्होंने इसे पर्याप्त गहराई से नहीं देखा, या वे शायद ऐसे students थे जिन्होंने पहले केवल teaching languages ही देखी थीं
    बेशक यह perfect नहीं है। community छोटी है, runtime का basic memory usage ज़्यादा है, और parallel processing के लिए हर system thread पर Racket VM चलाना पड़ता है जैसी समस्याएँ हैं। फिर भी ये चीज़ें समय के साथ बेहतर होंगी
    पिछले कुछ वर्षों में Racket से बनाई चीज़ें: e-commerce site[1], App Store पर मौजूद native macOS/iOS reminder app[2, 3, 4], Apache Kafka के लिए cross-platform desktop client[5, 6, 7], Lua के लिए #lang[8]। इसके अलावा भी[9][10][11] कई चीज़ें हैं। मुझे लगता है ये काफ़ी practical चीज़ें हैं
    [1]: https://defn.io/2019/08/20/racket-ecommerce/
    [2]: https://defn.io/2020/01/02/ann-remember/
    [3]: https://defn.io/2024/04/09/ann-remember-for-ios/
    [4]: https://github.com/bogdanp/remember
    [5]: https://defn.io/2022/11/20/ann-franz/
    [6]: https://defn.io/2023/10/15/ann-franz-for-windows/
    [7]: https://defn.io/2023/08/10/ann-franz-source-available/
    [8]: https://defn.io/2022/11/12/ann-racket-lua/
    [9]: https://docs.racket-lang.org/http-easy/index.html
    [10]: https://docs.racket-lang.org/deta/index.html
    [11]: https://docs.racket-lang.org/gui-easy/index.html

    • Bogdan Racket ecosystem में indispensable gui-easy और http-easy के author भी हैं
      community forum पर भी वे बहुत active हैं और सचमुच बहुत सारे मददगार जवाब देते हैं
      मुझे लगता है वे इस भाषा के hidden hero हैं, इसलिए उनका ज़िक्र ज़रूर करना चाहता था। कहा जा सकता है कि आपकी libraries ऐसा code चला रही हैं जो कुछ न जानने वाले users की ज़िंदगी को बहुत आसान बना देता है :)
      https://docs.racket-lang.org/http-easy/index.html
      https://docs.racket-lang.org/gui-easy/index.html
      https://racket.discourse.group
    • Backward compatibility सचमुच बहुत अहम बात है। मैंने कई साल Python को गहराई से इस्तेमाल किया, लेकिन 2/3 transition में core developers और community ने backward compatibility की कितनी कम परवाह की, यह देखकर मैं बहुत निराश हुआ, और उसके बाद भी सुधार नहीं हुआ
      शायद इसकी वजह वे क्षेत्र हैं जहाँ Python आज मुख्य रूप से इस्तेमाल होता है। 2000 के आसपास हुआ Numeric/Numpy transition बिल्कुल अलग था
      हर कुछ साल में चीज़ों का टूटना unicorn startups या तेज़ी से आगे बढ़ने वाली, और literally चीज़ें तोड़ने वाली companies के लिए ठीक हो सकता है। लेकिन ऐसे लोगों और organizations के लिए भी बहुत से valuable programs होते हैं जिनके पास mature algorithms को हर कुछ साल में फिर से लिखने की गुंजाइश नहीं होती, या वे इसे priority नहीं मानते
  • मैं Racket कभी-कभी इस्तेमाल करता हूँ और इसे पसंद करता हूँ। हालांकि मुझे पता चला है कि कुछ Lisp, खासकर Common Lisp और शायद Guile भी, अपेक्षा से ज़्यादा कम आंके जाते हैं।
    जो लोग इसे मुझसे बेहतर जानते हैं, उनसे पूछना चाहता हूँ: शुरुआत में जो व्यावहारिक, प्रासंगिक या उपयोगी नहीं लगते, लेकिन इस्तेमाल करने पर programming में अप्रत्याशित रूप से उपयोगी साबित होने वाले Racket features कौन-से हैं?

  • करीब 20 साल पहले, MzScheme के PLT Scheme बनने से पहले, मैंने उस पर आधारित भाषा इस्तेमाल करने वाले email security commercial software पर काम किया था। code cross-platform था और Solaris, Linux, HP-UX पर चलता था; operating system-specific code C में करीब 1,000 lines का था।
    filter rules खुद Scheme में compile होते थे। web-based UI समेत पूरा code करीब 30,000 lines का था, और developers सिर्फ 5–6 ही थे।
    बाद में immigrate करने के बाद मैं ऐसी company में गया जिसके पास मिलता-जुलता लेकिन कम features वाला product था; वह product C++ में लाखों lines का था और developers भी ज्यादा थे।