البرمجة الوظيفية في Kotlin: من الألف إلى الياء – دليل شامل

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

البرمجة الوظيفية في Kotlin: من الألف إلى الياء

البرمجة الوظيفية (FP) هي نموذج برمجي ينظر إلى العمليات الحسابية على أنها حساب دوال رياضية ويتجنب تغيير الحالة والبيانات القابلة للتغيير. Kotlin، كونه لغة متعددة النماذج، يوفر أدوات قوية لتطبيق المنهج الوظيفي دون إجبارك على التخلي عن البرمجة كائنية التوجه (OOP) المألوفة. في هذه المقالة، سنشرح المفاهيم الأساسية للبرمجة الوظيفية في Kotlin: من الدوال النقية والثبات إلى التقنيات المتقدمة مثل التركيب والمونادات.



1. أساسيات المنهج الوظيفي: الدوال النقية والثبات

أساس البرمجة الوظيفية يقوم على مبدأين: نقاء الدوال وثبات البيانات.

  • الدالة النقية هي دالة تعتمد نتيجتها فقط على الوسائط المُمررة وليس لها آثار جانبية (لا تغير المتغيرات الخارجية، لا تطبع في وحدة التحكم، لا تصل إلى قاعدة البيانات).
  • الثبات يعني أنه لا يمكن تغيير البيانات بعد إنشائها. بدلاً من تعديل الكائن الموجود، يتم إنشاء نسخة جديدة منه بالتغييرات المطلوبة.

مثال على دالة نقية وغير نقية في Kotlin:

// دالة غير نقية: لها تأثير جانبي (طباعة في وحدة التحكم)fun impureSum(a: Int, b: Int): Int {    println("المجموع: ${a + b}") // تأثير جانبي    return a + b}

// دالة نقية: حساب فقطfun pureSum(a: Int, b: Int): Int = a + b

// الثبات: استخدام val بدلاً من vardata class User(val name: String, val age: Int) // val يجعل الحقول غير قابلة للتغييرfun main() { val user = User("Alice", 30) // user.age = 31 // خطأ في الترجمة! val olderUser = user.copy(age = 31) // إنشاء نسخة جديدة}

استخدام val و data class مع copy() هي الطريقة القياسية للحفاظ على الثبات في Kotlin.



2. دوال الترتيب الأعلى وتعبيرات لامدا

يدعم Kotlin الدوال ككائنات من الدرجة الأولى. هذا يعني أنه يمكن تمرير الدوال كوسائط، وإرجاعها من دوال أخرى، وتخزينها في متغيرات. الدوال التي تستقبل أو تُرجع دوال أخرى تُسمى دوال الترتيب الأعلى.

تعبيرات لامدا هي طريقة مدمجة لإنشاء دوال مجهولة. الصيغة: { وسائط -> جسم }.

// دالة ترتيب أعلى: تستقبل دالة (Int, Int) -> Intfun operateOnNumbers(a: Int, b: Int, operation: (Int, Int) -> Int): Int {    return operation(a, b)}

fun main() { // تعبيرات لامدا val sum: (Int, Int) -> Int = { x, y -> x + y } val multiply: (Int, Int) -> Int = { x, y -> x * y }

println(operateOnNumbers(5, 3, sum)) // 8 println(operateOnNumbers(5, 3, multiply)) // 15

// استخدام لامدا "على الطاير" println(operateOnNumbers(10, 2, { a, b -> a - b })) // 8

// إذا كانت لامدا هي الوسيط الأخير، يمكن وضعها خارج الأقواس (trailing lambda) println(operateOnNumbers(10, 2) { a, b -> a / b }) // 5}

المكتبة القياسية في Kotlin تستخدم دوال الترتيب الأعلى بشكل نشط: map، filter، reduce للمجموعات.

val numbers = listOf(1, 2, 3, 4, 5)val evenSquares = numbers    .filter { it % 2 == 0 } // {2, 4}    .map { it * it }        // {4, 16}println(evenSquares) // [4, 16]


3. تركيب الدوال والكاري

التركيب هو عملية دمج دالتين أو أكثر لإنشاء دالة جديدة. في Kotlin لا يوجد عامل تركيب مدمج كما في Haskell، ولكن يمكن تنفيذه يدويًا أو باستخدام دوال الإضافة (extension functions).

// تركيب دالتينinfix fun  ((B) -> C).compose(f: (A) -> B): (A) -> C = { a -> this(f(a)) }

fun main() { val toInt: (String) -> Int = { it.toInt() } val square: (Int) -> Int = { it * it }

val squ

المدونات

توصيات الكتب