Gleam دیگر به منبع Erlang کامپایل نمی شود
آدرس مقاله: https://gleam.run/news/gleam-doesnt-compile-to-erlang-source-anymore/ آدرس نظرات: https://news.ycombinator.com/item?id=49975619 امتیاز: 256 # نظر: 103
Gleam یک زبان امن و مقیاس پذیر برای ماشین مجازی Erlang و زمان اجرا جاوا اسکریپت است. امروز Gleam نسخه 1.19.0 منتشر شده است، پس بیایید به موارد جدید بپردازیم.
طی چند ماه گذشته جاکومو کاوالیری به طور کامل ژنراتور کد Erlang Gleam را بازنویسی کرده است که طراحی کاملا متفاوتی دارد و مهمتر از همه، فرمت متفاوتی را تولید میکند. قبلا Gleam کد منبع Erlang را تولید می کرد، اکنون فرم های انتزاعی Erlang را تولید می کند.
"اشکال انتزاعی Erlang" یک نمایش میانی است که توسط کامپایلر Erlang استفاده می شود. این درخت مشروحشده با فراداده است که نحو Erlang را نشان میدهد و معمولا با اجرای نشانهگذار و تجزیهکننده Erlang تولید میشود. دارای یک رمزگذاری باینری با استفاده از فرمت اصطلاح خارجی Erlang است، و با این فرمت باینری میتوانیم کد تولید شده خود را مستقیما بارگذاری کنیم و از نیمه جلوی کامپایلر Erlang صرفنظر کنیم.
این مولد کد جدید Erlang چندین مزیت را به همراه دارد:
عملکرد کامپایلر بهبود یافته است و زمان ساخت پروژه های Gleam که در Erlang اجرا می شوند به میزان قابل توجهی کاهش یافته است.
ابرداده مکان در دسترس برای زمان اجرا، اکنون به جای کد منبع Erlang که کامپایلر تولید می کند، به کد منبع اصلی Gleam دقیق است. این بدان معناست که برای مثال، اعداد خطوط در گزارشهای خرابی BEAM و stacktraces کاملا دقیق هستند، در حالی که قبلا ممکن بود نادرست باشند و فقط به نزدیکترین تابع اشاره میکردند. این ابرداده همچنین میتواند پشتیبانی کامل از Gleam را در اشکالزدایی مانند edb فعال کند، اگرچه ما خودمان هیچ کاری روی این موضوع انجام ندادهایم.
کیفیت کد کامپایلر Gleam بهبود یافته است. مولد کد Erlang یکی از قدیمیترین و پایدارترین بخشهای پایگاه کد Gleam بود، بنابراین در حالی که برای ما مشکلی ایجاد نمیکرد، با استانداردها و قراردادهای امروزی مطابقت نداشت. این جایگزینی جدید بسیار عالی است و احتمالا سطح کامپایلر را به طور کلی بالا می برد.
ما هرگز نباید بشنویم که کسی از کلمه "ترانسپایلر" به عنوان توهین آمیز استفاده کند. 1
من در یک لحظه قصد دارم تعدادی اعداد را به شما نشان دهم، اما لطفا به یاد داشته باشید که معیارها همیشه ساختگی هستند و هرگز داستان کامل را بیان نمی کنند. این داده ها می تواند مقدمه یا نقطه پرش خوبی باشد، اما درک خوب مستلزم آن است که فرد تحقیقات و تجربه بیشتری انجام دهد.
این معیار بر اساس پروژه langcompilebench José Valim است. ممنون خوزه! این اندازه گیری زمان صرف شده برای کامپایل 100 ماژول است که هر کدام شامل 100 تابع است که یک رشته "Hello world" را برمی گرداند. این عملی است زیرا این شکل از پروژه آزمایشی را می توان به راحتی در زبان های مختلف تکرار کرد تا شبیه ترین پروژه های آزمایشی را تولید کند، اما در آنچه می تواند به ما بگوید محدود است زیرا فقط زیر مجموعه کوچکی از ویژگی های هر زبان کامپایل می شود.
در پروژه های واقعی کد بسیار متنوع تر خواهد بود و ویژگی های مختلف هزینه های کامپایل متفاوتی در زبان های مختلف خواهند داشت.
اولین مرحله از بازنویسی مولد کد در نسخه 1.18.0 منتشر شد، نسخه قبلی، بنابراین اجازه دهید v1.17.0 را با نسخه جدید منتشر شده v1.19.0 مقایسه کنیم. این نمودار زمان کامپایل پروژه معیار را نشان می دهد، کمتر بهتر است.
همانطور که می بینید، یک پیشرفت قابل توجه! این یک ساخت کامل از ابتدا، بدون هیچ گونه کش است. کامپایل Gleam افزایشی است، بنابراین در طول توسعه معمولی بسیار سریعتر خواهد بود زیرا کل پروژه را کامپایل نمی کند.
langcompilebench اصلی فقط شامل Erlang، Elixir و Gleam میشود، اما من آن را به مجموعهای از زبانهای برنامهنویسی محبوب دیگر گسترش دادهام تا به مردم کمک کنم تا نسبت به سرعت کامپایلهای Gleam در مقایسه با زبانی که با آن آشنا هستند، احساس خشن داشته باشند. من همچنین Gleam را هنگام کامپایل کردن به جاوا اسکریپت گنجانده ام. در اینجا نتایج:
به یاد داشته باشید: این یک معیار ساختگی است و آیا این به تنهایی برای نتیجه گیری سخت در مورد این زبان ها کافی نیست. با این حال، این نتایج نشان می دهد که کامپایل Gleam خوب و سریع است، و به عنوان یک برنامه نویس Gleam می توانم بگویم که توسعه Gleam بسیار لذت بخش است و زمان کمی برای انتظار برای رایانه صرف می شود.
ما از کامپایل از کد منبعی که به کامپایلر Erlang تغذیه میشود، به یک بازنمایی میانی که به کامپایلر Erlang وارد میشود، حرکت کردهایم، اما چرا به طور کلی از کامپایلر Erlang عبور نکنیم؟ آیا نمی توانیم یک مولد بایت کد BEAM بسازیم که از کامپایلر Erlang بهتر عمل کند؟ شاید بتوانیم از اطلاعات نوع Gleam برای تولید کدهای بهینه تر نیز استفاده کنیم.
در حالی که امکان دستیابی به این مزایا وجود دارد، بعید است که بتوانیم. برخلاف فرمهای انتزاعی Erlang و Erlang، بایت کد BEAM ثابت و بدون تغییر نیست. هر نسخه جدید از ماشین مجازی می تواند بایت کد را تکامل داده و بهبود بخشد، عملکردهای جدیدی اضافه کند و گاهی اوقات عملکردی را که اضافی شده است حذف کند. ما باید متعهد شویم که برای همیشه با این تکامل بهروز باشیم و با نگهبانان Erlang همکاری نزدیک داشته باشیم تا برای تغییرات آتی آماده باشیم و نسخههای جدید Gleam را برای نسخههای جدید ماشین مجازی آماده کنیم.
همچنین تلاش قابل توجهی برای بازتولید همه بهینهسازیهای موجود که در طول دههها در کامپایلر Erlang پیادهسازی شدهاند، حتی با کمکی که ممکن است از تجزیه و تحلیل استاتیک قویتر Gleam داشته باشیم، خواهد بود.
Gleam یک پروژه اجتماعی است که با حمایت مالی پشتیبانی می شود. ما تنها کسری از منابع مالی زبانهایی داریم که توسط شرکتها یا مؤسسات دانشگاهی پشتیبانی میشوند، بنابراین باید در مورد کارآمدترین و پایدارترین راهها برای استفاده از منابع خود به دقت فکر کنیم. Gleam یک پایه قابل اعتماد برای توسعه نرم افزار است، هر تصمیمی که می گیریم باید برای سال ها و دهه های آینده کار کند. جمعآوری به فرمهای انتزاعی Erlang امروز نقطهی شیرین هزینه و فایده برای Gleam است.
ما نیز با این تصمیم در شرکت بزرگی هستیم. زبان خواهر و برادر بزرگتر ما Elixir نیز از طریق فرمهای انتزاعی به ارلنگ کامپایل میشود. اگر به اندازه کافی برای اکسیر خوب است، پس برای گلیم به اندازه کافی خوب است!
خوب، در مورد آن کافی است. در Gleam نسخه 1.19.0 چیزهای بیشتری وجود دارد که میتوانید از آن استفاده کنید.
این فقط نسل کد Erlang نیست که کمی عشق دیده است، پیشرفت های خوبی برای جاوا اسکریپت نیز وجود دارد.
در Gleam کنترل جریان با تطبیق الگو با استفاده از عبارت case انجام می شود و به دستورات if تو در تو کامپایل می شود. از آنجایی که تطبیق الگوی بیانی است، کامپایلر میتواند منطق زمان اجرا را مجددا ترتیب داده و بهینهسازی کند، با استفاده از رویکرد تقسیم و غلبه برای یافتن شاخه مناسب در سریعترین زمان ممکن.
جان داونی این فرآیند را برای تولید کد مسطح تر، با دستورات if تو در تو در یک شرط واحد و متغیرهای میانی کمتری، بهبود داده است. به عنوان مثال، این کد Gleam را در نظر بگیرید:
قبلا این بیت کوچک Gleam به این بیت بزرگ جاوا اسکریپت 2 کامپایل می شد:
یک پیشرفت خوب، من مطمئن هستم که شما موافق هستید! با کمال تعجب، این امر باعث میشود که اندازه بستههای کد پس از کوچکسازی و فشردهسازی، تغییری کم یا بدون تغییر ایجاد کند (gzip واقعا جادویی است)، اما کدهای بهدستآمده شاخههای کمتری برای بهینهسازی موتورهای جاوا اسکریپت دارند.
در حالی که آنها یک نحو را در زبان های مربوطه خود به اشتراک می گذارند، نوع لیست دائمی تغییرناپذیر Gleam با نوع آرایه پیوسته قابل تغییر جاوا اسکریپت یکسان نیست. هنگامی که کد Gleam در جاوا اسکریپت کامپایل می شود، هر لیست تحت اللفظی باید به کد جاوا اسکریپت که ساختارهای داده زمان اجرا را می سازد، کامپایل شود. به عنوان مثال، این کد Gleam را در نظر بگیرید:
این به کد 2 جاوا اسکریپت مانند این کامپایل می شود، جایی که یک آرایه جاوا اسکریپت ساخته می شود و به یک تابع ارسال می شود تا آن را به لیست Gleam تبدیل کند.
با این نسخه، کامپایل اکنون کدهای متفاوتی را برای لیست کوتاه واقعی تولید می کند، و کد مستقیم بیشتری تولید می کند که از یک آرایه تبدیل نمی شود.
با موتورهای جاوا اسکریپت مدرن، این منجر به بهبود عملکرد خوب می شود، و به ویژه برای پروژه هایی که از لیست های کوتاه زیادی استفاده می کنند، مانند پروژه هایی که از کتابخانه Luster استفاده می کنند، تاثیرگذار است. ما هیچ بهبودی برای لیست های طولانی تر ثبت نکردیم، بنابراین رویکرد آرایه به لیست هنوز برای آن ها استفاده می شود.
هنگام کامپایل کردن در جاوا اسکریپت، کامپایلر Gleam همچنین توابعی را برای کار با ساختارهای داده تعریف شده توسط برنامه نویس از جاوا اسکریپت ایجاد می کند. علاوه بر این، کامپایلر همچنین میتواند فایلهای اعلان TypeScript را فراهم کند، که امکان ادغام کامل بین TypeScript و Gleam را در یک پروژه واحد فراهم میکند.
یکی از توابع ارائه شده برای هر نوع سفارشی، تابعی است برای بررسی اینکه آیا یک مقدار یک نوع خاص است یا خیر. به عنوان مثال، با توجه به نوع زیر:
تابع تولید شده این اعلان TypeScript را دارد:
خوانندگان برنامه نویس TypeScript با چشم تیزبین ممکن است متوجه مشکلی در اینجا شوند. اگر مقدار قبلا از نوع Box<number> شناخته شده باشد، می توان از این تابع برای اصلاح نوع ظرف به Full استفاده کرد، اما پارامتر نوع عدد به ناشناخته تعمیم داده می شود و باعث از دست رفتن اطلاعات نوع می شود. این بسیار دست و پا گیر است.
جاکومو کاوالیری اضافه بار را به تعریف اضافه کرده است، بنابراین تا حد امکان نوع آن حفظ می شود.
کاربران Gleam معمولا از ابزار رسمی ساخت که بخشی از فایل اجرایی گلیم است استفاده می کنند، اما گاهی اوقات مردم مایلند کد Gleam را در زمینه های دیگر کامپایل و استفاده کنند. به عنوان مثال، یک برنامه نویس Elixir یا Erlang ممکن است بخواهد از یک بسته وابستگی که در Gleam نوشته شده است استفاده کند. این کار در زمان اجرا فوقالعاده عمل میکند زیرا این سه زبان BEAM دارای تعامل عالی با هزینه صفر هستند، اما رسیدن به این نقطه میتواند دشوار باشد، زیرا ابزارهای ساخت Elixir و Erlang از Gleam پشتیبانی داخلی ندارند.
فایل اجرایی Gleam چندین دستور را ارائه می دهد که عملکرد کامپایلر را برای استفاده توسط سایر ابزارهای ساخت، نشان می دهد. این نسخه شامل چندین بهبود در این دستورات است، با هدف دریافت پشتیبانی Gleam در Elixir's Mix و Erlang's rebar3.
ماشین مجازی Erlang نیاز دارد که همه بستهها یک فایل منبع .app به همراه بایت کد کامپایلر داشته باشند. قبلا انتظار می رفت که این ابزارهای ساخت پشتیبانی کننده Gleam این موارد را ارائه دهند، اما اکنون gleam فایل ها را هنگام کامپایل در BEAM برای آنها تولید می کند.
دستور compile-package یک پرچم --no-dev به دست می آورد که کامپایلر فقط کد را از دایرکتوری src بارگیری می کند و بسته های فهرست شده به عنوان dev_dependencies را رد می کند.
دستورات صادرات بسته اطلاعات و صادرات بسته رابط اکنون می توانند اطلاعات خود را در stdout چاپ کنند، در حالی که قبلا باید در یک فایل بنویسند. در کنار آن، دستورات export javascript-prelude و export typescript-prelude اکنون می توانند در یک فایل بنویسند.
از رودریگو آلوارز برای این موارد اضافه شده سپاسگزاریم! امیدواریم به زودی شاهد پشتیبانی Gleam در ابزار ساخت Elixir's Mix باشیم.
Gleam دارای یک سرور داخلی عالی زبان است که عملکرد IDE را برای همه ویرایشگرهایی که از پروتکل سرور زبان پشتیبانی می کنند ارائه می دهد. احتمالا آخرین بخش از عملکرد اصلی پشتیبانی کامل از برچسبهای فیلدها و آرگومانها بود. آلیستر اسمیت این مشکل را برطرف کرده است و پشتیبانی از رفتن به تعریف، یافتن ارجاعات و تغییر نام برچسب ها را اضافه کرده است! با تشکر از شما آلیستر، می دانم که بسیاری از مردم از این ویژگی صرفه جویی در زمان کاملا خوشحال خواهند شد.
یک ساخت WebAssembly از کامپایلر وجود دارد که توسط تور زبان و زمین بازی برای کامپایل Gleam در مرورگر وب استفاده می شود. جان داونی یک تابع format_source جدید اضافه کرده است که به افراد امکان میدهد قالبکننده کد Gleam را در داخل مرورگر اجرا کنند. در آینده نزدیک این قابلیت را به زمین بازی اضافه خواهیم کرد. ممنون جان!
ایجاد پیام های خطا تا حد امکان واضح و مفید برای ما بسیار مهم است. وقتی همه چیز خوب پیش می رود، استفاده از یک ابزار بسیار خوب است، زمانی که اوضاع بد پیش می رود، این تجربه واقعا می تواند به سطح استرس برنامه نویس کمک کند یا به آن آسیب برساند.
خطاهای نحوی تصادفی کوچک می تواند دردناک باشد، به خصوص اگر مطمئن نیستید که اشتباه چیست و کجاست.
0xda157 یک خطای ویژه برای زمانی که نشانگر تضاد ادغام git در کد پیدا میشود، و خطای دیگری برای زمانی که نحو بهروزرسانی رکورد User(..lucy، امتیاز: 10) با رکورد اصلی در موقعیت اشتباه نوشته شده است، مانند User(امتیاز: 10، ..lucy) اضافه کرده است. او همچنین یک خطا برای عملگرهای رویه ای که در Gleam وجود ندارند، مانند += و *= اضافه کرده است.
n0kk23 یک پیام خطای سفارشی مفید برای زمانی که | اضافه کرده است در تطبیق الگو به گونه ای استفاده می شود که نحوی معتبر در Gleam نیست، اما در زبان های دیگر مانند جاوا معتبر است.
Giacomo Cavalieri یک پیام خطای مفید برای اپراتورهای باینری که در عبارات ثابت مجاز نیستند اضافه کرده است و در عین حال تحمل خطا 3 کامپایلر را در صورت وجود این اشتباهات بهبود داده است.
Andrey Kozhev برای زمانی که یک ماژول سعی می کند از یک نوع یا مقدار خصوصی از یک ماژول دیگر در همان بسته استفاده کند، زمینه اضافی را به پیام خطا اضافه کرده است و به آنها اطلاع می دهد که در حالی که وجود دارد، خصوصی است. ما این را برای ماژولهای بستههای وابستگی پیشنهاد نمیکنیم تا از افشای اطلاعات درباره کدهایی که برنامهنویس نگهداری نمیکند جلوگیری کنیم.
و در نهایت، جیمز دولان بررسیکننده نوع را بهگونهای بهبود داده است که تعریف نام مستعار نوع نامعتبر دیگر نمیتواند باعث ایجاد مجموعهای از خطاهای بیشتر در تمام موارد استفاده از نام مستعار شود.
از همه شما برای اینکه اشکال زدایی Gleam را آسان تر و آسان تر کردید متشکرم.
و از رفع کننده های باگ و پولیش کننده های تجربه تشکر می کنم:
0xda157، امرو کادری، آندری کوژف، جاکومو کاوالیری، هاری موهان، ایان چمبرلین، جک برنامهها، جان داونی، لیلیان رز، مار بلویمن، mmustafasenoglu، نائومی رابرتز، رودریگو آلوئنتیاهیل سورناتهان، .
برای جزئیات کامل بسیاری از اصلاحات و بهبودهایی که آنها اجرا کرده اند، تغییرات را ببینید.
ما به سمت هدف خود که بتوانیم به طور مناسب دستمزد اعضای اصلی تیم را پرداخت کنیم، پیشرفت زیادی داشته ایم، اما هنوز راه بیشتری داریم. لطفا از پروژه یا اعضای اصلی تیم حمایت کنید.
با تشکر از همه حامیان ما! و تشکر ویژه از حامی برتر ما:
"Transpiler" به معنای کامپایلری است که فرمت قابل خواندن توسط انسان مانند کد منبع را خروجی می دهد. این یک کلمه به نظر جالب است، اما اغلب مردم از آن به این معنی استفاده می کنند که یک کامپایلر خاص به نوعی پایین تر است. این بسیار احمقانه است، زیرا چیزی در مورد کامپایل کردن به یک قالب قابل خواندن توسط انسان وجود ندارد که پیاده سازی کامپایلر را آسان تر کند. اگر برای شما مهم است که آن خروجی به خوبی فرمت شود، ممکن است حتی سخت تر از استفاده از یک فرمت باینری باشد. ↩︎
کد برای وضوح کمی ویرایش شده است، اما بخش های مربوط به این بهبود بدون تغییر هستند. ↩︎
کامپایلر Gleam قلب سرور زبان Gleam است، بنابراین برخلاف کامپایلرهای سنتی باید بتواند اطلاعاتی در مورد کد ارائه دهد، حتی زمانی که در حالت نامعتبر است. اگر فقط کدهای معتبر میتوانست به طور کامل آنالیز شود، سرور زبان زمانی که برنامهنویس در نیمه راه یک refactoring یا سایر ویرایشهای بزرگ هستند، تجربهای ضعیف را برای برنامهنویس فراهم میکند. ↩︎
متن اصلی (انگلیسی)
Gleam doesn't compile to Erlang source anymore
Article URL: https://gleam.run/news/gleam-doesnt-compile-to-erlang-source-anymore/ Comments URL: https://news.ycombinator.com/item?id=49975619 Points: 256 # Comments: 103