چرا دنیا هنوز به زبان‌های برنامه‌نویسی تازه نیاز دارد؟ فلسفه‌ی طراحی و هدف‌های زبان برنامه‌نویسی سلام

هر زبان موفق بیست سال اخیر برای برطرف کردن یک درد مشخص ساخته شد. این مقاله انگیزه‌ی ساخت Go، Rust، Swift، Kotlin و Zig را مرور می‌کند و بعد سراغ خلأیی می‌رود که سلام هدف گرفته و تصمیم‌های طراحی‌ای که از آن نتیجه می‌شود.

در این مقاله
  1. چرا زبان‌های موجود نمی‌توانند ایده‌های تازه را به‌سادگی جذب کنند
  2. زبان‌های اخیر برای درمان چه دردی ساخته شدند
  3. هزینه‌هایی که زبان برنامه‌نویسی سلام هدف گرفته است
  4. اصول طراحی زبان برنامه‌نویسی سلام که از این هدف‌ها نتیجه می‌شوند
  5. این اصول در کد چه شکلی دارند
  6. خلأیی که سلام پر می‌کند، بی‌پرده
  7. هزینه‌ی یک زبان تازه، از جمله زبان سلام
  8. چگونه یک زبان برنامه‌نویسی تازه را بسنجیم
  9. پرسش‌های پرتکرار

زبان‌های برنامه‌نویسی تازه پیوسته پدید می‌آیند، چون مسئله‌هایی که برنامه‌نویس‌ها با آن روبه‌رو هستند پیوسته عوض می‌شود: سخت‌افزار هسته‌های بیشتری پیدا می‌کند، نرم‌افزار به شبکه و مرورگر کوچ می‌کند، خطاهای امنیتی گران تمام می‌شوند و برنامه‌نویس‌ها دیگر عمدتاً مهندسان انگلیسی‌زبانِ چند کشور محدود نیستند. ساختن یک زبان تازه وقتی می‌ارزد که هزینه‌ای را حذف کند که زبان‌های موجود بدون شکستن کد کاربران خودشان نمی‌توانند حذفش کنند؛ هر زبان پرکاربرد دو دهه‌ی اخیر هم دقیقاً همین‌طور شروع شد: به‌عنوان درمان یک درد مشخص. زبان برنامه‌نویسی سلام زبانی تازه است که حول دو هزینه از این دست ساخته شده: دردسر به کار گرفتن چند زبان برای یک محصول، و این پیش‌شرط که پیش از هر چیز باید انگلیسی بدانید تا بتوانید برنامه بنویسید.

این مقاله نخست مرور می‌کند که چه چیزی به ساخت شناخته‌شده‌ترین زبان‌های اخیر انجامید، هر کدام چه چیزی را درست کرد و چه چیزی را فدا کرد؛ سپس فلسفه‌ی طراحی سلام و خلأیی را که هدف گرفته شرح می‌دهد و صادقانه می‌گوید این انتخاب‌ها چه هزینه‌ای دارند.

چرا زبان‌های موجود نمی‌توانند ایده‌های تازه را به‌سادگی جذب کنند

یک زبان پخته میلیون‌ها خط کد دارد که به رفتار فعلی‌اش وابسته‌اند. می‌تواند قابلیت تازه بیفزاید، اما به‌ندرت می‌تواند چیزی را حذف کند یا یک پیش‌فرض را تغییر دهد. C نمی‌تواند بدون شکستن برنامه‌های C به‌طور پیش‌فرض ایمن در برابر خطاهای حافظه شود. جاوا نمی‌تواند ماشین مجازی‌اش را کنار بگذارد. پایتون نمی‌تواند متغیرهایش را تغییرناپذیر یا گونه‌هایش را اجباری کند. و در زبانی که کل بوم‌سازگان (Ecosystem)، مستندات و جامعه‌اش بر واژه‌های کلیدی انگلیسی بنا شده، نمی‌شود انگلیسی را اختیاری کرد.

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

زبان‌های اخیر برای درمان چه دردی ساخته شدند

پنج زبان از بیست سال اخیر این الگو را به‌خوبی نشان می‌دهند و خاستگاه هر کدام روشن است:

زبانخاستگاهدردی که هدف گرفتچیزی که فدا کرد
Goگوگل، آغاز در ۲۰۰۷، معرفی عمومی در ۲۰۰۹، نسخه‌ی ۱٫۰ در ۲۰۱۲ساخت کند C++، پیچیدگی کدهای بزرگ، هم‌زمانی روی سرورهای چندهسته‌ایقدرت بیان: تا نسخه‌ی ۱٫۱۸ (۲۰۲۲) جنریک نداشت، و زباله‌روب دارد
Rustآغاز به دست Graydon Hoare با پشتیبانی Mozilla، نسخه‌ی ۱٫۰ در ۲۰۱۵خطاهای ایمنی حافظه در کد سیستمی C و C++سادگی: یادگیری مدل مالکیت و قرض‌گیری زحمت واقعی دارد
Swiftاپل، ۲۰۱۴کهنگی و ناایمنی Objective-C در سکوهای اپلقابلیت حمل، دست‌کم در آغاز: بوم‌سازگانش هنوز گرد اپل می‌چرخد
KotlinJetBrains، نسخه‌ی ۱٫۰ در ۲۰۱۶، زبان ترجیحی گوگل برای اندروید از ۲۰۱۹پرگویی جاوا و خطای اشاره‌گر تهی، بدون ترک JVMاستقلال از مدل JVM در بیشتر کاربردها
ZigAndrew Kelley، ۲۰۱۶جریان کنترل پنهان C، پیش‌پردازنده و دردسرهای کامپایل متقابلپایداری زبان: میان نسخه‌ها تغییرهای چشمگیری داشته است

وجه مشترک این زبان‌ها نوآوری برای نوآوری نیست. هر کدام هزینه‌ای را برگزید که کاربرانش هر روز می‌پرداختند، طراحی‌اش را حول حذف آن چید و در عوض هزینه‌ی تازه‌ای را پذیرفت. Go قدرت بیان را با سادگی و ساخت سریع معاوضه کرد. Rust آسانی یادگیری را با ایمنی بدون زباله‌روب معاوضه کرد. Kotlin شروع از صفر را با سازگاری کامل با کد جاوا معاوضه کرد.

هزینه‌هایی که زبان برنامه‌نویسی سلام هدف گرفته است

طراحی سلام بازتاب دو هزینه است که زبان‌های بالا به آن‌ها نپرداخته‌اند.

نخست، پراکندگی. یک محصول وب معمولی امروز با چند زبان نوشته می‌شود: یک زبان سیستمی یا Go برای بک‌اند، TypeScript برای مرورگر، HTML و CSS برای صفحه، SQL برای پایگاه داده، و شل یا YAML برای ساخت. هر کدام ابزارها، سامانه‌ی گونه و مدیر بسته‌ی خودش را دارد. پاسخ سلام یک زبان است که از کد بدون سیستم‌عامل (Bare Metal) تا صفحه‌ی وب را پوشش می‌دهد: برای سرورها و ابزارهای خط فرمان به کد بومی کامپایل می‌شود، یک زبان صفحه‌ی داخلی دارد که HTML، CSS و جاوااسکریپت تولید می‌کند، می‌تواند به WebAssembly و جاوااسکریپت کامپایل شود و کتابخانه‌ی استانداردش HTTP، راه‌اندازهای پایگاه داده و یک بررسی‌کننده برای رشته‌های SQL را در خود دارد.

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

فایل readme پروژه هدف گسترده‌تر را این‌طور بیان می‌کند: ایجاد توازن میان کنترل سطح پایین و بهره‌وری برنامه‌نویس، و پایین آوردن مانع ذهنی ورود. بقیه‌ی طراحی از همین هدف‌ها نتیجه می‌شود.

اصول طراحی زبان برنامه‌نویسی سلام که از این هدف‌ها نتیجه می‌شوند

کد بومی، بدون ماشین مجازی، بدون زباله‌روب. اگر قرار است یک زبان برنامه‌نویسی سیستمی، سرور و ابزار را پوشش دهد، باید فایل‌های اجرایی بومی و کوچک با کارایی پیش‌بینی‌پذیر بسازد. سلام پیش از اجرا (AOT) و از راه C، LLVM یا پشتوانه‌ی (Backend) اختصاصی x86-64 خودش کامپایل می‌شود. در محک (Benchmark) پروژه روی ۳۹ برنامه که در همه‌ی زبان‌ها الگوریتم یکسان دارند، میانگین سلام ۱۰٫۶ میلی‌ثانیه، C ۱۱٫۷ و Rust ۱۱٫۳ میلی‌ثانیه بود؛ یعنی سلام در همان رده‌ی C و Rust قرار می‌گیرد. این عددها شرط و شروط دارند: برنامه‌ها کوتاه‌اند و زمان راه‌اندازی در آن‌ها به حساب می‌آید؛ اختلاف کمتر از حدود ۵ درصد نویز است؛ اجراها روی یک ماشین مجازی CI انجام شده‌اند؛ و سلام در ۶ برنامه از ۳۹ برنامه از سریع‌ترین زبان کامپایلی عقب‌تر بود. همه‌ی عددها در صفحه‌ی سرعت آمده است.

کامپایلر سخت‌گیر به‌عنوان تور ایمنی. وقتی نه زباله‌روب در کار است و نه وارسی‌گر قرض (Borrow Checker)، کامپایلر باید هر چه را می‌تواند بگیرد. سلام متغیرها و تابع‌های بی‌استفاده، مقداردهی دوباره به مقدار تغییرناپذیر، شرط‌هایی که منطقی نیستند، عبارت‌های همخوان ناقص و بسیاری از اندیس‌های بیرون از محدوده را که در زمان کامپایل قابل اثبات‌اند رد می‌کند؛ همه با کد خطا و پیشنهاد اصلاحی که salam check --fix می‌تواند اعمال کند.

باتری‌ها همراه زبان. زبانی که می‌خواهد جای چند ابزار را بگیرد از روز اول به کتابخانه‌ی استاندارد بزرگی نیاز دارد. کتابخانه‌ی سلام شبکه، TLS، پایگاه داده، فشرده‌سازی، رمزنگاری، تصویر و محاسبات عددی را در بر دارد و هر بسته‌اش نام فارسی دارد.

نحو خوانا با یک راه برای هر کار. بلوک‌ها با : باز و با پایان (در انگلیسی end) بسته می‌شوند؛ متغیرها تغییرناپذیرند مگر با ناپایا تعریف شوند؛ منطق با و، یا و وارونه نوشته می‌شود. هر جا دو شکل نوشتاری کار یکسانی بکنند، سلام معمولاً فقط یکی را می‌پذیرد. مقاله‌ی طراحی نحو یکایک این انتخاب‌ها را بررسی می‌کند.

خودمیزبانی. کامپایلر سلام به زبان سلام نوشته شده است. این کامپایلر یکی از بزرگ‌ترین برنامه‌های سلام و جدی‌ترین آزمون این زبان است، چون یک کامپایلر تقریباً همه‌ی قابلیت‌های زبان را به کار می‌گیرد.

این اصول در کد چه شکلی دارند

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

سلام
واردسازی رشته

تابع ریشه:
    متن := "باد آمد و باران آمد و برف آمد"
    واژه‌ها := رشته.تفکیک کردن(متن، " ")
    دیرکن واژه‌ها.آزادکن()
    ناپایا شمار := نگاشت {} برگردان نگاشت<رشته، صحیح>
    دیرکن شمار.آزادکن()
    هر واژه در واژه‌ها:
        قبلی := شمار.دارد(واژه) ? شمار.بگیر(واژه) : ۰
        شمار.درج(واژه، قبلی + ۱)
    پایان
    هر واژه در ["آمد"، "و"، "باد"، "ابر"]:
        سرچاپ واژه، شمار.دارد(واژه) ? شمار.بگیر(واژه) : ۰
    پایان
پایان
خروجیآمد 3 و 2 باد 1 ابر 0

و هدف کاستن از پراکندگی: یک سرور وب که صفحه‌ی HTML آن به همان زبان، در همان فایل نوشته شده و همان کامپایلر گونه‌هایش را بررسی می‌کند. این برنامه اینجا بررسی می‌شود ولی اجرا نمی‌شود، چون روی یک درگاه منتظر می‌ماند:

سلام
واردسازی شبکه.اچ تی تی پی
واردسازی شبکه.مسیریاب

صفحه وضعیت(سرویس: رشته، سالم: منطقی):
    عنوان = "وضعیت " + سرویس
    سرتیتر: اندازه = ۱ محتوا = سرویس پایان
    پاراگراف: محتوا = سالم ? "همه‌ی سامانه‌ها کار می‌کنند." : "کارکرد مختل است." پایان
پایان

تابع نمایش وضعیت(زمینه: صحیح۶۴):
    اچ تی تی پی.اچ تی ام ال(زمینه، وضعیت("صورت‌حساب"، درست))
پایان

تابع ریشه:
    ناپایا ر := مسیریاب.مسیریاب جدید()
    مسیریاب.دریافت(ر، "/status"، نمایش وضعیت)
    ناپایا س := اچ تی تی پی.سرور جدید(۸۰۸۰)
    اچ تی تی پی.استفاده(س، ر)
    اچ تی تی پی.اجرا(س)
پایان

بلوک صفحه زبان چیدمان سلام است: عنصرها و سبک‌ها به شکل کد سلام نوشته می‌شوند و کامپایلر آن‌ها را به HTML تبدیل می‌کند. درس چیدمان این زبان را معرفی می‌کند و درس سرور وب به راه‌اندازی آن روی سرور می‌پردازد.

خلأیی که سلام پر می‌کند، بی‌پرده

اگر همه را کنار هم بگذاریم، سلام این ترکیب را هدف گرفته است:

  • یک زبان سیستمی کامپایلی با گونه‌بندی ایستا در رده‌ی کارایی C و Rust؛
  • که خواندن و نوشتنش ساده‌تر از C، C++ یا Rust باشد؛
  • که صفحه‌ی وب را هم مثل سرور بدون زبان دوم پوشش دهد؛
  • و بتوان آن را به فارسی هم مثل انگلیسی نوشت، با پیام‌های خطا به هر دو زبان.

هر کدام از این‌ها جای دیگری هم پیدا می‌شود. Go از C++ ساده‌تر است، اما زباله‌روب دارد و زبان صفحه ندارد. Rust از سلام ایمن‌تر است، اما یادگیری‌اش سخت‌تر است. TypeScript هم مرورگر را پوشش می‌دهد و هم سرور را، اما روی موتور جاوااسکریپت اجرا می‌شود. زبان‌های آموزشی واژه‌های کلیدی به زبان مادری دارند، اما زبان سیستمی نیستند. آنچه تازه است، این ترکیب است.

هزینه‌ی یک زبان تازه، از جمله زبان سلام

اینجا صداقت مهم است، چون هزینه‌های یک زبان تازه واقعی‌اند و بر دوش نخستین کاربرانش می‌افتند:

  • بدون وارسی‌گر قرض. سلام ایمنی حافظه را آن‌طور که Rust اثبات می‌کند اثبات نمی‌کند. ظرف‌های هیپ با دست آزاد می‌شوند، دیرکن و وارسی‌گر مالکیت کمک می‌کنند، و خطا ممکن است.
  • بوم‌سازگان کوچک. کتابخانه‌ی استاندارد بزرگ است، اما بسته‌های شخص ثالث، پاسخ‌های Stack Overflow، کتاب‌ها و برنامه‌نویس‌های باتجربه در مقایسه با زبان‌های جاافتاده اندک‌اند.
  • تغییر پیش از نسخه‌ی ۱٫۰. زبان هنوز میان نسخه‌ها تغییر می‌کند؛ نحوی که پارسال کار می‌کرد ممکن است امروز کامپایل نشود.
  • استقرار عملیاتی اندک. برای مسئله‌های غیرعادی پاسخ‌های آزموده‌شده‌ی کمتری وجود دارد.
  • دو شکل نوشتاری برای نگهداری. هر قابلیت تازه به شکل فارسی، پیام خطای فارسی و آزمون به هر دو زبان نیاز دارد.

هیچ‌کدام از این‌ها برای یک زبان جوان غیرعادی نیست. Go، Rust و Kotlin همه از همین مرحله گذشتند. این‌که زبانی از این مرحله عبور کند یا نه، به این بستگی دارد که آیا افراد کافی معاوضه‌ی خاص آن را ارزش هزینه‌اش بدانند.

چگونه یک زبان برنامه‌نویسی تازه را بسنجیم

اگر می‌خواهید تصمیم بگیرید که یک زبان تازه ارزش وقت گذاشتن دارد یا نه، چند پرسش از پس تبلیغات برمی‌آید، از جمله تبلیغات خود ما:

  1. دقیقاً کدام هزینه را حذف می‌کند؟ اگر پاسخ «خوشایندتر است» باشد، بدبین باشید.
  2. چه چیزی را فدا کرده؟ هر طراحی بهایی دارد؛ زبانی که ادعا می‌کند بهایی ندارد آن را پنهان کرده است.
  3. آیا می‌شود ادعاهایش را راستی‌آزمایی کرد؟ محک‌ها باید کد و داده‌ی خامشان را منتشر کنند و قابلیت‌ها باید نمونه‌ی اجراشدنی داشته باشند. آموزش و مرجع کتابخانه‌ی سلام همه‌ی نمونه‌هایشان را هنگام ساخت سایت اجرا می‌کنند.
  4. آیا می‌تواند با دیگران کار کند؟ زبان تازه‌ای که نتواند C را فراخوانی کند یا با پروتکل‌های رایج حرف بزند، شما را به بازنویسی وادار می‌کند. سلام C را مستقیم از راه بلوک‌های درون‌داد (در انگلیسی extern) فراخوانی می‌کند.
  5. آیا آشکارا توسعه داده می‌شود؟ سلام با پروانه‌ی GPL-3.0 منتشر شده و روی گیت‌هاب توسعه می‌یابد.

برای آشنایی کامل، از مقاله‌ی زبان برنامه‌نویسی سلام چیست شروع کنید، سپس آن را نصب کنید یا در ویرایشگر آنلاین امتحانش کنید.

پرسش‌های پرتکرار

چرا هنوز زبان برنامه‌نویسی جدید ساخته می‌شود؟

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

زبان برنامه‌نویسی سلام چه مشکلی را حل می‌کند؟

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

آیا زبان سلام می‌خواهد جای C، Rust یا Go را بگیرد؟

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

یک زبان برنامه‌نویسی تازه چقدر طول می‌کشد تا فراگیر شود؟

معمولاً چند سال. Go از معرفی تا نسخه‌ی ۱٫۰ حدود سه سال، Rust از آغاز تا نسخه‌ی ۱٫۰ حدود نه سال و Kotlin از رونمایی تا نسخه‌ی ۱٫۰ حدود پنج سال طول کشید، و سه سال دیگر گذشت تا گوگل آن را زبان ترجیحی اندروید کند. سلام هنوز به نسخه‌ی ۱٫۰ نرسیده است.

زبان سلام

یک زبان، دو خط: برنامه‌نویسی فارسی و انگلیسی با یک کامپایلر در زبان سلام

سلام یک زبان است با دو املا. این مقاله نشان می‌دهد یک فایل فارسی و یک فایل انگلیسی چطور به یک کامپایلر می‌رسند، یک کتابخانه‌ی استاندارد را به اشتراک می‌گذارند، خطاها را به زبان خواننده گزارش می‌کنند و بسته‌های همدیگر را فرا می‌خوانند.

خواندن مقاله
زبان سلام

فراتر از ترجمه‌ی واژه‌های کلیدی: چالش‌های واقعی طراحی زبان برنامه‌نویسی فارسی و عربی

وقتی یک زبان برنامه‌نویسی با خط فارسی یا عربی نوشته می‌شود، در عمل چه چیزهایی خراب می‌شود، از نام‌های فاصله‌دار تا حرف‌های هم‌شکل، و سلام برای هر مشکل چه تصمیم مشخصی گرفته است.

خواندن مقاله