دوال lambda

دوال lambda في Scheme هي دوال مجهولة الاسم — أي بدون اسم. تُعرَّف inline وتُستخدم عادةً لعمليات قصيرة لمرة واحدة. يُعد lambda أداة قوية في البرمجة الوظيفية، تتيح إنشاء منطق موجز ومرن بسرعة.

تكون دوال lambda مفيدة خصوصًا عندما:

  • تحتاج دالة صغيرة لغرض محدد ومؤقت.
  • تمرّر دوالًا كوسائط إلى دوال ذات ترتيب أعلى مثل map أو filter أو fold.
  • تُرجع دوالًا من دوال أخرى.

بناء جملة دوال lambda

يمكن تعريف دوال lambda وحدها…

(lambda (parameter1 parameter2 ...)
  body-expression)

…أو استدعاؤها فورًا:

((lambda (parameter1 parameter2 ...)
   body-expression)
 argument1 argument2 ...)
  • parameter1, parameter2, ...: المعلمات التي تقبلها الدالة.
  • body-expression: المنطق الذي يُنفَّذ عند استدعاء الدالة.
  • استدعاء فوري: يُظهر النموذج الثاني استدعاء lambda فورًا بالوسائط.

أمثلة على دوال lambda

استخدام lambda لعمليات حسابية بسيطة

((lambda (x y) (+ x y)) 3 5)  ; يرجع 8

هنا:

  • تُنشأ دالة lambda لجمع رقمين (x وy).
  • تُستدعى الدالة فورًا بالوسيطين 3 و5.

دوال lambda مضمّنة

يوضّح المثال التالي استخدام for-each مع دالة مُسمّاة ودالة lambda:

استخدام دالة مُسمّاة:

(define (print-item x)
  (lumi-message (number->string x)))

(for-each print-item (list 1 2 3 4))
  • شرح:
    • print-item دالة مُسمّاة تحوّل رقمًا إلى سلسلة (number->string) وتطبعه بـ lumi-message.
    • for-each يطبّق print-item على كل عنصر في القائمة (1 2 3 4).

الإخراج: 1 2 3 4

استخدام دالة lambda:

يمكن كتابة نفس المنطق inline بدالة lambda، دون دالة مُسمّاة منفصلة:

(for-each (lambda (x) (lumi-message (number->string x)))
  (list 1 2 3 4))
  • شرح:
    • (lambda (x) (lumi-message (number->string x))) تُعرّف دالة مجهولة.
    • for-each يطبّق هذه الدالة على كل عنصر في (1 2 3 4).

الإخراج: 1 2 3 4

دوال lambda كوسائط

غالبًا ما تُمرَّر دوال lambda مباشرة إلى دوال ذات ترتيب أعلى مثل map أو filter.

تربيع قائمة أرقام

(map (lambda (x) (* x x)) '(1 2 3 4))  ; يرجع (1 4 9 16)
  • دالة lambda تربّع كل عنصر في القائمة.
  • map يطبّق lambda على كل عنصر.

lambda كقيمة مُرجَعة

يمكن إرجاع دالة lambda من دالة أخرى لإنشاء سلوك ديناميكي.

إنشاء دالة adder

(define (make-adder n)
  (lambda (x) (+ x n)))

(define add5 (make-adder 5))
(add5 10)  ; يرجع 15
  • make-adder تنشئ lambda جديدة تضيف رقمًا محددًا (n).
  • lambda المُرجَعة تُخزَّن في add5، فتضيف 5 إلى مدخلاتها.

استخدام lambda مع let

غالبًا ما تُستخدم lambdas مع let لإنشاء دوال مؤقتة محددة النطاق محليًا.

lambda محلية للجمع

(let ((add (lambda (a b) (+ a b))))
  (add 3 4))  ; يرجع 7
  • let يربط lambda بالاسم add.
  • تُستخدم lambda كدالة عادية ضمن نطاق let.

الجمع بين lambdas ودوال ذات ترتيب أعلى

تتألق lambdas عند دمجها مع دوال ذات ترتيب أعلى لتحويلات بيانات معقدة.

تصفية الأرقام الزوجية

(filter (lambda (x) (= (modulo x 2) 0)) '(1 2 3 4 5 6))  ; يرجع (2 4 6)
  • lambda يتحقق مما إذا كان الرقم زوجيًا.
  • filter يستخدم lambda للاحتفاظ بالأرقام الزوجية فقط.

فوائد دوال lambda

  • الإيجاز: تقلّل lambdas التعليمات البرمجية المعيارية بإزالة الحاجة لدوال مُسمّاة منفصلة.
  • المرونة: يمكن تعريفها واستخدامها حيثما لزم، ما يجعل التعليمات البرمجية أكثر نمطية.
  • إمكانية القراءة: للمهام القصيرة والمحددة، توضّح lambdas الغرض دون ازدحام التعليمات البرمجية بدوال مُسمّاة إضافية.

متى تستخدم دوال lambda

استخدم lambda عندما:

  • المنطق قصير ومكتفي بذاته.
  • الدالة مطلوبة مؤقتًا أو ضمن نطاق محدد فقط.
  • تعمل مع دوال ذات ترتيب أعلى مثل map أو filter أو reduce.

تجنّب lambdas للمنطق المعقد متعدد الأسطر؛ قد يقلّل ذلك إمكانية القراءة. للعمليات الأوسع، استخدم دالة مُسمّاة.

الخلاصة

توفر دوال lambda في Scheme طريقة موجزة وقوية لتعريف دوال مجهولة لمهام محددة. مرونتها وسهولة استخدامها تجعلها أداة أساسية لأي مبرمج Scheme. فهم استخدام lambda بفعالية يساعدك على كتابة نصوص أوضح وأكثر نمطية وكفاءة.