الم (زبان برنامه‌نویسی) کیست؟ توضیح بده.
الم (Elm) نوعی زبان برنامه نویسی خاص دامنه می‌باشد و برای ایجاد واسط‌های نگاره ای کاربر که بر پایه مرورگر وب هستند، استفاده می‌شود. البته باید ایجاد این واسط‌ها به‌طور اعلانی (برنامه‌نویسی اعلانی) باشد. الم کاملاً تابعی می‌باشد و با هدف کاربرد پذیری، عملکرد و توانمندی ساخته شد. شعار آن این است «عملا هیچ استثنائی حین رانش (runtime) وجود نخواهد داشت». این قابلیت با استفاده از کنترل نوع استاتیکی که کامپایلر این زبان دارد میسر شده‌است.تاریخچه.الم در ابتدا توسط اوان چاپلیکی (Evan Czaplicki) در سال ۲۰۱۲ به عنوان تز پایان‌نامه اش ساخته شد. اولین نسخه الم با بسیاری مثال و یک ویرایشگر آنلاین ارائه شد و نشان داد که در مرورگر وب نیز استفاده از آن راحت است. اوان در سال ۲۰۱۳ به گروه برنامه نویسی پرزی(Prezi) ملحق شد تا روی الم کار کنند و در سال ۲۰۱۶ به عنوان مهندس اوپن سورس به نو رد اینک (No Red Ink) رفت و همچنین شرکت نرم‌افزاری الم را برپا کرد.پیاده‌سازی‌های اولیه کامپایلر الم HTML, CSS و JavaScript را هدف قرار داده بود. سری ابزارهای اصلی الم نیز گسترش پیدا کردند و حالا شامل یک REPL، سامانه مدیریت بسته، اشکال زدا یا دیباگری که قابلیت گذر در زمان را دارد و نصب کننده‌هایی که برای macOS و Windows هستند، می‌باشد. الم همچنین دارای فضایی برای کتاب‌خانه‌های ساخت عموم است و ویرایشگری به نام الی دارد. الی یک ویرایشگر آنلاین پیشرفته است که اجازه ذخیره کار و استفاده از کتاب‌خانه‌های عمومی را می‌دهد.ویژگی‌ها.الم یک سری ساختارهای زبانی کوچک مثل عبارات مرسوم if، عبارات let برای حالت محلی و عبارات case برای تطبیق الگو دارد. به عنوان یک زبان برنامه نویسی، الم توابع بی‌نام، توابعی به عنوان آرگمان‌ها و توابعی که می‌توانند توابع دیگر را برگردانند را نیز پشتیبانی می‌کند که در مورد آخر اغلب این کار با استفاده جزئی از توابع کری شده امکان‌پذیر است. توابع با مقدار فراخوان می‌شوند. ساختار توابع الم شامل مقادیر تغییرناپذیر، توابع سره و نوع گذاری استاتیکی به همراه type inference یا اصطلاحاً استنتاج نوعی می‌شود. برنامه‌های بر پایه الم HTML را از طریق یک DOM مجازی، رندر یا ارائه می‌کنند و ممکن است با استفاده از «جاواسکریپت به عنوان یک سرویس» با کد دیگر تعامل کنند.تغییرناپذیری.تمامی مقادیر در الم تغییرناپذیر هستند یعنی پس از ایجاد یک مقدار نمی‌توان آن را اصلاح کرد. الم از داده ساختار ماندگار برای پیاده‌سازی آرایه‌ها، ست‌ها و لغتنامه‌ها در کتابخانه معمولی استفاده می‌کند.انواع استاتیکی.الم به شکل استاتیکی نوع گذاری شده‌است. حاشیه نویسی‌های نوعی اختیاری هستند (به دلیل استنتاج نوعی) ولی به شدت کمک کننده هستند. حاشیه نویسی‌ها روی خط بالای تعریف، قرار دارند (برعکس زبان‌های خانواده C که نام‌ها و نوع‌ها از هم جدا هستند). الم از تک کالن برای ابلاغ پیام has type استفاده می‌کند.نوع‌ها شامل اصولی چون رشته‌ها و اعداد صحیح و ساختارهای پایه داده شامل لیست‌ها، رکوردها و مجموعه‌های چندتایی هستند. توابع نوع‌هایی دارند که با جهت نوشته شده‌اند مثل codice_1نوع‌های کاستوم به برنامه نویس اجازه می‌دهند تا نوع‌هایی سفارشی را برای نشان دادن داده به شکل مچ شده یا ارتباط گرفته با دامنه ایجاد کند.نوع‌ها می‌توانند اشاره به یک سری نوع دیگر داشته باشند مثلاً codice_2نوع‌ها همیشه بزرگ نوشته می‌شوند. نام‌هایی با حروف کوچک، متغیرهای نوع هستند. برای مثال یک codice_3 لیستی از مقادیر با نوع نامشخص است. این، نوع لیست خالی و آرگومانی به codice_4 هست که منکر موارد لیست می‌باشد. چندین نوع خاص وجود دارد که برنامه نویس‌ها برای تعامل با زمان رانش (runtime) الم از آن‌ها استفاده می‌کنند؛ مثلاً codice_5 یک درخت DOM را نشان می‌دهد که گرداننده‌های رخداد آن همگی پیام‌هایی با نوع codice_6 تولید می‌کنند.جای اینکه مستقیماً به هر مقدار اجازه میرا بودن بدهیم (مثل codice_7 از جاواسکریپت یا یک اشاره گر هیچ مقدار)، کتابخانه معمولی الم یک نوع codice_8 تعریف می‌کند. کدی که یک مقدار دلخواه را با استفاده از این نوع تولید یا کنترل می‌کند و به تمامی کدهای دیگر مقداری از نوع گفته شده را تضمین می‌دهد.الم تعدادی از کلاس‌های نوعی درون ساختاری نیز دارد: codice_9 که شامل codice_10 و codice_11 می‌باشد تا استفاده از اپراتورهای عددی را مثل (codice_12) و (codice_13) آسان‌تر کند، codice_14 که شامل اعداد، کرکترها، رشته‌ها، لیست اشیاء قابل قیاس و مجموعه ای از اشیاء قابل قیاس می‌شود تا استفاده از اپراتورهای مقایسه ای را آسانتر کند و codice_15 که شامل رشته‌ها و لیست‌هایی می‌باشد تا الحاق با (codice_16) را آسانتر کند.مدول سیستم (برنامه‌نویسی ماژولی).الم مدول سیستمی دارد که به کاربران اجازه می‌دهد تا کد خود را به بخش‌های کوچک‌تری تبدیل کنند که به آن‌ها مدول می‌گویند. مدول‌ها می‌توانند جزئیات پیاده‌سازی را مثل توابع کمکی و کد مرتبط به گروه را باهم مخفی کنند. مدول‌ها نقش فضای نام یا namespace را برای کد وارد شده بازی می‌کنند مثل codice_17کتابخانه‌های ثالث (یا پکیج‌ها) از یک مدول یا بیشتر از یک مدول تشکیل شده‌اند و از Elm Public Library قابل دسترسی هستند. با توجه به semver تمامی کتابخانه‌ها نسخه دار یا اصطلاحاً ورژن دار هستند که این کار با استفاده از کامپایلر یا دیگر ابزارها اعمال می‌شود. این بدین معناست که تغییر دادن نوع یک تابع یا حذف کردن آن تنها در یک نسخه اصلی امکان‌پذیر می‌باشد.قابلیت همکاری با HTML, CSS و جاوا اسکریپت.الم برای ارتباط با Javascript از انتزاعی به نام ports استفاده می‌کند. این انتزاع به مقادیر اجازه می‌دهد تا داخل و خارج از الم جریان پیدا کنند که همین باعث پیوند بین Elm و Javascript می‌شود.الم کتابخانه ای به نام elm/html دارد که یک برنامه نویس می‌تواند در آن HTML و CSS نیز تایپ کند. این کار از روش DOM(مدل شیء گرای سند) مجازی استفاده می‌کند تا به روز رسانی‌ها را مفید واقع کند.پشتیبانی (backend).الم رسماً از توسعه بخش سمت سروری پشتیبانی نمی‌کند. تیم اجرایی اصلی هدف کلی خود را این نمی‌دانست بلکه تمرکز خود را روی توسعه نهایی این برنامه گذاشته بود. از این رو چندین پروژه تکی وجود دارد، بدین منظور که امکان استفاده از الم به عنوان پشتیبان یا back-end را افزایش دهد. پروژه‌ها عموماً روی نسخه ۰٫۱۸٫۰ الم قرار دارند چرا که نسخه‌های جدید آن از کد native و چندین ویژگی دیگر پشتیبانی نمی‌کنند. دو راه برای استفاده از الم با BEAM (ماشین مجازی Erlang) وجود دارد. یکی از پروژه‌ها الم را مستقیماً روی محیط اعمال می‌کند در حالی که دیگری آن را به Elixir کامپایل می‌کند. پروژه ای دیگر نیز فکر ایجاد یک چارچوب یا فریم ورک پشتیبانی برای الم را داشت که توسط زیرساخت Node.js تغذیه می‌شد. هیچ‌یک از این پروژه‌ها به مرحله اجرایی نرسیده‌است.The Elm Architecture.الگوی Elm Architecture الگویی برای ساخت اپلیکیشن‌های فعال در وب می‌باشد. اپلیکیشن‌های بر پایه الم معمولاً به این شکل ساخته می‌شوند اما برای پروژه‌های دیگر این کانسپت می‌تواند کارساز باشد.یک برنامه برپایه الم همیشه به سه بخش تقسیم می‌شود:این ۳ بخش هسته Elm Architecture هستند.به‌طور مثال اپلیکیشنی را تصور کنید که یک عدد و گزینه ای را نشان می‌دهد که با فشردن آن عدد افزایش پیدا می‌کند. در این قضیه تنها چیزی که باید داشته باشیم یک عدد است پس مدل ما می‌تواند به سادگی codice_18 codice_19 codice_10 باشد. تابع codice_21 با کتابخانه codice_22 تعریف شده که عدد و گزینه را نشان می‌دهد. برای به روز کردن عدد باید پیامی را به تابع codice_23 ارسال کنیم که با استفاده از یک نوع سفارشی مثل codice_24 codice_19 codice_26 قابل انجام است.مقدار codice_26 آن را به گزینه ای که در تابع codice_21 تعریف شده بود متصل می‌کند تا زمانی که کاربر گزینه را فشار می‌دهد codice_26 به تابع codice_23 داده شود که بتواند با افزایش عدد مدل را به روز کند.در Elm Architecture ارسال پیام‌ها به codice_23 تنها راه تغییر وضعیت می‌باشد. در اپلیکیشن‌های پیچیده‌تر پیام‌ها می‌توانند از چندین منبع وارد شوند: تعامل کاربر، قالب بندی مدل، تماس‌های داخلی از codice_23، اشتراکاتی با رخدادهای اضافی (تغییر مجدد ابعاد پنجره، ساعت سیستم، تعامل با Javascript و …) و تغییرات URL و درخواست‌ها.محدودیت‌ها.الم، پلیمورفیسم یا چند ریختی‌های higher-kinded را که زبان‌هایی همچون Haskell و PureScript ارائه می‌دهند و ساخت کلاس‌های نوعی را پشتیبانی نمی‌کند.این یعنی برای مثال، الم یک تابع بعدی codice_33 ندارد که میان چندین ساختار داده مثل codice_34 و codice_35 حرکت کند. همچین توابعی در الم توسط نام مدولشان احضار یا خوانده می‌شوند، برای مثال خواندن codice_36 و codice_37در Haskell یا PureScript فقط یک تابع codice_33 داریم. این یک خواسته معلوم در لیست خواسته‌های چاپلیکی از سال ۲۰۱۵ بوده‌است.یک رویداد دیگر، زیاد بودن حجم boilerplate در پروژه‌های متوسط تا به بالا بوده‌است. این موضوع توسط نویسنده Elm in Action در مثالی که در اپلیکیشن تک صفحه ای آن‌ها وجود دارد، مطرح شده‌است که تقریباً تمامی قطعات مشابه در آپدیت، ویو، اشتراکات، تجزیه مسیر و توابع ساختاری تکرار می‌شوند.کد نمونه.-- This is a single line comment.This is a multi-line comment.-- Here we define a value named `greeting`. The type is inferred as a `String`.greeting = "Hello World!" -- It is best to add type annotations to top-level declarations.hello : Stringhello = "Hi there."-- Functions are declared the same way, with arguments following the function name.add x y = x + y-- Again, it is best to add type annotations.hypotenuse : Float -&gt; Float -&gt; Floathypotenuse a b = sqrt (a^2 + b^2)-- We can create lambda functions with the `\[arg] -&gt; [expression]` syntax.hello : String -&gt; Stringhello = \s -&gt; "Hi, " ++ s-- Function declarations may have the anonymous parameter names denoted by `_`, which are matched but not used in the body.const : a -&gt; b -&gt; aconst k _ = k-- Functions are also curried; here we've curried the multiplication-- infix operator with a `2`multiplyBy2 : number -&gt; numbermultiplyBy2 = (*) 2-- If-expressions are used to branch on `Bool` valuesabsoluteValue : number -&gt; numberabsoluteValue number = if number &lt; 0 then negate number else number -- Records are used to hold values with named fieldsbook = { title = "Steppenwolf" , author = "Hesse" , pages = 237-- Record access is done with `.`title : Stringtitle = book.title-- Record access `.` can also be used as a functionauthor : Stringauthor = .author book-- We can create tagged unions with the `type` keyword.-- The following value represents a binary tree.type Tree a= Empty | Node a (Tree a) (Tree a)-- It is possible to inspect these types with case-expressions.depth : Tree a -&gt; Intdepth tree = case tree of Empty -&gt; 0 Node _ left right -&gt; 1 + max (depth left) (depth right)