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

القيم والوظائف
مرة أخرى ، ضع في اعتبارك هذه الوظيفة البسيطة.
let add1 x = x + 1
ماذا يعني x
هنا:
- خذ بعض القيمة من المجال (النطاق).
- استخدم الاسم "
x
" لتوفير هذه القيمة بحيث يمكن الوصول إليها لاحقًا.
استخدام اسم لتمثيل قيمة يسمى ربط. الاسم " x
" هو "مرتبط" بقيمة الإدخال.
لذلك إذا قمت بحساب دالة بقيمة إدخال ، على سبيل المثال ، 5 ، فسيحدث ما يلي: أينما تكون " x
" في التعريف الأصلي ، يتم تعيين القيمة 5 ، على غرار وظيفة "البحث والاستبدال" في محرر نصوص.
let add1 x = x + 1 add1 5 // «x» with «5» // add1 5 = 5 + 1 = 6 // 6
من المهم أن نفهم أن هذه ليست مهمة. " x
" ليست "فتحة" وليست متغيرًا بقيمة محددة يمكن تغييرها لاحقًا. هذا ارتباط لمرة واحدة لاسم " x
" بقيمة معينة. هذه القيمة هي واحدة من الأعداد الصحيحة المحددة مسبقًا ، ولا يمكن تغييرها. على سبيل المثال مرة واحدة لا يمكن تغيير س . التصنيف المرتبط بالقيمة مرتبط إلى الأبد بهذه القيمة.
هذا المبدأ هو جزء هام من التفكير الوظيفي: لا توجد "متغيرات" ، فقط قيم .
الوظائف كقيم
إذا فكرت في الأمر لفترة أطول قليلاً ، يمكنك أن ترى أن الاسم " add1
" في حد ذاته هو مجرد ربط بـ "وظيفة تزيد المدخلات بمقدار واحد". الوظيفة نفسها مستقلة عن الاسم المرتبط بها.
من خلال تقديم let add1 x = x + 1
، نقول let add1 x = x + 1
F # "في كل مرة ترى فيها اسم" add1
"، استبدله بوظيفة تضيف 1 إلى الإدخال." يسمى " add1
" قيمة دالة .
لمعرفة أن الوظيفة لا تعتمد على اسمها ، يكفي تنفيذ التعليمات البرمجية التالية:
let add1 x = x + 1 let plus1 = add1 add1 5 plus1 5
كما ترون ، " add
" و " plus
" هما اسمان مرتبطان بنفس الوظيفة.
يمكنك دائمًا تحديد دالة القيمة من خلال توقيعها ، والتي تحتوي على domain -> range
النموذج القياسي domain -> range
. التوقيع المعمم لدالة القيمة:
val functionName : domain -> range
قيم بسيطة
تخيل عملية لا تأخذ شيئًا وتعيد دائمًا 5.

ستكون عملية "مستمرة".
كيف يمكن وصف ذلك في F #؟ نريد أن نخبر المترجم: "في كل مرة ترى فيها الاسم c
، استبدله بـ 5". مثل هذا:
let c = 5
عندما يعود الحساب:
val c : int = 5
هذه المرة لا يوجد سهم مطابق ، فقط int. من الجديد - علامة مساوية للقيمة الحقيقية المستنتجة بعدها. يعرف المترجم F # أن هذا الربط له قيمة معروفة ، والتي سيتم إرجاعها دائمًا ، أي الرقم 5.
بعبارة أخرى ، لقد حددنا للتو قيمة ثابتة ، أو ، من حيث F # ،.
يمكنك دائمًا تمييز قيمة بسيطة من دالة قيمة ، لأن جميع القيم البسيطة لها توقيع مشابه:
val aName: type = constant // -
القيم البسيطة مقابل قيم الدوال | معنى بسيط مقابل وظائف القيمة
من المهم أن نفهم أنه في F # ، على عكس اللغات الأخرى مثل C # ، هناك اختلاف بسيط جدًا بين القيم البسيطة ووظائف القيمة. كلا النوعين عبارة عن قيم يمكن ربطها بالأسماء (باستخدام الكلمة الرئيسية let
) ، وبعد ذلك يمكن تمريرها في كل مكان. في الواقع ، سنرى قريبًا أن فكرة أن الوظائف هي قيم يمكن تمريرها كمدخلات إلى وظائف أخرى هي أحد الجوانب الرئيسية للتفكير الوظيفي.
لاحظ أن هناك اختلافًا طفيفًا بين قيمة بسيطة ودالة قيمة. للدالة دومًا نطاق ونطاق ، ويجب "تطبيقها" على الوسيطة من أجل إرجاع النتيجة. لا يلزم حساب قيمة بسيطة بعد الربط. باستخدام المثال أعلاه ، إذا أردنا تعريف "دالة ثابتة" تُرجع 5 ، فيمكننا استخدام:
let c = fun()->5 // or let c() = 5
يبدو توقيع هذه الوظائف كما يلي:
val c : unit -> int
ليس هكذا:
val c : int = 5
سيتم توفير المزيد من المعلومات حول unit
وبناء الجملة والوظائف المجهولة لاحقًا.
"القيم" مقابل "كائنات"
في لغات البرمجة الوظيفية ، مثل F # ، تسمى معظم الأشياء "القيم". في اللغات الموجهة للكائنات ، مثل C # ، تسمى معظم الأشياء "الكائنات". ما الفرق بين "المعنى" و "الشيء"؟
القيمة ، كما رأينا أعلاه ، هي عضو في المجال. مجال الأعداد الصحيحة ، نطاق السلاسل ، مجال الدالات التي تعين الأعداد الصحيحة للسلاسل ، وهكذا. من حيث المبدأ ، القيم غير قابلة للتغيير (غير قابلة للتغيير). والمعاني لا ترتبط بالسلوك المرتبط بها.
الكائنات في التعريف الأساسي هي تغليف بنية البيانات مع السلوك (الأساليب) المرتبطة بها. بشكل عام ، يجب أن يكون للكائنات حالة (أي قابلة للتغيير) ، ويجب توفير جميع العمليات التي تغير الحالة الداخلية بواسطة الكائن نفسه (عبر علامة "نقطة").
في F # ، حتى القيم البدائية لها قدر معين من سلوك "الكائن". على سبيل المثال ، يمكنك الحصول على طول سلسلة من خلال نقطة:
«abc».Length
ولكن بشكل عام ، سنتجنب مصطلح "الكائن" للقيم القياسية في F # ، ونحفظه للإشارة إلى الفئات الكاملة ، أو القيم الأخرى التي توفر طرقًا.
قيم التسمية
اصطلاحات التسمية القياسية المستخدمة لأسماء القيم والوظائف هي في الأساس حروف أبجدية رقمية + شرطات سفلية. ولكن هناك زوجان من الإضافات:
- يمكنك إضافة علامة اقتباس أحادية في أي جزء من الاسم ، باستثناء الحرف الأول.
A'b'c begin' //
- غالبًا ما تستخدم الحالة الأخيرة كتسمية لإصدارات "مختلفة" من القيمة:
let f = x let f' = derivative f let f'' = derivative f'
أو لمتغيرات تحمل نفس الاسم مع الكلمات الرئيسية الموجودة
let if' btf = if b then t else f
يمكنك أيضًا استخدام علامات backticks مزدوجة لأي سلسلة لجعلها معرّفًا صالحًا.
``this is a name`` ``123`` //
الحالات التي قد تحتاج فيها إلى استخدام خدعة خلفية مزدوجة:
- عندما تحتاج إلى استخدام معرف يطابق الكلمة الرئيسية.
let ``begin`` = «begin»
- عندما تحتاج إلى استخدام لغات طبيعية لقواعد العمل ، أو اختبارات الوحدة ، أو الوثائق القابلة للتنفيذ على غرار BBD مثل Cucumber.
let ``is first time customer?`` = true let ``add gift to order`` = () if ``is first time customer?`` then ``add gift to order`` // - let [<Test>] ``When input is 2 then expect square is 4``= // code here // BDD clause let [<Given>] ``I have (.*) N products in my cart`` (n:int) = // code here
على عكس C # ، تتطلب اصطلاح التسمية F # أن تبدأ الدوال والقيم بحرف صغير ، وليس بحرف كبير ( camelCase
، وليس PascalCase
) ، ما لم يتم تصميمها للتفاعل مع لغات .NET الأخرى . ومع ذلك ، تستخدم الأنواع والوحدات الأحرف الكبيرة (في البداية).
موارد إضافية
هناك العديد من البرامج التعليمية لـ F # ، بما في ذلك المواد لأولئك الذين يأتون مع تجربة C # أو Java. قد تكون الروابط التالية مفيدة عندما تتعمق في F #:
كما تم وصف عدة طرق أخرى لبدء تعلم F # .
أخيرًا ، مجتمع F # ودود للغاية للمبتدئين. هناك محادثة نشطة للغاية في Slack ، تدعمها F # Software Foundation ، مع غرف للمبتدئين يمكنك الانضمام إليها بحرية . نوصي بشدة أن تفعل ذلك!
لا تنس زيارة موقع المجتمع الناطق باللغة الروسية F # ! إذا كان لديك أي أسئلة حول تعلم لغة ، يسعدنا مناقشتها في غرف الدردشة:
حول مؤلفي الترجمة
ترجمه kleidemos
تم إجراء تغييرات الترجمة والتحرير من خلال جهود المجتمع الناطق باللغة الروسية لمطوري F # . نشكر أيضًا schvepsss و shwars لإعداد هذه المقالة للنشر.