1 पॉइंट द्वारा GN⁺ 2025-11-08 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • C code compilation और cross-compilation क्षमता को डिफ़ॉल्ट रूप से उपलब्ध कराने वाला Zig compiler, 45 वर्षों के अनुभव वाले लेखक के लिए उनके देखे गए भाषाओं में सबसे चौंकाने वाली भाषा है
  • compile-time execution, arbitrary bit-size variables, test block environment जैसी अनोखी विशेषताओं के साथ यह सिर्फ C/C++ का विकल्प नहीं, बल्कि प्रोग्रामिंग का बिल्कुल नया तरीका प्रदान करता है
  • type inference के जरिए variable declaration, anonymous struct, label break जैसी संक्षिप्त और स्पष्ट syntax के कारण इसे जल्दी सीखा जा सकता है
  • test block के जरिए स्वतंत्र module testing और @breakpoint built-in function के माध्यम से optimized code debugging का समर्थन
  • bit field और bit operations का उपयोग करने वाली low-level programming support के जरिए efficiency और robustness दोनों हासिल होते हैं, और interpreter भाषाओं के लाभ compiled language में समाहित हो जाते हैं

प्रस्तावना

  • 45 साल के अनुभव में Zig जितनी चौंकाने वाली भाषा कोई नहीं रही
    • Zig सिर्फ एक नई भाषा नहीं, बल्कि प्रोग्रामिंग के तरीके को मूल रूप से बदल देने वाला tool है
  • इसे केवल C या C++ के विकल्प के रूप में देखना बहुत बड़ा कम आकलन होगा
  • इस लेख का उद्देश्य Zig की सरल लेकिन आकर्षक विशेषताओं का परिचय देना और प्रोग्रामर को जल्दी शुरुआत करने में मदद करना है
  • उद्योग में Zig की स्वीकार्यता को प्रभावित करने वाली और भी कई विशेषताएँ मौजूद हैं

Zig compiler

  • C code compilation और cross-compilation क्षमता बिना किसी अलग configuration के डिफ़ॉल्ट रूप से उपलब्ध कराकर इसका उद्योग पर बड़ा प्रभाव पड़ता है
  • installation के लिए Ziglang download page से processor/OS के अनुसार compiler डाउनलोड करके उसे unzip कर मनचाही directory में कॉपी करना होता है
    • Windows 10 में x86_64 zip file को Program Files में कॉपी करें और root directory का नाम zig-windows-x86_64 कर दें, ताकि version update के समय Path environment variable बदलने की ज़रूरत न पड़े
    • Path environment variable में root directory path जोड़ने के बाद CLI mode में compiler इस्तेमाल किया जा सकता है
  • Hello World! प्रोग्राम build करने के लिए official site के Getting Started section को देखना उचित है

मुख्य अवधारणाएँ और commands

variable declaration

  • variable declaration तीन भागों से बनी होती है: accessibility (pub या उसका omission), var/const और variable name वाला पहला भाग, type declaration वाला दूसरा भाग, और initialization वाला तीसरा भाग
    • केवल पहला और तीसरा भाग आवश्यक हैं, और type को initialization value से infer किया जा सकता है
    • उदाहरण: var sum : usize = 0;
  • pub के बिना घोषित variable केवल module के अंदर access किया जा सकता है, यह C के static variable जैसा है
  • pub variable declaration की सिफारिश नहीं की जाती, और coupling कम व cohesion बढ़ाने के लिए pub function का उपयोग भी न्यूनतम रखने की सलाह दी जाती है

struct, anonymous struct, test block

  • .{ और } से घिरा anonymous struct literal किसी दूसरे struct के elements initialize करने या initialized elements के साथ नया struct बनाने में उपयोग होता है
  • .{ } एक खाली anonymous struct literal है
  • struct { } रूप struct declaration है
  • test block की मदद से executable के बिना compile और test run किया जा सकता है

bit field

  • bit field को packed struct में किसी निश्चित size वाले type के field के रूप में declare किया जाता है
  • pointer किसी विशेष bit field को point कर सकता है

for loop

  • Zig की syntax, C की तुलना में अधिक स्पष्ट है, लेकिन [0..8] की जगह open interval [0..9) का उपयोग करती है
  • loop variable i का type declaration, initialization, test और increment अपने-आप संभाले जाते हैं

array

  • [_] ऐसे array को define करता है जिसका size पहले से ज्ञात नहीं है, इसके बाद element type और initialization आता है
    • उदाहरण: var grid = [_]u8{0} ** 81; 81 u8 elements को 0 से initialize करता है
    • array size को initialization repetition argument से infer किया जाता है
  • test environment में array elements पर iterate करके उनका sum निकाला जा सकता है
  • for loop में | के बीच declared variable को array element के समान type का माना जाता है
  • usize platform का natural unsigned integer है, यानी 64-bit पर u64 और 32-bit पर u32

multi-item pointer

  • यदि array pointer पर pointer arithmetic इस्तेमाल करनी हो, तो उसे [*]const i32 की तरह स्पष्ट रूप से multi-item pointer के रूप में declare करना पड़ता है
  • array const होने पर भी pointer को var के रूप में declare किया जा सकता है

pointer dereference

  • array की किसी एक position के address से assigned pointer को pointer arithmetic से update नहीं किया जा सकता
  • pointer dereference के लिए ptr.* का उपयोग होता है

label break

  • compile time पर array initialization सहित कई तरह के काम किए जा सकते हैं
  • label break में block name के बाद : लगाया जाता है, और break के जरिए block से value लौटाई जाती है
    • उदाहरण: break :init m;
  • 0.. का अर्थ 0 से शुरू होने वाली infinite range है
  • for loop में variables अपने-आप initialize और increment होते हैं, और array की आख़िरी position process होने पर loop समाप्त हो जाता है
  • array को undefined से explicitly initialize करना ज़रूरी नहीं होता

Zig में functions

  • function को fn से declare किया जाता है और डिफ़ॉल्ट रूप से यह static होता है, यानी केवल file के अंदर उपयोगी
    • pub fn के रूप में declare करने पर उसे दूसरी file से import किया जा सकता है
  • function को inlined किया जा सकता है
  • function pointer में पहले const आता है और उसके बाद function prototype

Zig में object-oriented programming

  • struct के अंदर function हो सकते हैं
  • stack उदाहरण में अधिकतम 81 elements (StkNode type) रखे जा सकते हैं
  • ++ और -- operator Zig में नहीं हैं; उनकी जगह += और -= का उपयोग होता है
  • stack pointer, stk array के index के रूप में उपयोग होने वाला integer है
  • pointer self को parameter के रूप में explicitly pass नहीं किया जाता; उसे उस stack instance के pointer के रूप में अप्रत्यक्ष रूप से माना जाता है जिस पर function call हुआ है
    • stack.pop() जैसी call में self, stack के pointer के बराबर होता है, जो Java/C++ के this जैसा है
  • init() function stack constructor है
  • pop और push functions inlined हैं

Zig program build और run

executable build करना

  • executable बनाने के लिए main function चाहिए, जो program entry point को दर्शाता है
  • simple program में main function उसी file में शामिल किया जा सकता है
  • module को स्वतंत्र रूप से debug करने के लिए file के अंत में main function जोड़ा जा सकता है और debugging पूरी होने के बाद उसे comment out किया जा सकता है
  • compile command: zig build-exe -O ReleaseFast program.zig

module के test block चलाना

  • यह Zig की सबसे उत्कृष्ट विशेषताओं में से एक है, और testing तथा prototyping दोनों में उपयोगी है
  • test block test "message" { से शुरू होकर } पर समाप्त होता है
    • message वह string है जो test run के समय दिखाई जाती है
  • test block executable से स्वतंत्र रूप से चलते हैं, और अंतिम executable tests को run नहीं करता
  • test command: zig test module.zig
  • example.zig का test block set और print functions को test करता है; set decimal string को parameter के रूप में लेता है, और print Input Grid header प्रिंट करने के बाद grid को दिखाता है

Zig का output

  • std.debug.print statement, standard Zig library std के debug.zig में मौजूद print function को call करता है
  • पहला parameter format string होता है, और दूसरा display की जाने वाली variables की list वाले anonymous struct को रखता है
  • अगर format नहीं है तो struct खाली होता है
  • डिफ़ॉल्ट रूप से output stderr पर दिखता है
  • C के printf से अलग, Zig literal string और variable list को compile time पर process कर सकता है

executable debugging

  • debugger का उपयोग integrated debugger वाले IDE (Eclipse, IntelliJ IDEA) या integrated development kit (w64devkit) के अलावा आसान नहीं है
  • symbol integration code को भारी बनाती है और Debug mode compilation की मांग करती है, जिससे executable code की efficiency काफ़ी घट जाती है
  • Zig इन समस्याओं से बचने के लिए एक सुविधाजनक समाधान देता है

@breakpoint built-in function

  • source code में @breakpoint(); डालने पर debugger में run करते समय program उसी बिंदु पर रुक जाता है
  • यह symbols के बिना optimized Zig code को debug करने के लिए उपयोगी सुविधा है
  • @breakpoint(); से ठीक पहले std.debug.print का उपयोग करके track किए जाने वाले variables प्रिंट कर दें, तो उस क्षण उनके values देखे जा सकते हैं
  • debug_example.zig उदाहरण में set function के भीतर grid और variables प्रिंट करने वाला code तथा @breakpoint(); डाला गया है
  • build command: zig build-exe debug_example.zig
  • gdb जैसे debugger से debug_example.exe चलाएँ और r command से program run करें
  • c command से आगे बढ़ते हुए grid contents और variables track किए जा सकते हैं
  • Enter बार-बार दबाकर आगे बढ़ने पर देखा जा सकता है कि grid के values example.zig के test block से मेल खाते हैं

Zig की low-level programming

matrix representation

  • decimal digits को standard u8 integer के रूप में matrix में store किया जाता है
  • input grid string format में होती है, लेकिन ASCII characters अंदरूनी रूप से u8 integers में बदल जाते हैं
  • numbers को 81 positions वाले grid array में linear रूप से, एक-एक row के हिसाब से store किया जाता है: var grid = [_]u8{0} ** 81;
  • grid की correctness जाँचने के लिए हर row और column से elements access करने पड़ते हैं
  • 9 pointers का array बनाया जाता है, जिनमें हर pointer अपनी row की शुरुआत को point करता है
  • label break के जरिए code block से value लौटाई जाती है: break :fill9x9 m; के साथ matrix को m से initialize किया जाता है
  • element access notation: element = matrix[i][j]

decimal digit को bit के रूप में दर्शाना

  • integer decimal digit i को integer code से बदलना मुख्य विचार है
    • i ∈ [1,9] → code = 2ⁱ⁻¹
    • i = 0 → code = 0
  • जब i 1 से 9 के बीच हो, तो code में केवल i-1 position वाला bit 1 होता है; अन्यथा सभी bits 0 रहते हैं
  • हर digit के लिए code values की table दी गई है (1→1, 2→2, 3→4, ..., 9→256)

Zig में code की गणना

  • जब c 0 न हो तभी left shift operator से code value निकाली जाती है: code = @as(u9,1) << (c-1);
  • Zig में constants का उपयुक्त size होना ज़रूरी है ताकि operation compile हो सके और result variable को assign किया जा सके
  • code को u9 type के रूप में declare किया जाता है, क्योंकि maximum value 256 के लिए कम-से-कम 9 bits चाहिए
  • Zig arbitrary bit-size variables को support करता है
  • built-in function @as के जरिए constant 1 को u9 type में cast किया जाता है

bit field का उपयोग करने वाला grid representation

row-wise bit field grid

  • lines array, हर row को 9-bit integer के रूप में दिखाकर पूरे grid को mirror करता है: var lines = [_]u9{0} ** 9;
  • row i से array access करते समय, कोई digit उस row में पहले से मौजूद है या नहीं, इसे bit AND operation (&) से जाँचा जाता है: lines[i] & code
  • अगर result 0 है, तो digit अभी row i में नहीं है; अन्यथा वह duplicate है

column-wise bit field grid

  • columns array, हर column को 9-bit integer के रूप में दिखाकर पूरे grid को mirror करता है: var columns = [_]u9{0} ** 9;
  • column j से array access करते समय, कोई digit उस column में पहले से मौजूद है या नहीं, इसे bit AND operation से जाँचा जाता है: columns[j] & code
  • अगर result 0 है, तो digit अभी column j में नहीं है; अन्यथा वह duplicate है

Sudoku rules

  • खाली Sudoku grid में नया digit डालते समय, वह उसके पूरे row, column और cell में पहले से मौजूद नहीं होना चाहिए
  • cell से आशय मोटी रेखाओं से अलग किए गए 9 अलग-अलग 3x3 grids से है
  • 9x9 grid का हर specific element एक unique row, column और cell से संबंधित होता है
  • example grid में पहला cell 3, 5, 6, 8, 9 को शामिल करता है, जबकि 1, 2, 4, 7 अनुपस्थित हैं
  • lines और columns arrays row और column duplicate checking संभालते हैं
  • cell duplicate checking के लिए एक नए array की ज़रूरत होती है

cell-wise bit field grid

  • cells array, हर cell को 9-bit integer के रूप में दिखाकर पूरे grid को mirror करता है: var cells = [_]u9{0} ** 9;
  • cells को 3x3 matrix के रूप में access करना अधिक आसान है
  • 9x9 matrix की तरह ही cell array को भरा जाता है
  • मूल 9x9 grid में element की row और column से cell matrix की row और column तय करनी होती है
  • integer division बहुत धीमी होती है, इसलिए division result देने के लिए cindx = [_]usize{ 0,0,0, 1,1,1, 2,2,2 }; array का उपयोग किया जाता है
  • 9x9 grid के element की row i और column j से matrix access करते हुए, उस element के cell में कोई digit पहले से है या नहीं, इसे bit AND operation से जाँचा जाता है: cell[cindx[i]][cindx[j]] & code
  • अगर result 0 है, तो digit अभी cell में नहीं है; अन्यथा duplicate है

element duplicate test

  • एक ही row, column और cell के सभी पिछले elements को bit OR (|) से जोड़कर, फिर element के code के साथ bit AND करने पर duplicate verification पूरी हो जाती है
if (((lines[i]|columns[j]|cell[cindx[i]][cindx[j]])&code) != 0) {  
    unreachable;  
}  
  • अगर result 0 है, तो element अभी row, column या cell में मौजूद नहीं है
  • अगर result 0 नहीं है, तो program unreachable command चलाकर रुक जाता है
  • Zig में runtime error को स्पष्ट रूप से दिखाने का यह सबसे सरल तरीका है
  • वास्तविक code error location की विस्तृत जानकारी भी प्रिंट करता है
  • उदाहरण के लिए, input string में पहले '8' के तुरंत बाद आने वाले '0' को '5' से बदलने पर error आती है, क्योंकि column 1 की row 3 में पहले से 5 मौजूद है

data structure update

  • set function में nested for loop rows के क्रम में काम करते हुए input string s के हर नए element को grid में कॉपी करता है
    • variable k, string s के नए input character का index बनाए रखता है
  • character से '0' घटाकर उसे u4 (variable c) में बदला जाता है
  • अगर grid में डाला जाने वाला नया element 0 नहीं है (c != 0), तो left shift command से निकाला गया code हर mirror grid में कॉपी किया जाता है
    • संबंधित mirror grids पर bit OR (|=) किया जाता है:
lines[i] |= code;  
columns[j] |= code;  
cell[cindx[i]][cindx[j]] |= code;  
  • c की value 1 से 9 के बीच है या नहीं, इसे अलग से test करने की ज़रूरत नहीं, क्योंकि shift operation चलने पर overflow हो जाएगा
  • उदाहरण के लिए, input string में पहले '8' के तुरंत बाद आने वाले '0' को ':' से बदलने पर runtime error आती है
  • उसी '0' को '/' से बदलने पर भी वैसी ही runtime error आती है
  • program केवल तब काम करता है जब values 1 से 9 के बीच हों, यानी input grid में सिर्फ decimal digits हों
  • web पर कई Sudoku grids '0' की जगह '.' का उपयोग करती हैं, इसलिए set function में if (s[k] == '.') c = 0; line मौजूद है
  • इससे c की value 0 हो जाती है, और shift operation आसानी से bypass हो जाता है

prototyping और robustness

  • ऊपर के दो sections में दिखाई गई forced errors, Zig की एक महत्वपूर्ण विशेषता दिखाती हैं
  • एक है Zig की robustness — shift operation के मामले में गलत व्यवहार की अनुमति नहीं दी जाती और उसे runtime पर पकड़ लिया जाता है
  • सब कुछ efficiency की ओर उन्मुख लगता है, लेकिन यह एक विशिष्ट उदाहरण है जहाँ performance और robustness के बीच समझौता दिखाई देता है
  • C में shift operation bit खो भी दे तो वह प्रोग्रामर की समस्या मानी जाती है, और इससे खास assembly instructions के कारण बेहतर performance मिल सकती है
  • दूसरी विशेषता है test block को prototyping के लिए इस्तेमाल करने की संभावना
  • इसके संभावित उपयोग अनगिनत हैं, और यहाँ दिखाया गया उपयोग केवल error होने पर किसी विशेष स्थिति को debug करने का है
  • केवल ये विशेषताएँ ही प्रोग्रामिंग भाषाओं में बहुत दुर्लभ और अद्भुत क्षमता देती हैं, खासकर compiled languages में

निष्कर्ष

  • Zig तीन मुख्य तत्वों पर आधारित है: C compatibility, cross-compilation, और सरल installation
  • ये विशेषताएँ दिखाती हैं कि यह system programming language के नए standard के रूप में स्थापित हो सकता है
  • जो कई फायदे पहले केवल interpreter languages में मिलते थे, वे बेहतर performance के लिए धीरे-धीरे compiled languages में आ रहे हैं
  • compile-time execution की अवधारणा के कारण Zig, interpreter languages से बेहद मिलता-जुलता महसूस होता है
  • यही बात Zig को खास, अलग और शक्तिशाली बनाती है, और साथ ही कुछ हद तक समझने में कठिन भी

1 टिप्पणियां

 
GN⁺ 2025-11-08
Hacker News राय
  • यह लेख शुरुआत में दावा करता है कि “Zig सिर्फ़ एक simple language नहीं, बल्कि पूरी तरह नया programming तरीका” है, लेकिन वास्तव में यह Zig की अपनी अनोखी खूबियों पर लगभग बात ही नहीं करता।
    type inference, anonymous structs, labeled break जैसी चीज़ें तो काफ़ी पहले से दूसरी भाषाओं में मौजूद हैं।
    सच में अनोखी चीज़ comptime है, लेकिन उसका यहाँ बिल्कुल ज़िक्र नहीं है।
    यह Lisp macros जितनी पूरी तरह नई अवधारणा तो नहीं, लेकिन Zig जिस तरह इसे generics की जगह इस्तेमाल करता है, वह दिलचस्प है।
    फिर भी लेख का दावा काफ़ी बढ़ा-चढ़ाकर किया हुआ लगता है।

    • Rust को भी इसी तरह “पूरी तरह नया तरीका” कहा जा सकता है।
      Rust में code execution का timing साफ़ तौर पर व्यक्त किया जा सकता है, और पूरे code space को explore करने वाला query engine जैसा design काफ़ी प्रभावशाली है।
    • D language में 2007 से ही compile-time function execution का support था।
      D docs link देखें।
      अगर वह const-expression हो, तो अपने-आप execute हो जाता है।
    • अब C/C++ को एक साथ बाँधना मतलबहीन है।
      वे Java/Scala की तरह पूरी तरह अलग भाषाएँ हैं।
    • comptime कोई जादुई invention नहीं, बल्कि metaprogramming का आधुनिक version है।
      Zig, C++ templates से ज़्यादा साफ़-सुथरा है, लेकिन क्रांतिकारी से ज़्यादा एक practical alternative जैसा लगता है।
      व्यक्तिगत रूप से, Rust के समय जैसी ज़रूरत से ज़्यादा hype मुझे समझ नहीं आती।
    • “पूरी तरह नया तरीका” वाली पंक्ति देखकर मुझे LISP या Prolog जैसे नए paradigm की उम्मीद थी, लेकिन असल में ऐसा कुछ नहीं था।
      मैंने Zig docs पूरी पढ़ लीं, फिर भी चौंकाने जैसा कुछ नहीं मिला, तो थोड़ा अजीब लगा।
  • Zig की सबसे बड़ी समस्या यह है कि errors के साथ data attach नहीं किया जा सकता
    errors सिर्फ़ एक side channel से pass होते हैं, इसलिए debugging मुश्किल हो जाती है, और अंत में developers error data छोड़ ही देते हैं।
    related issue देखें।
    सिर्फ़ AccessDenied जैसे simple code से वजह समझना मुश्किल होता है।

    • मैंने matklad का लेख पढ़ा, और error codes और diagnostic information को अलग रखने वाला approach काफ़ी convincing लगा।
      वास्तव में, complex Error object इस्तेमाल करने पर भी अलग diagnostic channel की ज़रूरत अक्सर पड़ती है।
    • system languages में error के साथ data attach करना हमेशा अच्छा नहीं होता।
      performance overhead या system state की समस्या के कारण, कई बार context के हिसाब से lazy binding से handle करना ज़्यादा सुरक्षित होता है।
      Zig की philosophy ऐसी precision और determinism को प्राथमिकता देती है।
    • Zig में error stack traces में user-defined information डालने की सुविधा पर भी चर्चा चल रही है।
      related issue देखें।
      लेकिन असल ज़रूरत structured logging और call stack आधारित context tracking की है।
    • std.zon को एक अच्छा उदाहरण माना जाता है, और community में अलग-अलग error handling patterns इकट्ठा करके उन्हें standard में reflect करने की कोशिश हो रही है।
    • errors के साथ data attach न कर पाना उल्टा स्पष्ट error design को बढ़ावा देता है।
      इससे आलसी developers हर जगह बेवजह data चिपकाने से बचते हैं।
  • “Zig का development तरीका ही language development का नया तरीका है” — इस दावे से मैं सहमत हूँ।
    features को सावधानी से परखना और गैर-ज़रूरी चीज़ों को हटाते जाना वाला धीमा evolution process प्रभावशाली है।

    • लेकिन ऐसा approach Java या Rust जैसी भाषाओं में भी आम है।
      मैं और ठोस तरीके से सुनना चाहूँगा कि Zig की अपनी खास बात वास्तव में क्या है।
  • Zig को PyPI से install किया जा सकता है, यह मुझे पसंद है।
    ziglang package को pip install ziglang से install करके तुरंत इस्तेमाल किया जा सकता है।
    uvx का इस्तेमाल करके C code build भी किया जा सकता है।

    • Python wheel के ज़रिए arbitrary software को bundle किया जा सकता है, इसलिए यह installation तरीका संभव है।
    • लेकिन यह approach nix से कम सुविधाजनक reinvention जैसा लगता है।
    • काश Nim में भी ऐसा installation option होता।
    • व्यक्तिगत रूप से, pip/uv की तुलना में micromamba या pixi मुझे बेहतर package management तरीका लगते हैं।
    • AI tools की वजह से अब किसी भी language को सीखना पहले से कहीं आसान हो गया है।
  • Ada, Object Pascal, Modula-2 जैसी भाषाओं में पहले से मौजूद features को Zig की “innovation” की तरह पेश किया जाना थोड़ा निराशाजनक है।
    C-style syntax में दोबारा पैक करने से 40 साल पुराने ideas भी नए लगने लगते हैं — यह बात दिलचस्प है।

  • लेख की शुरुआत अच्छी थी, लेकिन बाद में वह बस Zig features की सूची बनकर रह गया।
    Zig का intuitive syntax और explicit control flow (defer आदि) आकर्षक है।
    comptime की वजह से अलग macro syntax सीखने की ज़रूरत भी नहीं पड़ती।

    • Zig की असली ताकत बिना अनावश्यक duplication वाला design है।
      इसके सभी हिस्से स्वाभाविक रूप से एक-दूसरे से फिट होते हैं, इसलिए पहली बार इस्तेमाल करने पर भी यह लंबे समय से जाना-पहचाना tool लगता है।
    • matklad का Zig syntax analysis article भी देखने लायक है।
  • Zig का for (0..9) syntax intuitive है, लेकिन open interval होने की वजह से कई बार भ्रमित करता है।
    Python के range(0, 9) की तरह आख़िरी value शामिल है या नहीं, यह भूलना आसान है।

    • Rust में 0..9 और 0..=9 का फर्क साफ़ है।
    • Zig की तरह सिर्फ़ half-open intervals इस्तेमाल करने की consistency उल्टा errors कम करती है।
      interval size सिर्फ़ difference से निकाला जा सकता है, और reverse iteration भी आसान हो जाती है।
    • Odin में 0..<5 (open) और 0...5 (closed) से इसे और साफ़ तौर पर अलग किया जाता है।
  • Zig के identifier rules मुझे पसंद नहीं हैं।
    snake_case और camelCase का मिश्रण थोड़ा अटपटा लगता है।
    फिर भी build system, memory allocator, compiler experience वगैरह शानदार हैं।
    मैं ज़्यादातर Rust इस्तेमाल करता हूँ, लेकिन Zig को लेकर जिज्ञासा बनी रहती है।

    • मेरा भी यही हाल है। व्यक्तिगत रूप से, मैं private function naming rule नहीं मानता।
      C libraries का prefix convention भी उतना ही झंझटभरा लगता है।
  • Zig की खासियत किसी एक feature में नहीं, बल्कि practical decisions के जमा होते असर में है।
    जो choices शुरुआत में radical लगती थीं, उन्हें गहराई से समझने पर वे तार्किक लगने लगती हैं।
    Zig जिज्ञासु developers को reward देने वाली language है।

    • मैंने Odin में एक छोटा game बनाया था, और वह सचमुच बहुत मज़ेदार अनुभव था।
  • Zig अच्छा इसलिए भी है क्योंकि वह low-level system code की वास्तविकता को स्वीकार करता है
    कई भाषाएँ aesthetic reasons से इन बातों को नज़रअंदाज़ करती हैं, लेकिन Zig ऐसा नहीं करता।

    • standard library definitions में जाएँ तो Plan9 OS जैसे special-case handling भी सीधे देखे जा सकते हैं।
      page_allocator docs देखें।
    • फिर भी ऐसे दावों को मज़बूत करने के लिए ठोस उदाहरण और चाहिए।