۳۰ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

با زیگ آشنا شوید: جایگزین مدرن برای C

Zig یک زبان سیستم محور است که روزی می تواند جایگزین زبان C شود.

Zig یک زبان سیستم محور است که روزی می تواند جایگزین زبان C شود.

برنامه نویسان هرگز راضی نیستند. به محض اینکه به یک هدف تقریباً غیرممکن دست یافتیم، شروع به کار برای رسیدن به هدف جدید می کنیم. نمونه‌ای از آن توسعه سیستم‌محور است که در آن ما قبلاً مکملی از زبان‌های قوی برای کار با آنها داریم: C، C++، Rust، و برو. اکنون Zig را نیز داریم، یک زبان جدیدتر که به دنبال جذب بهترین این زبان‌ها و ارائه عملکرد قابل مقایسه با تجربه توسعه‌دهنده بهتر و مطمئن‌تر است.

Zig یک پروژه بسیار فعال است. این توسط اندرو کلی در سال ۲۰۱۵ شروع شد و اکنون به نظر می رسد که به حجم بحرانی رسیده است. جاه طلبی زیگ در تاریخ نرم افزار بسیار مهم است: تبدیل شدن به وارث سلطنت طولانی مدت C به عنوان زبان سطح پایین قابل حمل و به عنوان استانداردی که زبان های دیگر با آن مقایسه می شوند.

قبل از اینکه به جزئیات برنامه نویسی با Zig بپردازیم، بیایید در نظر بگیریم که در کجای اکوسیستم زبان برنامه نویسی بزرگتر قرار می گیرد.

یک جایگزین برای C؟

Zig به عنوان یک “زبان سیستم های سطح پایین” توصیف می شود، اما سطح پایین چیست؟ زبان سیستم نیز نسبتاً مبهم است. از لوریس کرو، معاون انجمن در بنیاد نرم‌افزار Zig، پرسیدم که چگونه Zig را توصیف می‌کند. او گفت: “من Zig را به عنوان یک زبان برنامه نویسی همه منظوره تعریف می کنم، زیرا اگرچه برای برنامه نویسی سیستمی مناسب است، اما برای برنامه نویسی دستگاه های تعبیه شده، هدف قرار دادن WebAssembly، نوشتن بازی ها و حتی بیشتر مناسب است. وظایفی که معمولاً توسط زبان های سطح بالاتر انجام می شود.”

زیگ در رابطه با C، به عنوان یک هدف کلی، غیر زباله جمع‌آوری‌شده و زبان قابل حمل با اشاره‌گر، شاید ساده‌ترین درک باشد. امروزه، تقریباً تمام زیرساخت‌های برنامه‌نویسی به روش‌های مختلف بر روی C قرار دارند، از جمله پایه و اساس زبان‌های برنامه‌نویسی دیگر مانند جاوا، جاوا اسکریپت و پایتون. تأثیر موج دار تکامل به زبانی را تصور کنید که مانند C است، اما ایمن تر، باگ کمتر و نگهداری آسان تر است. اگر زیگ به طور گسترده به عنوان جایگزینی کهن الگویی برای C مورد استفاده قرار گیرد، می تواند مزایای سیستماتیک زیادی داشته باشد.

لوریس به من گفت، در حالی که Zig با C رقابت می‌کند، “ما انتظار نداریم که C را بدون زمان بسیار طولانی که هر دو زبان باید در کنار هم وجود داشته باشند، جایگزین کند.”

اهداف و نحو طراحی Zig

Zig یک زبان “نزدیک به فلز” است که به توسعه دهندگان اجازه می دهد تا مستقیماً با حافظه سیستم کار کنند، لازمه ای برای نوشتن کدی که می تواند حداکثر برای وظیفه خود بهینه شود. تخصیص حافظه مستقیم مشخصه ای است که توسط خانواده C، Rust و سایر زبان های سیستم های سطح پایین مشترک است. Zig قابلیت‌های مشابهی را ارائه می‌کند، اما هدف آن این است که به روش‌های مختلف آنها را بهبود بخشد.

Zig به دنبال ساده‌تر بودن زبان سیستم‌گرا نسبت به زبان‌های قبلی خود است و نوشتن کد صحیح و ایمن را آسان‌تر می‌کند. همچنین با کاهش لبه‌های تیز موجود در نوشتن نرم‌افزار C مانند، تجربه توسعه‌دهنده بهتری را هدف قرار می‌دهد. در اولین بررسی، ویژگی‌های Zig ممکن است به‌عنوان زمین‌شکنی به نظر نرسند، اما اثر کلی پلتفرمی است که توسعه‌دهندگان آن را آسان‌تر برای تسلط و استفاده از آن می‌یابند.

چیزی که توسعه دهندگان از آن متنفرند

در حال حاضر، Zig برای اجرای Bun.js JavaScript زمان اجرا به عنوان جایگزینی برای Node.js استفاده می شود. خالق Bun جارد سامنر به من گفت “Zig به نوعی شبیه نوشتن C است، اما با ویژگی های ایمنی حافظه بهتر در حالت اشکال زدایی و ویژگی‌های مدرن مانند defer (نوعی شبیه به Go) و کد دلخواه را می‌توان در زمان کامپایل از طریق comptime اجرا کرد. این دارای کلمات کلیدی بسیار کمی است، بنابراین یادگیری آن بسیار ساده تر از C++ یا Rust است.”

Zig از نظر ردپای ویژگی کوچکش با اکثر زبان‌های دیگر متفاوت است، که نتیجه یک هدف طراحی واضح است: تنها یک راه واضح برای انجام کارها. توسعه دهندگان Zig آنقدر این هدف را جدی گرفته اند که برای مدتی، Zig هیچ حلقه ای نداشت ، که یک توضیح نحوی غیر ضروری در حلقه while از قبل کافی تلقی می شد.

کوین لینا، که از یک پیشینه Rust آمده است، نوشت، “زبان بسیار کوچک و سازگار است. که بعد از چند ساعت مطالعه توانستم آنقدر از آن را در ذهنم بار کنم تا فقط کارم را انجام دهم.» Nathan Craddock، یک توسعه‌دهنده C، این احساس را تکرار کرد. به نظر می رسد برنامه نویسان واقعاً کیفیت متمرکز سینتکس Zig را دوست دارند.

چگونه Zig حافظه را مدیریت می کند

یک ویژگی متمایز Zig این است که به طور مستقیم با تخصیص حافظه در زبان سروکار ندارد. هیچ کلمه کلیدی malloc مانند C/C++ وجود ندارد. در عوض، دسترسی به پشته به صراحت در کتابخانه استاندارد انجام می شود. هنگامی که به چنین ویژگی نیاز دارید، یک شی Allocator را ارسال می کنید. این اثر به وضوح نشان می دهد که چه زمانی حافظه توسط کتابخانه ها درگیر می شود و در عین حال چگونگی پرداختن به آن را انتزاع می کند. در عوض، کد مشتری شما تعیین می کند که چه نوع تخصیص دهنده مناسب است.

برای جلوگیری از تخصیص‌های پنهان، دسترسی به حافظه را به یک ویژگی آشکار کتابخانه تبدیل کنید. ، که برای محیط های با منابع محدود و بلادرنگ یک موهبت است. حافظه از نحو زبان برداشته می شود، جایی که می تواند در هر جایی ظاهر شود، و مدیریت آن واضح تر می شود.

اجازه دادن به کد سرویس گیرنده برای تعیین نوع تخصیص دهنده به یک API به این معنی است که کد باید بر اساس محیطی که هدف قرار می دهد انتخاب کند. این بدان معناست که کد کتابخانه واضح تر و قابل استفاده تر می شود. یک برنامه کاربردی می‌تواند تعیین کند که کتابخانه‌ای که از آن استفاده می‌کند دقیقاً چه زمانی به حافظه دسترسی پیدا می‌کند، و نوع تخصیص‌دهنده (جاسازی‌شده، سرور، WebAssembly، و غیره) را که برای زمان اجرا مناسب‌تر است به آن تحویل دهد.

به عنوان مثال، کتابخانه استاندارد Zig با یک تخصیص دهنده اصلی به نام تخصیص دهنده صفحه ارسال می شود که با صدور: const allocator = std.heap.page_allocator;، حافظه را از سیستم عامل درخواست می کند. برای اطلاعات بیشتر در مورد تخصیص دهنده های موجود.

Zig همچنین دارای ویژگی‌های ایمنی برای جلوگیری از سرریز شدن بافر است و ارسال می‌شود با یک تخصیص دهنده اشکال زدایی که نشت حافظه را تشخیص می دهد.

تدوین شرطی

Zig از تلفیقی مشروط استفاده می‌کند، که نیاز به پیش پردازنده همانطور که در C یافت می شود. بنابراین، Zig ماکروهایی مانند C/C++ ندارد. از نقطه نظر طراحی، تیم توسعه Zig نیاز به یک پیش پردازشگر را به عنوان نشانه ای از محدودیت زبانی می داند که به شدت اصلاح شده است.

Visual Studio Code 1.79 فقط خواندنی را برای فایل ها، پوشه ها معرفی می کند

به‌جای ماکروها، کامپایلر Zig تعیین می‌کند که کدام کد را می‌توان در زمان کامپایل ارزیابی کرد. به عنوان مثال، یک دستور if در صورت امکان شاخه مرده خود را در زمان کامپایل حذف می کند. به جای استفاده از #define برای ایجاد یک ثابت زمان کامپایل، Zig تعیین می‌کند که آیا می‌توان با مقدار const به این روش برخورد کرد یا نه و فقط آن را انجام می‌دهد. این نه تنها خواندن، نوشتن و فکر کردن در مورد کد را آسان‌تر می‌کند، بلکه فرصت بهینه‌سازی را نیز باز می‌کند.

همانطور که اریک انگهایم می نویسد، Zig محاسبه زمان کامپایل را به یک ویژگی اصلی تبدیل می کند به جای یک فکر بعدی این به توسعه دهندگان Zig اجازه می دهد تا “کدهای عمومی بنویسند و برنامه نویسی متا را بدون داشتن هیچ گونه پشتیبانی صریح از ژنریک ها یا قالب ها انجام دهند.”

یک ویژگی متمایز Zig کلمه کلیدی comptime است. این اجازه می دهد تا کد را در زمان کامپایل اجرا کنید، که به توسعه دهندگان اجازه می دهد تا از جمله موارد دیگر، انواع را در مقابل ژنریک ها اعمال کنند.

قابلیت همکاری با C/C++

Zig دارای درجه بالایی از قابلیت همکاری با C و C++ است. همانطور که اسناد Zig تأیید می کنند، “در حال حاضر از نظر عملی درست است که C همه کاره ترین و قابل حمل ترین زبان است. هر زبانی که توانایی تعامل با کد C را نداشته باشد در معرض خطر گمنامی قرار می گیرد.

Zig can می تواند C و C++ را کامپایل کند . همچنین با کتابخانه های libc برای بسیاری از پلتفرم ها ارسال می شود. قادر است اینها را بدون پیوند به کتابخانه های خارجی libc بسازد. (برای بحث دقیق درباره رابطه Zig با libc، این موضوع Reddit را ببینید.)

در اینجا سازنده Zig بحث می کند قابلیت کامپایلر C در عمق، از جمله نمونه ای از Zig که کامپایلر GCC LuaJIT را کامپایل می کند. نکته پایانی این است که Zig تلاش می کند نه تنها C را با نحو خاص خود جایگزین کند، بلکه در واقع C را تا آنجا که ممکن است در خود جذب کند.

لوریس به من گفت که “Zig کامپایلر C/C++ بهتری نسبت به سایر کامپایلرهای C/C++ است زیرا از کامپایل متقابل خارج از جعبه، در میان موارد دیگر، پشتیبانی می‌کند. Zig همچنین می‌تواند به طور پیش پاافتاده با C تعامل داشته باشد (شما می‌توانید فایل‌های هدر C را مستقیماً وارد کنید) و در کل در استفاده از کتابخانه‌های C بهتر از C است، به لطف سیستم نوع قوی‌تر و ویژگی‌های زبانی مانند defer.”

سیستم نوع زیگ

Zig به شدت تایپ شده است و دارای struct برای معناشناسی شی‌مانند است، اما کلاس‌ها و اشیاء را ندارد. این نرم افزار از ژنریک ها، مانند C++ یا جاوا، بر خلاف C، پشتیبانی می کند و دارای یک کلمه کلیدی anytype است که به پارامترهای عمومی اجازه می دهد (arg: anytype). Zig از اتحادیه‌ها پشتیبانی می‌کند.

بررسی خطا در Zig

Zig یک سیستم رسیدگی به خطا منحصربه‌فرد دارد. به عنوان بخشی از فلسفه طراحی «جلوگیری از جریان کنترل پنهان»، زیگ از پرتاب برای مطرح کردن استثناها استفاده نمی‌کند. تابع throw می تواند اجرا را به روش هایی که دنبال کردن آنها سخت است شاخه بندی کند. در عوض، در صورت لزوم، عبارات و توابع می توانند یک نوع خطا را به عنوان بخشی از یک نوع اتحادیه با هر چیزی که در مسیر شاد برگردانده می شود، برگردانند. کد می تواند از شی خطا برای پاسخ مناسب استفاده کند یا از کلمه کلیدی try برای عبور از خطا استفاده کند.

نحوه استفاده از binding پارامتر در حداقل API در ASP.NET Core

یک نوع اتحادیه خطا دارای نحو است! <نوع ابتدایی>. می‌توانید با مثال ساده «Hello, world» این را در عمل ببینید (از اسناد Zig ) در فهرست ۱.


const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    try stdout.print("Hello, {s}!\n", .{"world"});
}

بیشتر فهرست ۱ خود توضیحی است. نحو !void جالب است. می گوید این تابع می تواند باطل یا خطا را برگرداند. این بدان معناست که اگر تابع main() بدون خطا اجرا شود، چیزی برنمی‌گرداند. اما اگر با خطا مواجه شد، یک شی خطا که شرایط خطا را توصیف می‌کند، برمی‌گرداند.

می توانید ببینید که چگونه کد مشتری می تواند از یک شی خطا در خطی که کلمه کلیدی try ظاهر می شود استفاده کند. از آنجایی که stdout.print می تواند خطا را برگرداند، عبارت try در اینجا به این معنی است که خطا به مقدار بازگشتی تابع main() منتقل می شود.

زنجیره ابزار و آزمایش

Zig همچنین دارای یک ابزار ساخت است. به عنوان مثال، می‌توانیم برنامه را در فهرست ۱ با دستورات فهرست ۲ بسازیم و اجرا کنیم (این دوباره از اسناد Zig است).


$ zig build-exe hello.zig
$ ./hello
Hello, world!

ابزار ساخت Zig به روشی بین پلتفرم کار می کند و جایگزین ابزارهایی مانند make و cmake می شود.

یک مدیر بسته در حال کار است، و پشتیبانی آزمایشی مستقیماً در زبان و دونده.

ساخته شده بر روی LLVM

Zig در ابتدا در بالای مجموعه ابزار LLVM ساخته شد، اما از آن زمان به سمت تبدیل LLVM به یک جزء اختیاری حرکت کرده است. این به قابل حمل بودن زبان Zig و سازگاری بیشتر با ساخت‌های مستقل کمک می‌کند.

ایالت زیگ

Zig یک انجمن Discord فعال و یک اکوسیستم GitHub. اسناد داخلی بسیار کامل است و کاربران Zig مقدار خوبی از مطالب شخص ثالث تولید کرده‌اند. ، همچنین.

Zig هنوز نسخه ۱.۰ منتشر نشده است، اما سازندگان آن می‌گویند که در حال نزدیک است آماده تولید. در مورد آمادگی، لوریس گفت: “Zig هنوز در نسخه ۱.۰ نیست، بنابراین چیزهایی مانند webdev هنوز در مراحل ابتدایی خود هستند، اما تنها استفاده ای که Zig را برای آن توصیه نمی کنم، بحث و جدل داده است، که فکر می کنم یک زبان پویا مانند پایتون یا جولیا کاربردی تر خواهد بود.”

در حال حاضر، به نظر می‌رسد که تیم Zig برای انتشار نسخه ۱.۰ وقت گذاشته است، که ممکن است در سال ۲۰۲۵ یا بعد از آن-اما هیچ کدام از اینها ما را از ساختن انواع چیزها با زبان امروز باز نمی دارد.

فعالیت، اهداف و پذیرش Zig توسط جامعه توسعه دهندگان، آن را به پروژه ای جالب برای تماشا تبدیل کرده است.

درباره Zig بیشتر بیاموزید

در اینجا چند مقاله وجود دارد که می توانید در مورد Zig و اینکه چگونه دنیای برنامه نویسی سیستم محور را تکان می دهد بیشتر بیاموزید: