لماذا نتحمس للغة Elixir
استغرق الأمر 3.5 سنوات من العمل، لكن فريق Elixir أطلق الإصدار 1.0.0 في سبتمبر 2014. وإليكم أسباب حماسنا الكبير له!

بعد أكثر من 3.5 سنوات من العمل، أطلق فريق Elixir الإصدار 1.0.0 في 18 سبتمبر 2014. تهانينا يا شباب!
ولأن بين صفوفنا عددًا من متعددي اللغات البرمجية وعشّاق لغات البرمجة، فمن الطبيعي أن يثير إعلان كهذا حماسنا، لذا أردنا أن نشارككم بعض الأسباب التي تجعلنا نتطلع إلى تجربة هذه اللغة في الأشهر القادمة.
المنصة
من حيث النضج، لا تستطيع منصات كثيرة اليوم منافسة Erlang، التي صدرت لأول مرة عام 1986 وأصبحت مفتوحة المصدر عام 1988.
العمر وحده ليس مهمًا بطبيعة الحال، لكن بما أن Erlang طُوّرت بهدف بناء تطبيقات الاتصالات الهاتفية، فهي تملك ميزات كثيرة مفيدة جدًا في تطوير تطبيقات الويب الحديثة. فأدوات التزامن (concurrency primitives) المبنية على نموذج Actor، إلى جانب الاتصال بين العمليات (IPC) عبر تمرير الرسائل، تتيح لمطوّري Erlang التوسّع بسهولة لا عبر عدة أنوية في الجهاز نفسه فحسب، بل عبر عدة أجهزة أيضًا.
يوضّح هذا المثال المأخوذ من موقع Elixir مدى سهولة التعامل مع IPC:
parent = self()
# Spawns an Elixir process (not an operating system one!)
spawn_link(fn ->
send parent, {:msg, "hello world"}
end)
# Block until the message is received
receive do
{:msg, contents} -> IO.puts contents
end
lang-elixir
ومن الميزات الرائعة الأخرى في بيئة تشغيل Erlang التحميل الساخن للكود (hot code loading)، ويُعرف أيضًا باسم استبدال الكود، وهو يتيح تغيير الكود في تطبيق قيد التشغيل.
لكن منظومة Erlang تخفي حيلة أخرى في جعبتها: OTP، أي Open Telecom Platform، التي تصفها الوثائق بأنها "مجموعة من الوحدات والمعايير المصممة لمساعدتكم على بناء التطبيقات". وتوفّر OTP تجريدات رائعة، مثل وحدات لكتابة تطبيقات خادم عامة (gen_server) لا يلزم فيها إلا تنفيذ مجموعة محددة بوضوح من دوال المعالجة، و gen_fsm لتعريف آلات الحالة المنتهية (Finite State Machines)، أو Supervisor الذي يتيح إدارة العمليات الفرعية بسهولة.
وتشغّل Erlang مشاريع مثل Facebook Chat وWhatsApp وAmazon SimpleDB، ما يثبت قابلية المنصة للتوسّع واستقرارها معًا. ومن المثير أن نتخيل أن Elixir قد تفتح الباب أمام كثير من المطوّرين الجدد للوصول إليها بسهولة أكبر.
صياغة شبيهة بـ Ruby
ثمرة الحب بين Ruby وErlang، Benjamin Tan Wei Hao (@bentanweihao)
بالتأكيد لا ينبغي أن تكون الصياغة (syntax) العامل الحاسم في اختيار لغة البرمجة، لكن الألفة تساعد بالتأكيد في جذب المطوّرين الجدد. ومن المرجح أن تجذب صياغة Elixir المستوحاة من Ruby جمهورًا أوسع من أسلوب Prolog الذي تتبعه Erlang، وهو أسلوب تجدون نقدًا له في تدوينة Damien Katz الشهيرة (وسيئة السمعة) "What Sucks About Erlang".
ورغم أن المؤلف الرئيسي للغة Elixir، José Valim، من أغزر مطوّري Ruby إنتاجًا، فإنه قرر ألا يكتفي "بمجرد" نقل Ruby إلى Erlang VM، بل ابتكر صياغة يألفها القادمون من خلفية Ruby وكذلك من خلفية Erlang (مثل pattern matching وguard clauses). كما أضاف قدرًا من التناظر تفتقر إليه Ruby (مثل كلمة do المفتاحية في تعريفات الأصناف والوحدات)، ما سهّل تنفيذ نظام الماكرو في Elixir.
نعم، هذا صحيح، Elixir توفّر ماكرو صحية (hygienic macros). ورغم أن هناك قولًا قديمًا بين مبرمجي Lisp مفاده أن القاعدة الأولى للماكرو هي ألا تكتب ماكرو، فإنها تكون مفيدة أحيانًا، وتضيف إلى اللغة قدرات قوية في البرمجة الوصفية (meta-programming) وبناء DSL. وإليكم مثالًا على عبارة unless مأخوذًا من موقع المشروع:
defmacro macro_unless(clause, expression) do
quote do
if(!unquote(clause), do: unquote(expression))
end
end
lang-elixir
لن يكون من الممكن تنفيذ السلوك نفسه كدالة، لأن جسمها سيُقيَّم دائمًا دون شرط بوصفه وسيطًا في الاستدعاء.
وهذه الطريقة السهلة لإضافة عناصر إلى اللغة تبدو كأنها من بنياتها الأساسية تتيح أيضًا إنشاء DSL بسهولة، كما توضح مكتبة اختبارات الوحدات (unit testing) في Elixir:
defmodule MyTest do
use TestCase
test "arithmetic operations" do
4 = 2 + 2
end
test "list operations" do
[1, 2, 3] = [1, 2] ++ [3]
end
end
MyTest.run
lang-elixir
أدوات جيدة
بالنسبة إلى لغة حديثة نسبيًا، تملك Elixir بالفعل أدوات داعمة جيدة جدًا.
ومن الأمثلة على ذلك mix، التي يمكن لمطوّري Ruby تخيّلها مزيجًا من ميزات Rake وBundler. وإليكم قائمة مختصرة بالمهام المعرّفة مسبقًا:
mix clean # Delete generated application files
mix cmd # Executes the given command
mix compile # Compile source files
mix deps # List dependencies and their status
mix deps.clean # Remove the given dependencies' files
mix deps.compile # Compile dependencies
mix deps.get # Get all out of date dependencies
mix deps.unlock # Unlock the given dependencies
mix deps.update # Update the given dependencies
mix new # Create a new Elixir project
mix run # Run the given file or expression
mix test # Run a project's tests
lang-elixir
كما ترون، تغطي mix كل الجوانب، من إنشاء المشروع إلى إدارة التبعيات وتشغيل الاختبارات والترجمة (compilation) والتنفيذ.
وسيسعد محبو اختبارات الوحدات بمعرفة أن Elixir تأتي افتراضيًا مع ExUnit، وهو إطار عمل أساسي لاختبارات الوحدات على طراز Test::Unit، وقد رأينا مثالًا عليه في القسم الخاص بـ DSL.
ومن الميزات الذكية الأخرى دعم doc tests. يكفي أن تضمّنوا مثالًا أو أكثر في توثيق الدالة:
defmodule Oozou do
@doc ~S"""
Adds two numbers
## Examples
iex> Oozou.add(2, 2)
4
"""
def add(a, b), do: a + b
end
lang-elixir
وملف الاختبار المقابل بسيط للغاية:
defmodule OozouTest do
use ExUnit.Case, async: true
doctest Oozou
end
lang-elixir
توثيق ممتاز
ومن المواضيع الأخرى التي يبدو أن فريق Elixir يأخذها بجدية كبيرة التوثيق، فهو عنصر أساسي من الدرجة الأولى في اللغة:
defmodule Oozou do
@moduledoc """
We handcraft beautiful web apps
"""
@doc """
Be awesome!
"""
def work(), do: :beautiful_web_app
end
lang-elixir
وسيظهر هذا على النحو التالي في iex، بيئة REPL الخاصة بـ Elixir:
كما يضم موقع المشروع توثيقًا ممتازًا، مثل دليل البدء الذي يغطي اللغة الأساسية وMix وOTP، إضافة إلى البرمجة الوصفية.
وفوق ذلك، يتوفر توثيق API للغة Elixir، ولمكتبة القوالب EEx، وExUnit، وIEx، وعدد من الأدوات والمكتبات الأخرى.
والآن أرونا بعض الكود
رغم أنه ربما ليس أفضل مثال لاستعراض قدرات Elixir في الأنظمة الموزعة، فإن FizzBuzz تمرين مألوف لكثير من المطوّرين، ويستعرض بعض مفاهيم اللغة الأساسية بشكل جميل.
defmodule FizzBuzz do
def compute(n) do
s = case {rem(n, 3), rem(n, 5)} do
{0, 0} -> :FizzBuzz
{0, _} -> :Fizz
{_, 0} -> :Buzz
_ -> n
end
IO.puts(s)
end
end
Enum.map(1..15, &FizzBuzz.compute/1)
# or as list comprehension:
# for i <- 1..15, do: FizzBuzz.compute(i)
lang-elixir
في الكود أعلاه، نعرّف وحدة (module) اسمها FizzBuzz، لا تحتوي إلا على دالة واحدة هي compute. ولاحظوا أن الدوال، على عكس Erlang، تُصدَّر افتراضيًا، فإذا أردتم تعريف دالة خاصة في الوحدة، فاستخدموا defp بدلًا من def.
مصادر
إذا أثار هذا فضولكم وأردتم تجربة Elixir بأنفسكم، فإليكم بعض مصادرنا المفضلة:
- الموقع الإلكتروني
- Elixir Dose
- Elixir Sips
- Introducing Elixir (Simon St. Laurent, J. David Eisenberg)
- Programming Elixir (Dave Thomas)
- The Little Elixir & OTP Guidebook (Benjamin Tan Wei Hao)
- Erlang and OTP in Action (Martin Logan, Eric Merritt, and Richard Carlsson)


