1 पॉइंट द्वारा GN⁺ 3 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • type inference और gradual type checking अब सभी Elixir प्रोग्राम्स पर लागू होते हैं, जिससे type annotations के बिना भी dead code और runtime पर निश्चित रूप से fail होने वाले verified bugs खोजे जा सकते हैं
  • dynamic() type, “anything allowed” वाले any() से अलग, runtime पर संभव type range को track करता है और केवल तब violation report करता है जब वह allowed type से बिल्कुल भी overlap न करे
  • dynamic(integer() or binary()) value, numeric operations या string functions जैसी calls में जहाँ कुछ संभावनाएँ overlap करती हैं, violation नहीं देती, लेकिन Map.fetch! जैसी calls में जो केवल map लेती हैं, violation देती है
  • dynamic() उपयोग के तरीके के अनुसार narrow होता है, और data.a + data.b जैसे code में data को %{..., a: number(), b: number()} रूप वाले map के रूप में refine करता है
  • guard में union, intersection, negation infer किए जाते हैं, ताकि is_list, is_integer, is_map_key, not is_map_key, tuple_size जैसी conditions को type information के रूप में इस्तेमाल किया जा सके
  • case और conditionals, पिछले clause की जानकारी को अगले clause में reflect करते हैं, जिससे पहले nil handle करने के बाद बचे हुए value को binary() तक narrow करने जैसी type checking की जा सके
  • standard library के tuple और map से जुड़ी कई functions में types जोड़े गए हैं, जिससे existing codebases में redundant clauses और dead code खोजने में मदद मिलती है
  • “If T: Benchmark for Type Narrowing” में 13 categories में से 12 pass करके यह दिखाया गया कि सामान्य Elixir code में precise type information recover की जा सकती है
  • v1.20 ने multi-core environments में applications के लिए compile time को फिर बेहतर किया है, और synthetic benchmarks में Elixir build tool ने BEAM languages में सबसे तेज़ results दिखाए
  • नया compiler option :module_definition module definition execution method को default :compiled या :interpreted के रूप में चुनने देता है, और इसे mix.exs के elixirc_options: [module_definition: :interpreted] से activate किया जा सकता है
  • :module_definition option, disk पर लिखी जाने वाली .beam files को प्रभावित नहीं करता और केवल defmodule के अंदर execution method बदलता है, जिससे बड़े projects के compile time सुधारने में मदद मिल सकती है
  • set-theoretic types का उपयोग करने वाले नए type signatures पर v1.20 के type system performance, recursive types, parameterized types, और map key-value traversal research पूरी होने के बाद typed struct definitions के साथ चर्चा की जाएगी

1 टिप्पणियां

 
GN⁺ 3 시간 전
Hacker News की राय
  • यह शायद मेरा निजी अनुभव हो, लेकिन जो भाषाएँ शुरू से typed नहीं थीं, वे वास्तविक static typed languages जितना अच्छा काम नहीं करतीं

    • सहमत हूँ, लेकिन एक दूसरा नज़रिया भी है: “Why are gradual static types so great?” https://www.benkuhn.net/gradual/
    • दूसरी ओर, TypeScript को उन तमाम अजीब पैटर्न्स को support करना पड़ता है जो लोगों ने type-less भाषाओं में किए हैं, इसलिए वही मेरा सबसे पसंदीदा type system बन गया है
  • मैं लगभग 10 साल से पेशेवर Elixir developer के रूप में काम कर रहा हूँ, और types आने का लंबे समय से इंतज़ार कर रहा था। इस बार उसकी शुरुआत सच में आ गई, यह देखकर बहुत खुशी है
    लेकिन मैं जानना चाहूँगा कि v1.20 में जो आया है, वह spec-less Dialyzer की तुलना में कैसा है। Dialyzer के success typing approach को मैं इस तरह समझता था कि यह “अगर arguments के कोई ऐसे combinations हों जो fail कर सकते हैं तो warning दो” की बजाय “अगर arguments का एक भी combination काम कर जाता है तो warning मत दो” के ज़्यादा करीब है। मुझे लगा था Elixir भी यहाँ कुछ वैसा ही कर रहा है, और Dialyzer मुझे ज़्यादा उपयोगी नहीं लगा था

    • यह देखने की जिज्ञासा है कि अभी production में चल रहे 10 साल पुराने Elixir codebase से यह क्या-क्या निकाल पाएगा
  • Elixir के gradual type system पर कुछ पोस्ट्स HN पर देखी हैं, लेकिन मैंने उन्हें विस्तार से follow नहीं किया। मैं जानना चाहता हूँ कि क्या यह gradual type system, type-less code की तुलना में, किसी प्रोग्राम की asymptotic complexity बदल सकता है
    जहाँ तक मुझे पता है, ज़्यादातर gradual type systems, जैसे Racket, प्रोग्राम को asymptotically और धीमा बना सकते हैं, हालांकि कुछ exceptions भी हैं [1]
    [1] https://doi.org/10.1145/3314221.3314627

    • Elixir का gradual type system प्रोग्राम की asymptotic complexity नहीं बदल सकता। design के अनुसार यह उन runtime casts को स्पष्ट रूप से बाहर रखता है जो दूसरे gradual type systems में slowdown का कारण बनते हैं
      ज़्यादातर gradual type systems typed और untyped code की boundary पर, जब values पार होती हैं, तब enforcement डालते हैं। उदाहरण के लिए, list के सभी elements की जाँच करना, या values को type proxies में wrap करना। लेकिन Elixir टीम ने ऐसे runtime checks के बिना soundness पाने के लिए strong arrows का परिणाम प्रकाशित किया, और compiler जो bytecode बनाता है वह अर्थ की दृष्टि से untyped code के समान ही है
  • विडंबना यह है कि आलोचक कहते थे कि types की ज़रूरत है, और Elixir fans कहते थे कि types की ज़रूरत नहीं, Elixir किसी तरह जादुई है, इसलिए type-related bugs आते ही नहीं। अब जब types जोड़े गए हैं, तो वही bugs पकड़ रहे हैं। क्या पहले यह नहीं कहा जाता था कि bug prevention के लिए इनकी ज़रूरत नहीं? फिर भी यह एक अच्छा बदलाव है। मैंने पहले Elixir काफ़ी इस्तेमाल किया है और मुझे वह पसंद भी था, लेकिन types की अनुपस्थिति से सहमत होना मुश्किल था

    • यह Goomba fallacy है
      https://en.wiktionary.org/wiki/Goomba_fallacy
    • मैंने Elixir को विशेष गहराई से follow नहीं किया, लेकिन Erlang की चर्चाओं में जो देखा वह थोड़ा अलग था। चूँकि fail होने की स्थिति को graceful ढंग से संभालना ही पड़ता है, इसलिए type errors को भी उन्हीं failure recovery mechanisms से संभाल लिया जाए जो पहले से होने ही चाहिए — तर्क कुछ ऐसा था
      मैं उस दृष्टिकोण से सहमत नहीं हूँ, लेकिन यह “$LANGUAGE जादुई है” कहने से कहीं अधिक defensible दावा है
    • मैं यह दावा नहीं कर सकता कि ऐसा तर्क मैंने कभी नहीं देखा, लेकिन मुझे याद नहीं कि देखा हो, और अगर था भी तो शायद बहुत अल्पसंख्यक रहा होगा। असली विरोधी तर्क आम तौर पर यह होता है कि “types अच्छे हैं, लेकिन उनकी एक लागत है, और वह लागत हमेशा पर्याप्त लाभ देकर वापस नहीं आती”
      set-theoretic type theory के विकसित होने से पहले यह रुख शायद सही भी रहा हो
    • JavaScript/TypeScript और Python में भी यही हुआ था। कभी-कभी लोगों को वही मानने देना पड़ता है जो वे मानना चाहते हैं
    • यही जीवन चक्र है। dynamic typed languages के fans बनते हैं, और दूसरे लोग सही ही कहते हैं कि static types होने पर वे कहीं ज़्यादा उपयोगी हो जाएँगी। fans इसे निजी तौर पर ले लेते हैं और कहते हैं कि static types की ज़रूरत नहीं है। वजहें अलग-अलग होती हैं: “वैसे भी उपयोगी नहीं”, “भाषा की आत्मा के खिलाफ है”, “यह तो बस scripting language है”, “debugger इस्तेमाल कर लो”, “static types productivity घटाते हैं” आदि
      फिर अंत में static types जोड़ ही दिए जाते हैं। Python, JavaScript, Ruby में ऐसा हुआ, और भी भाषाओं में हुआ होगा
  • यह बहुत अच्छा लगता है कि Elixir को update करने पर कई projects में breaking changes नहीं आते, और compiler मुफ्त में bugs भी पकड़ देता है। अब तो इसकी आदत-सी पड़ गई है

  • यह देखकर सच में खुशी हुई। अब यह “बेहतरीन भाषा” के स्तर के और करीब पहुँच रही है, और मेरे लिए Elixir पहला दावेदार है
    अगर कोई दूसरी भाषा है जो पहले से ही इस्तेमाल में आसान है और फिर भी शानदार features को लगातार stable और safe तरीके से जोड़ती रहती है, तो बताइएगा। मैं Go में दक्ष हो रहा था, फिर advanced C# सीखने की तरफ मुड़ गया, क्योंकि Go में अच्छे features जुड़ना जैसे रुक-सा गया था

  • पिछले एक महीने में मैंने Elixir exercism.io track किया https://exercism.org/tracks/elixir
    यह सच में शानदार है

  • आह, फिर से शुरू हो गया। लगता है अगले 1 साल तक फिर Elixir सीखना पड़ेगा
    Elixir की हर चीज़ अच्छी लगती है, लेकिन किसी भी दूसरी language से ज़्यादा Elixir मुझे खुद पर शक करने पर मजबूर करती है। लगता है मेरा दिमाग functional के लिए बना ही नहीं है, लेकिन इस बदलाव की वजह से इसे फिर से आज़माने का मन हो रहा है
    अफ़सोस की बात यह है कि ecosystem को beginner-friendly कहना मुश्किल है, और सवालों के जवाब देते समय अक्सर यह मान लिया जाता है कि आपको language पहले से काफ़ी आती है

    • https://pragprog.com/titles/lhelph/functional-web-developmen...
      शीर्षक पर मत जाइए। किताब का पहला आधा हिस्सा बस Elixir ही है
      पिछले 8 सालों में जब-जब मुझे Elixir में फिर से ढलना पड़ा, मैंने यही किताब उठाई, और हर बार यह काम आई। इसे कभी पूरा नहीं पढ़ा
      इस तरह की tutorial-project शैली की programming किताब अच्छी है या नहीं, इसे परखने का एक तरीका यह है कि अगर आप इसे कई बार शुरू करें लेकिन अंत तक न भी पहुँचें, तब भी क्या बीच तक आते-आते आपके पास अपने काम पर लौटने लायक tools आ जाते हैं
    • कॉलेज में जब मैंने पहली बार “Programming Paradigms का परिचय” जैसी किसी class में Haskell किया था, तब मैंने यह तकलीफ़ सच में बहुत गहराई से महसूस की थी। तब तक मैं कई सालों से programming कर रहा था, इसलिए यह यक़ीन करना मुश्किल था कि जिन चीज़ों को मैं इतने समय से बुनियादी मानता था, उन्हें पूरा करने में मैं इतना असहाय हो सकता हूँ
      लेकिन मुझे लगता है कि यह दिमाग के अनुकूल न होने से ज़्यादा इस बात का असर है कि imperative languages में आपका अनुभव जिस स्तर पर है, pure functional style में आपको फिर से beginner बनकर शुरू करना पड़ता है
      यह धीरे-धीरे बेहतर होगा। functional programming में सहज होने का मोड़ मेरे लिए तब आया, जब मुझे एहसास हुआ कि मुझे Bash की अच्छी spacing वाली “one-liner” जैसी चीज़ों को जोड़ना कितना पसंद है। डेटा किसी रूप में शुरू होता है, आप उसे किसी command में dump करते हैं, फिर सोचते हैं कि उसे चाही हुई शक्ल के थोड़ा और क़रीब लाने के लिए अगली command में pipe करना है, फिर दोबारा देखते हैं। ऐसा करते-करते आख़िर में आम तौर पर आपके पास बिना बदले जाने वाले data transformations की एक श्रृंखला बचती है
      shell में यह सहज लगने का एक कारण यह भी है कि आप रोज़ file system में घूमते हुए commands की vocabulary बनाते रहते हैं। Unix-जैसे environment में आपकी परिचित “functions” की library सालों में काफ़ी बड़ी हो चुकी होती है। pure functional programming environment में भी यही करना होता है, बस vocabulary सीखने में थोड़ी ज़्यादा मेहनत लगती है। अक्सर इस्तेमाल होने वाले “commands” grep, cat, sort की जगह map, fold, zip जैसी functions बन जाती हैं
      लेकिन मूल बात सचमुच वही है, और pipeline बनाने का आकर्षण दोनों तरफ़ एक जैसा लागू होता है। आप चीज़ों को टुकड़ों में बना सकते हैं, और हर puzzle में पिछला चरण भूलकर बस यह सोच सकते हैं कि सामने के data को अगली बार कैसे transform करना है। यही कम संदर्भ-भार ताज़गीभरा और सुकून देने वाला है
      ज़रूर कोशिश करें और उम्मीद है कि आपको इसमें मज़ा आएगा। जब आप किसी चीज़ में अभी अच्छे न होने की स्थिति का आनंद लेना सीख लेते हैं, तभी आप सच में उसमें अच्छे होने लगते हैं
    • सोच रहा हूँ कि क्या आपको Rust की थोड़ी जानकारी है। मुझे भी functional languages का बहुत अनुभव नहीं है, लेकिन Gleam अपने Rust-जैसे हिस्सों की वजह से परिचित लगा, इसलिए मैं syntax से ज़्यादा concepts पर ध्यान दे पाया
      बेशक मैंने इसे बस कुछ दोपहरों तक ही आज़माया है, लेकिन अगर मुझे अपने दिमाग को फिर से functional languages के लिए प्रशिक्षित करना हो, तो शायद परिचय की वजह से मैं Gleam चुनूँगा
    • मैं ElixirForum पर पूछने की सलाह दूँगा। मैंने कभी सचमुच hostile प्रतिक्रिया नहीं देखी
      कभी-कभी पोस्ट अस्पष्ट होने की वजह से ध्यान नहीं खींच पाती, या उनमें “मेरा homework कर दो” वाली गंध होती है, इसलिए उन्हें नज़रअंदाज़ कर दिया जाता है
      लेकिन जहाँ सच्ची जिज्ञासा होती है, मेरी नज़र में हर ऐसी पोस्ट को जवाब मिलता है
    • ऐसी बातें हमेशा मुझे उलझाती हैं। state से लथपथ object-oriented programs मुझे उससे कहीं ज़्यादा मुश्किल लगते हैं जिनके बारे में तर्क करना हो
  • शानदार। 1.20 में हमारी बड़ी umbrella app compilation काफ़ी तेज़ हो गई लगती है

  • जानना चाहता हूँ कि यह Gleam के मुकाबले कैसा है। या अब फिर Gleam की बजाय Elixir क्यों इस्तेमाल करें? Phoenix, ख़ासकर LiveView, Elixir की बड़ी ताकत लगती है

    • यह इस बात का फ़र्क है कि आपको Rust पसंद है या Erlang। Gleam इस्तेमाल करना Rust इस्तेमाल करने जैसा लगता है, और Elixir इस्तेमाल करना Erlang इस्तेमाल करने जैसा
      Gleam OTP की मौजूदा स्थिति मुझे नहीं पता, लेकिन आख़िरी बार जब मैंने देखा था, तब वह अच्छी नहीं थी
      अगर आपको दोनों में से किसी से फ़र्क नहीं पड़ता और सिर्फ़ types मायने रखते हैं, तो Gleam इस्तेमाल करिए। लेकिन फिर सीधा Rust ही क्यों न इस्तेमाल करें?
    • Gleam वेबसाइट पर सीधे comparison material मौजूद है
    • Gleam में macros नहीं हैं, और Phoenix या Ecto जैसी कई Elixir libraries macros का बहुत प्रभावी इस्तेमाल करती हैं
      उदाहरण के लिए, Gleam में JSON decoding/encoding काफ़ी verbose हो जाती है। Rust में आप serde derive कर देते हैं, और Elixir में एक function call काफ़ी होती है
      Elixir का ecosystem ज़्यादा mature है। उदाहरण के लिए, आप Gleam में Phoenix या कोई और Gleam framework इस्तेमाल कर सकते हैं, लेकिन अनुभव वैसा नहीं होता
      Gleam का Elixir पर बड़ा आकर्षण types हैं, और अब Elixir उस फ़ासले को कम कर रहा है। साथ ही यह JavaScript में compile भी कर सकता है, और Elixir में Hologram कुछ वैसा ही कर रहा है
      निजी तौर पर मुझे Gleam का type system और Rust जैसी syntax ज़्यादा पसंद है, लेकिन इस समय मेरे सभी web development projects के लिए Elixir बेहतर विकल्प लगता है
    • व्यावहारिक रूप से देखें तो Phoenix और Ecto की वजह से