إذا كنت تتعلم لغة ما، فمن المحتمل أنك سمعت كلمة "تركيب الجملة" وتتعامل معها طوال الوقت. (خطأ في بناء الجملة).
منذ بضع ليالٍ كنت أفكر في نفسي، ولم أتبع أبدًا نماذج وتقنيات البرمجة على محمل الجد، واليوم بدأت أتعلم من أصغر المواضيع التي أسمعها دائمًا (حتى لو كنت أتذكرها بالفعل). لقد قمت بإنشاء هذا المستودع. مسار التعلم الذي اتخذته مميز (في ملف LEARNING_LIST.md). دعنا نمر، على عكس اللغات الطبيعية، التي نتواصل بها أفكارنا ومشاعرنا، يمكن النظر إلى لغات البرمجة على أنها لغات اصطناعية حددها الرجال والنساء في البداية لغرض التواصل مع أجهزة الكمبيوتر ولكن، والأهم من ذلك، لتوصيل الخوارزميات بين الناس .
على سبيل المثال، تتكون تعريفات اللغة من ثلاثة مكونات:
بناء الجملة : بناء جملة لغة البرمجة هو مجموعة القواعد التي تحدد مجموعات الرموز التي تعتبر برامج منظمة بشكل صحيح في تلك اللغة. يحدد بناء جملة اللغة شكلها السطحي. تعتمد لغات البرمجة المبنية على النصوص على تسلسل الأحرف. تحدد القواعد المعجمية للغة النصية كيفية تقسيم الأحرف إلى رموز مميزة. يشير بناء الجملة إلى الطرق التي يمكن بها دمج الرموز لإنشاء جمل (أو برامج) جيدة التكوين في اللغة. يحدد بناء الجملة العلاقات الرسمية بين مكونات اللغة، وبالتالي يوفر وصفًا بنيويًا لمختلف التعبيرات التي تشكل سلاسل قانونية في اللغة. يتعامل بناء الجملة فقط مع شكل وبنية الرموز في اللغة دون أي اعتبار لمعناها، والنحو هو المفهوم الذي يهتم فقط بما إذا كانت الجملة صالحة لقواعد اللغة أم لا
علم الدلالات : علم الدلالة يدور حول ما إذا كانت الجملة لها معنى صحيح أم لا. تكشف الدلالات معنى السلاسل الصحيحة نحويًا في اللغة. بالنسبة للغات الطبيعية، يعني هذا ربط الجمل والعبارات بالأشياء والأفكار والمشاعر التي نكتسبها من تجاربنا. بالنسبة للغات البرمجة، تصف الدلالات السلوك الذي يتبعه الكمبيوتر عند تنفيذ برنامج باللغة. قد نكشف عن هذا السلوك من خلال وصف العلاقة بين مدخلات ومخرجات البرنامج أو من خلال شرح خطوة بخطوة لكيفية تنفيذ البرنامج على جهاز حقيقي أو مجرد. علم الدلالة هو المصطلح العام لدراسة المعنى. في علوم الكمبيوتر، يسعى موضوع دلالات لغة البرمجة إلى إعطاء معنى رياضي دقيق للبرامج.
في اللغات الطبيعية، يمكن أن تكون الجملة صحيحة نحويًا ولكنها لا معنى لها من الناحية الدلالية. على سبيل المثال الجملة:
"الرجل اشترى اللانهاية من المتجر."
هذا صحيح نحويًا ولكن ليس له أي معنى في العالم الحقيقي. وبالمثل، في لغات البرمجة، يمكن أن تكون العبارة صحيحة من الناحية النحوية ولكنها غير صحيحة من الناحية الدلالية لأنها تنتهك قواعد اللغة أو المعنى المقصود منها.
في دلالات المستوى المنخفض للبرمجة، نحن مهتمون بما إذا كانت العبارة التي تحتوي على بناء جملة صحيح منطقية أيضًا وفقًا لنظام كتابة اللغة أو القواعد الأخرى. على الرغم من أن بناء الجملة قد يكون صالحًا، إلا أن المعنى الدلالي للعملية قد يكون غير صالح. يساعد نظام الكتابة في اللغات المكتوبة بشكل ثابت، مثل Java، على فرض هذه القواعد قبل وقت التشغيل، لكن اللغات المكتوبة ديناميكيًا مثل JavaScript لا تفرض دائمًا هذه القواعد حتى وقت التشغيل.
في JavaScript، التي يتم كتابتها بشكل فضفاض، قد لا تتمتع بالحماية التي تأتي مع نظام كتابة أكثر صرامة، وستسمح اللغة بعمليات معينة لا معنى لها بطريقة ذات معنى لغويًا. خذ بعين الاعتبار كود JavaScript التالي:
let name = "Alice"; name = 42; // No error, but semantically this doesn't make sense.
هنا، بناء الجملة صالح تمامًا، وتسمح JavaScript بالمهمة، لكنه غريب من الناحية الدلالية. أنت تحاول تعيين رقم (42) لمتغير يُفترض أنه مخصص للاحتفاظ بسلسلة (اسم). لا يوجد تدقيق في النوع في JavaScript لمنعك من ارتكاب هذا الخطأ، ولكنه خطأ دلالي منخفض المستوى لأنه لا يتوافق مع نية المطور.
إذا قمنا بتنفيذها. يتم تنفيذه. بدون أي خطأ!
في اللغات الأكثر صرامة، مثل TypeScript أو Java، قد يؤدي ذلك إلى حدوث خطأ في النوع على الفور أثناء التجميع.
يقدم TypeScript، وهو مجموعة شاملة من JavaScript، فحصًا للنوع لمنع هذه المشكلات الدلالية ذات المستوى المنخفض:
let name: string = "Alice"; name = 42; // Error: Type 'number' is not assignable to type 'string'.
في TypeScript، يكتشف المترجم الخطأ الدلالي لأن 42 رقم ولا يمكن تعيينه لمتغير تم تعريفه كسلسلة. هذا التطبيق للأنواع يحمي المطور من الأخطاء غير المقصودة.
في JavaScript، لتجنب هذه المشكلات الدلالية ذات المستوى المنخفض، غالبًا ما يستخدم المطورون عمليات التحقق من وقت التشغيل:
let name = "Alice"; if (typeof name !== "string") { throw new Error("Expected a string!"); }
على الرغم من أن JavaScript لا تفرض الأنواع، إلا أن إضافة عمليات فحص يدوية يمكن أن تساعد في تجنب الأخطاء حيث تؤدي الأنواع غير الصحيحة إلى حدوث مشكلات في البرنامج.
على مستوى أعلى، يهتم علم الدلالات بما يفترض أن يحققه برنامجك. لا يتعلق الأمر فقط بما إذا كان البرنامج يحتوي على بناء جملة صالح أو ما إذا كانت الأنواع تتم محاذاتها بشكل صحيح، بل يتعلق بما إذا كان البرنامج يتصرف بالطريقة التي أرادها المطور، أو يحل المشكلة التي تم تصميمه لمعالجتها.
على سبيل المثال، لنفترض أنك تقوم ببناء نظام بسيط لتداول الأسهم. تتعلق الدلالات عالية المستوى للتعليمات البرمجية الخاصة بك بالتأكد من أن النظام يتداول الأسهم بالطريقة الصحيحة، وبمنطق العمل الصحيح. حتى لو لم تنتج التعليمات البرمجية أخطاء في الكتابة أو أخطاء في بناء الجملة، فمن الممكن أن تفشل في تلبية الوظيفة المقصودة.
دعونا نلقي نظرة على مثال جافا سكريبت لدلالات عالية المستوى باستخدام سيناريو مبسط لتداول الأسهم:
let openTrade = { symbol: "EURUSD", direction: "buy", profit: 100 }; function closeTrade(trade) { if (trade.profit >= 50) { console.log(`Closing trade for ${trade.symbol} with profit of ${trade.profit}`); } else { console.log(`Trade for ${trade.symbol} is not ready to close.`); } } // Check if a trade is open for EURUSD and close it if the profit target is reached. closeTrade(openTrade);
التركيب صحيح، والبرنامج يعمل بدون أخطاء. ومع ذلك، تخيل أننا الآن أدخلنا خطأ على مستوى أعلى، مثل الدخول بطريق الخطأ في صفقتين لنفس الرمز، وهو ما ينتهك قواعد عمل النظام.
let openTrades = [ { symbol: "EURUSD", direction: "buy", profit: 100 }, { symbol: "EURUSD", direction: "sell", profit: 20 } ]; // Check all trades and close any that hit their profit target. openTrades.forEach(trade => closeTrade(trade));
هنا، تتم معالجة كلا الصفقتين بشكل مستقل، لكن النظام ينتهي بصفقتين على نفس الرمز، واحدة في اتجاه الشراء والأخرى في اتجاه البيع. وهذا يكسر قاعدة العمل رفيعة المستوى التي تنص على أنه يجب أن يكون لدينا تداول واحد مفتوح فقط لكل رمز في أي وقت.
على الرغم من تنفيذ التعليمات البرمجية بدون أخطاء في بناء الجملة أو الكتابة، إلا أنها غير صحيحة لغويًا على مستوى عالٍ. يجب أن يضمن منطق النظام إمكانية تفعيل تداول واحد فقط لكل رمز في المرة الواحدة. من المحتمل أن يؤدي هذا الخطأ إلى عواقب غير مقصودة في نظام التداول الحقيقي، مثل الخسارة المالية.
لإصلاح هذه المشكلة الدلالية عالية المستوى، ستحتاج إلى ضبط المنطق لضمان فتح صفقة واحدة فقط لرمز معين:
let openTrades = [ { symbol: "EURUSD", direction: "buy", profit: 100 } ]; function openNewTrade(newTrade) { // Ensure no other trades are open for the same symbol. const existingTrade = openTrades.find(trade => trade.symbol === newTrade.symbol); if (!existingTrade) { openTrades.push(newTrade); console.log(`Opened new trade for ${newTrade.symbol}`); } else { console.log(`Cannot open a new trade for ${newTrade.symbol}, trade already exists.`); } } openNewTrade({ symbol: "EURUSD", direction: "sell", profit: 0 });
هنا، يضمن المنطق أنه لا يمكن فتح تداول جديد إذا كان هناك بالفعل تداول نشط لنفس الرمز. هذا هو إصلاح دلالي عالي المستوى لأنه يعالج منطق العمل الأساسي الذي من المفترض أن يتبعه البرنامج، بدلاً من مشكلة بناء الجملة أو الكتابة.
كانت هذه مجرد معلومات أساسية عن كل منها. لمزيد من المعلومات يمكنك قراءة هذه العناصر:
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3