المسارات
/
Julia
Julia
/
التمارين
/
حبيب الثانوية
حبيب الثانوية

حبيب الثانوية

تمرين تعلّمي

مقدمة

تشجّع Julia المبرمجين على وضع أكبر قدر ممكن من الكود داخل دوال يمكن ترجمتها آنيًا، وإنشاء دوال صغيرة كثيرة هو بحسب التصميم سريع الأداء.

وهذا يؤدي عادةً إلى وجود دوال صغيرة بسيطة كثيرة، تحتاج إلى أن تُدمج معًا لتنفيذ مهام غير بسيطة.

من الأساليب الواضحة تداخل نداءات الدوال. المثال التالي مصطنع جدًا، لكنه يوضّح الفكرة.

julia> first.(titlecase.(reverse.(["my", "test", "strings"])))
3-element Vector{Char}:
 'Y': ASCII/Unicode U+0059 (category Lu: Letter, uppercase)
 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)

عيب هذا الأسلوب أن قابلية القراءة تنخفض بسرعة كلما زاد عمق التداخل.

نحتاج إلى أسلوب أبسط وأكثر مرونة.

التركيب

هذه هي التقنية التي يعشقها علماء الرياضيات، وقد نقلت Julia صياغتها الرياضية.

يمكن composed عددٍ اعتباطي من الدوال معًا باستخدام معاملات ∘ (تُدخل بكتابة \circ ثم ضغط زر الجدولة). ويمكن استخدام النتيجة كدالة واحدة.

julia> compfunc = first ∘ titlecase ∘ reverse
first ∘ titlecase ∘ reverse
julia> compfunc.(["my", "test", "strings"])
3-element Vector{Char}:
 'Y': ASCII/Unicode U+0059 (category Lu: Letter, uppercase)
 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)
# alternative syntax, giving the same result
julia> (first ∘ titlecase ∘ reverse).(["my", "test", "strings"])

هناك نقطتان جديرتان بالملاحظة:

  • تظهر الدوال الأولى بالترتيب نفسه كما في حالة التداخل، وتُنفَّذ من اليمين إلى اليسار.
  • ليس من السهل استخدام البث عند التركيب، لكن يمكن تطبيقه عند نداء الدالة المركّبة.

خطوط الأنابيب

قد يُنظر إلى بديل آخر على أنه أسلوب المبرمجين لا أسلوب علماء الرياضيات.

Pipelines مستخدمة منذ زمن طويل في نصوص Unix shell، وأصبحت في الآونة الأخيرة شائعة في لغات البرمجة السائدة (يُنسب إلى F# أحيانًا أنها رائدة في تبنّيها).

الفكرة الأساسية هي البدء ببعض البيانات، ثم تمريرها عبر تسلسل من الدوال للحصول على النتيجة.

معامل الأنبوب هو |> (كما في F# والإصدارات الحديثة من R)، مع أن Julia لديها أيضًا نسخة بث .|>.

julia> ["my", "test", "strings"] .|> reverse .|> titlecase .|> first
3-element Vector{Char}:
 'Y': ASCII/Unicode U+0059 (category Lu: Letter, uppercase)
 'T': ASCII/Unicode U+0054 (category Lu: Letter, uppercase)
 'S': ASCII/Unicode U+0053 (category Lu: Letter, uppercase)

أصبح التنفيذ الآن من اليسار إلى اليمين حصرًا، حيث يتدفق ناتج كل دالة في اتجاه السهم ليصبح مدخل الدالة التالية.

القيود وحلول بديلة وخيارات أخرى

ليس من قبيل المصادفة أن الدوال المستخدمة لتوضيح التركيب وخطوط الأنابيب جميعها تأخذ وسيطًا واحدًا.

بعض اللغات الوظيفية المحضة تمرّر الوسيط الأول إلى دالة لكنها تسمح بإدراج وسائط أخرى.

في المقابل، لا تتوقع Julia في خط الأنابيب سوى أسماء الدوال (أو ما يعادلها)، دون أي وسائط إضافية.

وهناك أسباب تقنية مهمة لذلك (تتعلق بأن currying ليس جزءًا معياريًا من تصميم اللغة). وعلى العديد ممن لا يفهمون الـ currying أن يتقبلوا ببساطة أن هذا القيد ليس سهوًا ناتجًا عن الإهمال، وأنه ليس مرجحًا أن يتغير في إصدارات Julia المستقبلية.

حلول بديلة

نحتاج إلى دوال تأخذ وسيطًا واحدًا وتفعل ما يلزم. لحسن الحظ، تعريف دوال جديدة في Julia أمر سهل.

وبأبسط صورة، يمكننا استخدام anonymous function. مثلًا، إذا كانت لدينا سلسلة نصية واحدة كمدخل وأردنا تقسيمها عند الشرطات السفلية:

julia> "my_test_strings" |> (s -> split(s, '_'))
3-element Vector{SubString{String}}:
 "my"
 "test"
 "strings"

ويمكن بعد ذلك تمرير هذه المصفوفة عبر الأنابيب إلى دوال أخرى، كما في السابق.

وضع الدالة المجهولة بين الأقواس الهلالية اختياري في هذه الحالة، لكنه عمومًا أسلوب مفيد لتقليل الالتباس.

وبالمثل، يمكننا إنشاء دالة مسماة في موضع أبكر من البرنامج وإعادة استخدامها عند الحاجة.

التعليمات

في هذا التمرين، ستساعد حبيبين من المدرسة الثانوية على إعلان حبهما على وسائل التواصل الاجتماعي، عبر إنشاء قلب يونيكود بالحرفين الأولين من اسميهما:

❤ J.  +  M. ❤

1. نظّف الاسم

نفّذ الطريقة cleanupname. يجب أن تأخذ اسمًا وتحذف منه كل محارف - مستبدلةً إياها بمسافة. ويجب أيضًا أن تحذف أي مسافات بيضاء من بداية الاسم ونهايته.

julia> cleanupname("Jane-Ann")
"Jane Ann"

2. احصل على الحرف الأول من الاسم

نفّذ الطريقة firstletter. يجب أن تأخذ اسمًا وتُرجع حرفه الأول على هيئة سلسلة نصية. احرص على إعادة استخدام cleanupname التي عرّفتها في الخطوة السابقة ودمجها مع دوال أخرى.

julia> firstletter("Jane")
"J"

3. نسّق الحرف الأول كحرف اختصاري

نفّذ الطريقة initial. يجب أن تأخذ اسمًا وتُرجع حرفه الأول بحالة أحرف كبيرة متبوعًا بنقطة. احرص على إعادة استخدام firstletter التي عرّفتها في الخطوة السابقة.

initial("Robert")
"R."

4. ضع الحرفين الأولين داخل القلب

نفّذ الطريقة couple. يجب أن تأخذ اسمين وتُرجع الحرفين الأولين محاطين بقلوب إيموجي. احرص على إعادة استخدام initial التي عرّفتها في الخطوة السابقة.

couple("Blake Miller", "Riley Lewis")
"❤ B.  +  R. ❤"
تعديل عبر GitHub يفتح الرابط في نافذة أو علامة تبويب جديدة
Julia Exercism

مستعد لبدء حبيب الثانوية؟

سجّل في Exercism لتتعلّم وتتقن Julia عبر 35 مفهومًا128 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.