it-swarm.dev

ما هو الفرق بين لغات البرمجة الوظيفية والحتمية؟

تم تصميم معظم اللغات الرئيسية ، بما في ذلك لغات البرمجة الموجهة للكائنات (OOP) مثل C # و Visual Basic و C++ و Java لدعم البرمجة الإلزامية (الإجرائية) بشكل أساسي ، في حين أن Haskell/gofer like languages ​​تعمل بحتة. هل يمكن لأي شخص أن يوضح ما الفرق بين هاتين الطريقتين للبرمجة؟

أعلم أن ذلك يعتمد على متطلبات المستخدم لاختيار طريقة البرمجة ، لكن لماذا يوصى بتعلم لغات البرمجة الوظيفية؟

119
Swapnil Kotwal

التعريف: تستخدم لغة حتمية سلسلة من العبارات لتحديد كيفية الوصول إلى هدف معين. يقال إن هذه العبارات تغير حالة البرنامج حيث يتم تنفيذ كل منها بدوره.

أمثلة: Java هي لغة ضرورية. على سبيل المثال ، يمكن إنشاء برنامج لإضافة سلسلة من الأرقام:

 int total = 0;
 int number1 = 5;
 int number2 = 10;
 int number3 = 15;
 total = number1 + number2 + number3; 

يغير كل عبارة حالة البرنامج ، من تعيين القيم إلى كل متغير إلى الإضافة النهائية لتلك القيم. باستخدام سلسلة من خمس عبارات ، يتم إخبار البرنامج بشكل صريح بكيفية إضافة الأرقام 5 و 10 و 15 معًا.

اللغات الوظيفية: تم إنشاء نموذج البرمجة الوظيفية بشكل صريح لدعم نهج وظيفي خالص لحل المشكلات. البرمجة الوظيفية هي شكل من أشكال البرمجة التصريحية.

مزايا الوظائف البحتة: السبب الرئيسي لتنفيذ التحولات الوظيفية كوظائف بحتة هو أن الوظائف البحتة قابلة للتكوين: أي ، قائمة بذاتها وعديمة الحالة. تجلب هذه الخصائص عددًا من الفوائد ، بما في ذلك ما يلي: زيادة إمكانية القراءة وسهولة الصيانة. هذا لأنه تم تصميم كل وظيفة لإنجاز مهمة محددة في ضوء وسائطها. لا تعتمد الوظيفة على أي حالة خارجية.

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

أسهل اختبار وتصحيح الأخطاء. نظرًا لأنه يمكن بسهولة اختبار الوظائف البحتة بمعزل عن غيرها ، يمكنك كتابة رمز الاختبار الذي يستدعي الوظيفة البحتة بقيم نموذجية ، وحالات Edge صالحة ، وحالات Edge غير صالحة.

For OOP أشخاص أو لغات ضرورية:

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

تكون اللغات الوظيفية جيدة عندما يكون لديك مجموعة ثابتة من الأشياء ومع تطور الشفرة الخاصة بك ، فأنت تقوم أولاً بإضافة عمليات جديدة على الأشياء الحالية. يمكن تحقيق ذلك عن طريق إضافة وظائف جديدة تتوافق مع أنواع البيانات الحالية وتترك الوظائف الحالية بمفردها.

سلبيات:

يعتمد ذلك على متطلبات المستخدم لاختيار طريقة البرمجة ، لذلك لا يوجد ضرر إلا عندما لا يختار المستخدمون الطريقة الصحيحة.

عندما يسير التطور بطريقة خاطئة ، لديك مشاكل:

  • قد تتطلب إضافة عملية جديدة إلى برنامج موجه نحو الكائن تحرير العديد من تعريفات الفئة لإضافة طريقة جديدة
  • قد تتطلب إضافة نوع جديد من الأشياء إلى برنامج وظيفي تحرير العديد من تعريفات الوظائف لإضافة حالة جديدة.
126
user2102654

هنا هو الفرق:

صيغة الامر:

  • بداية
  • بدوره على حذائك حجم 9 1/2.
  • قم بتوفير مساحة في جيبك للاحتفاظ بمجموعة من المفاتيح.
  • ضع المفاتيح في الغرفة للمفاتيح الموجودة في الجيب.
  • دخول المرآب.
  • فتح المرآب.
  • أدخل السيارة.

... وهلم جرا، وعلى ...

  • ضعي الحليب في الثلاجة.
  • توقف.

التعريفي ، حيث الوظيفية هي فئة فرعية:

  • الحليب مشروب صحي ، إلا إذا كنت تواجه مشاكل في هضم اللاكتوز.
  • عادة ، واحد يخزن الحليب في الثلاجة.
  • الثلاجة هي صندوق يحافظ على برودة الأشياء.
  • المتجر هو المكان الذي تباع فيه العناصر.
  • بكلمة "بيع" نعني تبادل الأشياء مقابل المال.
  • أيضا ، فإن تبادل المال للأشياء يسمى "شراء".

... وهلم جرا، وعلى ...

  • تأكد من حصولنا على الحليب في الثلاجة (عندما نحتاجه - للغات وظيفية كسولة).

الخلاصة: في اللغات الحتمية ، تخبر الكمبيوتر كيف يغير البتات والبايت والكلمات الموجودة في ذاكرته وترتيبها. في الأمور الوظيفية ، نخبر الكمبيوتر عن الأشياء والإجراءات وما إلى ذلك. على سبيل المثال ، نقول أن مضروب 0 يساوي 1 ، و مضروب كل رقم طبيعي آخر هو نتاج هذا الرقم و مضروب سلفه. نحن لا نقول: لحساب عامل التكرار لـ n ، قم بحجز منطقة ذاكرة وتخزين 1 هناك ، ثم اضرب الرقم في منطقة الذاكرة بالأرقام من 2 إلى n وقم بتخزين النتيجة في نفس المكان ، وفي النهاية ، سوف منطقة الذاكرة تحتوي على مضروب.

194
Ingo

البرمجة الوظيفية هو شكل من أشكال البرمجة التصريحية ، التي تصف منطق الحساب وترتيب التنفيذ غير واضح تماما.

المشكلة: أريد تغيير هذا المخلوق من حصان إلى زرافة.

  • إطالة العنق
  • إطالة الساقين
  • تطبيق البقع
  • إعطاء المخلوق لسان أسود
  • إزالة ذيل الحصان

يمكن تشغيل كل عنصر بأي ترتيب لإنتاج نفس النتيجة.

البرمجة الضرورية إجرائية. الدولة والنظام مهم.

المشكلة: أريد إيقاف سيارتي.

  1. لاحظ الحالة الأولية لباب المرآب
  2. توقف السيارة في الممر
  3. إذا كان باب الجراج مغلقًا ، افتح باب الجراج ، تذكر الحالة الجديدة ؛ تواصل خلاف ذلك
  4. سحب السيارة في المرآب
  5. أغلق باب المرآب

يجب أن يتم كل خطوة للوصول إلى النتيجة المرجوة. قد يؤدي السحب إلى المرآب أثناء إغلاق باب الجراج إلى كسر باب المرآب.

8
Jakub Keller

معظم اللغات الحديثة بدرجات متفاوتة ضرورية وعملية ولكن لفهم البرمجة الوظيفية بشكل أفضل ، سيكون من الأفضل أخذ مثال للغة الوظيفية البحتة مثل هاسكل على النقيض من الكود الإلزامي بلغة غير وظيفية مثل Java/c #. أعتقد أنه من السهل دائمًا شرح مثال ، لذلك أدناه واحد.

البرمجة الوظيفية: احسب عامل التكرار لـ n ie n! بمعنى أن n x (n-1) x (n-2) x ... x 2 X 1

-- | Haskell comment goes like
-- | below 2 lines is code to calculate factorial and 3rd is it's execution  

factorial 0 = 1
factorial n = n * factorial (n - 1)
factorial 3

-- | for brevity let's call factorial as f; And x => y shows order execution left to right
-- | above executes as := f(3) as 3 x f(2) => f(2) as 2 x f(1) => f(1) as 1 x f(0) => f(0) as 1  
-- | 3 x (2 x (1 x (1)) = 6

لاحظ أن Haskel يسمح بزيادة التحميل على وظيفة إلى مستوى قيمة الوسيطة. الآن أدناه مثال على الكود الإلزامي في درجة متزايدة من اللامبالاة:

//somewhat functional way
function factorial(n) {
  if(n < 1) {
     return 1;
  }
  return n * factorial(n-1);   
}
factorial(3);

//somewhat more imperative way
function imperativeFactor(n) {
  int f = 1
  for(int i = 1; i <= n; i++) {
     f = f * i
  }
  return f;
}

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

يمكن اعتبار المثال اللاحق على أنه رمز Java/c # lang تقريبًا وأول جزء على أنه تقييد للغة نفسها على عكس Haskell لتثقل الوظيفة بالقيمة (صفر) وبالتالي يمكن القول أنها ليست لغة وظيفية خالصة ، من ناحية أخرى يد يمكنك القول أنه يدعم بروغ وظيفية. إلى حد ما.

الإفصاح: لم يتم اختبار/تنفيذ أي من التعليمات البرمجية أعلاه ولكن نأمل أن تكون جيدة بما يكفي لنقل المفهوم ؛ كما أقدر التعليقات على أي تصحيح من هذا القبيل :)

8
old-monk

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

ويترتب على ذلك أن البرنامج الوظيفي هو مجرد تعبير.

يمكنك بسهولة رؤية التباين بين هذين الأسلوبين عن طريق الإشارة إلى الأماكن في برنامج ضروري حيث لم يعد التعبير شفافًا مرجعيًا (وبالتالي لم يتم بناؤه بوظائف وقيم ، ولا يمكن أن يكون بحد ذاته جزءًا من دالة). المكانان الأكثر وضوحًا هما: تحور (مثل المتغيرات) تدفق تحكم غير محلي للآثار الجانبية (مثل الاستثناءات)

في هذا الإطار من البرامج -التعبيرات التي تتألف من الوظائف والقيم ، تم بناء نموذج عملي كامل من اللغات والمفاهيم و "الأنماط الوظيفية" ، والجمع بين الأنظمة المختلفة وأنواع خوارزميات التقييم.

من خلال التعريف الأكثر تطرفًا ، يمكن تسمية أي لغة تقريبًا - حتى C أو Java - وظيفية ، ولكن عادةً ما يحتفظ الأشخاص بمصطلح اللغات ذات التجريدات ذات الصلة على وجه التحديد (مثل الإغلاقات والقيم الثابتة والأدوات التركيبية مثل مطابقة الأنماط). بقدر ما يتعلق الأمر باستخدام البرمجة الوظيفية ، فإنه ينطوي على استخدام functins ويبني الكود دون أي آثار جانبية. تستخدم لكتابة البراهين

4
Romil pawar

تم ممارسة أسلوب البرمجة الضروري في تطوير الويب من عام 2005 حتى عام 2013.

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

ينتج عن أسلوب البرمجة الوظيفية التجريد من خلال طرق ذكية للجمع بين الوظائف.

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

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

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

لذلك يعطينا رئيسنا قائمة من التوجيهات ، ما نعرفه بمثابة وصفة.

سوف تخبرنا الوصفة كيفية عمل الفطيرة. يتم كتابة وصفة واحدة بأسلوب ضروري مثل:

  1. مزيج 1 كوب من الطحين
  2. أضف 1 بيضة
  3. أضف 1 كوب من السكر
  4. صب الخليط في مقلاة
  5. ضع المقلاة في الفرن لمدة 30 دقيقة و 350 درجة فهرنهايت.

ستقوم الوصفة التصريحية بما يلي:

1 كوب دقيق ، 1 بيضة ، 1 كوب سكر - الحالة الأولية

قواعد

  1. إذا كان كل شيء مختلطاً ، ضعيه في المقلاة.
  2. إذا كان كل شيء غير مختلط ، ضعه في وعاء.
  3. إذا كان كل شيء في المقلاة ، ضعه في الفرن.

تتميز المناهج الحتمية بنهج خطوة بخطوة. تبدأ بالخطوة الأولى وانتقل إلى الخطوة 2 وما إلى ذلك.

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

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

نأخذ الحالة الأولية أو المكونات الأولية ونطبق عليها بعض القواعد.

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

لذلك في نهج التصريح ، علينا أن نعرف كيفية هيكلة هذه القواعد بشكل صحيح.

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

مع حالتنا الأولية ، لا يتطابق ذلك لأننا لم نخلط مكوناتنا بعد.

هكذا تقول القاعدة 2 ، إذا لم يتم خلطها فمزجها في وعاء. حسنا نعم تنطبق هذه القاعدة.

الآن لدينا وعاء من المكونات المختلطة كما حالتنا.

الآن نطبق هذه الحالة الجديدة على قواعدنا مرة أخرى.

إذن القاعدة 1 تقول إذا تم خلط المكونات في وعاء ، حسناً نعم الآن تنطبق القاعدة 1 ، دعنا نفعل ذلك.

الآن لدينا هذه الحالة الجديدة حيث يتم خلط المكونات في وعاء. لم تعد القاعدة 1 ذات صلة ، ولا تنطبق القاعدة 2.

تقول القاعدة 3 إذا كانت المكونات في مقلاة ، ضعها في الفرن ، مع العلم أن تلك القاعدة هي التي تنطبق على هذه الحالة الجديدة ، فلنقم بذلك.

ونحن في نهاية المطاف مع فطيرة التفاح الساخنة لذيذ أو أيا كان.

الآن ، إذا كنت مثلي ، فربما تفكر ، لماذا لا نواصل القيام ببرمجة ضرورية. هذا يبدو منطقيا.

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

في النهج التعريفي ، قد يكون لدينا بعض المكونات الأولية أو الحالة الأولية مثل textInput=“” ، متغير واحد.

ربما يبدأ إدخال النص كسلسلة فارغة.

نأخذ هذه الحالة الأولية ونطبقها على مجموعة من القواعد المحددة في طلبك.

  1. إذا قام مستخدم بإدخال نص ، فقم بتحديث إدخال النص. حسنًا ، هذا لا ينطبق الآن.

  2. إذا تم تقديم القالب ، فقم بحساب عنصر واجهة المستخدم.

  3. إذا تم تحديث textInput ، فأعد تقديم القالب.

حسنًا ، لا ينطبق أي من هذا الأمر ، لذا سينتظر البرنامج حدثًا ما.

لذلك في مرحلة ما يقوم المستخدم بتحديث إدخال النص ثم قد نطبق القاعدة رقم 1.

قد نقوم بتحديث ذلك إلى “abcd”

لذلك قمنا بتحديث تحديثات النص والنص المدخلات الخاصة بنا ، لا يتم تطبيق القاعدة رقم 2 ، وتقول القاعدة رقم 3 إذا تم تحديث إدخال النص ، والذي حدث للتو ، ثم نعيد تقديم القالب ، ثم نعود إلى القاعدة 2 التي تنص على ما إذا تم تقديم القالب ، حساب القطعة ، حسنا يتيح حساب القطعة.

بشكل عام ، كمبرمجين ، نريد أن نسعى جاهدين للحصول على المزيد من تصميمات البرمجة التصريحية.

تبدو الضرورة أكثر وضوحًا وضوحًا ، ولكن المقاربة التصميمية تتقن بشكل جيد للغاية بالنسبة للتطبيقات الأكبر حجمًا.

1
Daniel

أعتقد أنه من الممكن التعبير عن البرمجة الوظيفية بطريقة حتمية:
- استخدام الكثير من التحقق من حالة الكائنات وعبارات if... else/switch
- بعض آلية المهلة/الانتظار لرعاية عدم التزامن

هناك مشاكل كبيرة مع هذا النهج:
- تتكرر القواعد/الإجراءات - تتيح حالة الحيلولة فرص حدوث آثار جانبية/أخطاء

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

مثال على الاستخدامات: تشمل تطبيقات الواجهة الأمامية مثل Android أو iOS أو منطق تطبيقات الويب. التواصل مع الخلفية

0
ericn