برنامه نویسی

Syntax و Semantics چیست؟

Summarize this content to 400 words in Persian Lang
اگر در حال یادگیری یک زبان هستید، احتمالاً کلمه “syntax” را شنیده اید و همیشه با آن سر و کار دارید. (خطای نحوی لعنتی).

چند شب پیش بود که با خودم فکر می کردم، هرگز پارادایم ها و تکنیک های برنامه نویسی را به طور جدی دنبال نکردم و امروز شروع کردم به یادگیری از کوچکترین موضوعاتی که همیشه می شنوم (حتی اگر قبلاً یادم باشد). من این مخزن را ایجاد کردم. مسیر یادگیری من مشخص است (در فایل LEARNING_LIST.md). بگذریم، برخلاف زبان‌های طبیعی که افکار و احساسات خود را با آن‌ها ارتباط برقرار می‌کنیم، زبان‌های برنامه‌نویسی را می‌توان به‌عنوان زبان‌های مصنوعی تعریف کرد که توسط مردان و زنان در ابتدا به منظور برقراری ارتباط با رایانه‌ها، اما مهم‌تر از همه، برای برقراری ارتباط الگوریتم‌ها بین افراد تعریف شده است. .به عنوان مثال، تعاریف زبان از سه جزء تشکیل شده است:

نحو: سینتکس یک زبان برنامه نویسی مجموعه قوانینی است که ترکیبی از نمادها را تعریف می کند که به عنوان برنامه هایی با ساختار صحیح در آن زبان در نظر گرفته می شوند. نحو یک زبان شکل سطحی آن را مشخص می کند. زبان های برنامه نویسی مبتنی بر متن بر اساس دنباله ای از کاراکترها هستند. گرامر واژگانی یک زبان متنی مشخص می‌کند که چگونه کاراکترها باید به نشانه‌ها تقسیم شوند. نحو به روش‌هایی اشاره دارد که ممکن است نمادها برای ایجاد جملات (یا برنامه‌های) خوب در زبان ترکیب شوند. نحو روابط رسمی بین اجزای تشکیل دهنده یک زبان را تعریف می کند و بدین وسیله توصیفی ساختاری از عبارات مختلفی که رشته های قانونی در زبان را تشکیل می دهند ارائه می دهد. نحو صرفاً به شکل و ساختار نمادها در یک زبان می پردازد بدون اینکه به معنای آنها توجه شود، نحو مفهومی است که فقط به خود مربوط می شود که آیا جمله برای دستور زبان آن زبان معتبر است یا نه.
معناشناسی: معناشناسی به معنای معتبر بودن یا نبودن جمله است. معناشناسی معنای رشته های معتبر نحوی را در یک زبان آشکار می کند. برای زبان های طبیعی، این به معنای همبستگی جملات و عبارات با اشیاء، افکار و احساسات تجربیات ماست. برای زبان‌های برنامه‌نویسی، معناشناسی رفتاری را توصیف می‌کند که کامپیوتر هنگام اجرای یک برنامه در زبان از آن پیروی می‌کند. ما ممکن است این رفتار را با توصیف رابطه بین ورودی و خروجی یک برنامه یا با توضیح گام به گام نحوه اجرای یک برنامه بر روی یک ماشین واقعی یا انتزاعی فاش کنیم. معناشناسی اصطلاح کلی برای مطالعه معناست. در علوم کامپیوتر موضوع معناشناسی زبان برنامه نویسی به دنبال این است که معنای ریاضی دقیقی به برنامه ها بدهد.

معناشناسی سطح پایین:

در زبان‌های طبیعی، یک جمله می‌تواند از نظر گرامری درست باشد، اما از نظر معنایی بی‌معنی باشد. مثلاً جمله:

“مرد بی نهایت را از فروشگاه خرید.”

این از نظر گرامری درست است اما در دنیای واقعی معنی ندارد. به طور مشابه، در زبان‌های برنامه‌نویسی، یک عبارت می‌تواند از نظر نحوی درست باشد، اما از نظر معنایی نادرست باشد، زیرا قوانین زبان یا معنای مورد نظر آن را نقض می‌کند.

در معناشناسی سطح پایین در مورد برنامه نویسی، ما نگران این هستیم که آیا عبارتی که نحو درستی داشته باشد با توجه به سیستم نوع زبان یا قوانین دیگر نیز معنا دارد یا خیر. حتی اگر نحو ممکن است معتبر باشد، معنای معنایی عملیات ممکن است نامعتبر باشد. سیستم تایپ در زبان‌های دارای تایپ استاتیک، مانند جاوا، به اجرای این قوانین قبل از زمان اجرا کمک می‌کند، اما زبان‌هایی که به‌صورت پویا تایپ می‌شوند مانند جاوا اسکریپت همیشه این قوانین را تا زمان اجرا اجرا نمی‌کنند.

مثال در جاوا اسکریپت:

در جاوا اسکریپت که به صورت آزاد تایپ می شود، ممکن است محافظتی که با یک سیستم نوع سخت گیرانه ارائه می شود را نداشته باشید، و این زبان عملیات خاصی را که از لحاظ معنایی معنی دار نیستند اجازه می دهد. کد جاوا اسکریپت زیر را در نظر بگیرید:

let name = “Alice”;
name = 42; // No error, but semantically this doesn’t make sense.

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا، نحو کاملا معتبر است و جاوا اسکریپت اجازه انتساب را می دهد، اما از نظر معنایی عجیب است. شما در حال تلاش برای اختصاص یک شماره هستید (42) به متغیری که احتمالاً برای نگه داشتن یک رشته (name). هیچ نوع بررسی در جاوا اسکریپت وجود ندارد که شما را از انجام این اشتباه باز دارد، اما این یک اشتباه است خطای معنایی سطح پایین زیرا با هدف توسعه دهنده مغایرت دارد. اگر آن را اجرا کنیم. اجرا می شود. بدون هیچ خطایی!

در زبان‌های سخت‌گیرانه‌تر، مانند TypeScript یا Java، این امر بلافاصله در حین کامپایل کردن، یک خطای نوع ایجاد می‌کند.

مثال در TypeScript:

TypeScript، ابر مجموعه ای از جاوا اسکریپت، بررسی نوع را برای جلوگیری از این مسائل معنایی سطح پایین معرفی می کند:

let name: string = “Alice”;
name = 42; // Error: Type ‘number’ is not assignable to type ‘string’.

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در TypeScript، کامپایلر خطای معنایی را تشخیص می دهد زیرا 42 یک عدد است و نمی توان آن را به متغیری که به عنوان رشته اعلام شده است نسبت داد. این اعمال انواع، توسعه دهنده را از اشتباهات ناخواسته محافظت می کند.

در جاوا اسکریپت، برای جلوگیری از این مسائل معنایی سطح پایین، توسعه دهندگان اغلب از بررسی های زمان اجرا استفاده می کنند:

let name = “Alice”;

if (typeof name !== “string”) {
throw new Error(“Expected a string!”);
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

حتی اگر جاوا اسکریپت انواع را اعمال نمی کند، افزودن بررسی های دستی می تواند به جلوگیری از خطاهایی که در آن انواع نادرست منجر به مشکلاتی در برنامه می شود، کمک کند.

معناشناسی سطح بالا:

در سطح بالاتر، معناشناسی به آنچه برنامه شما قرار است به آن برسد مربوط می شود. این فقط در مورد این نیست که آیا برنامه دارای نحو معتبر است یا اینکه انواع به درستی تراز می شوند، بلکه در مورد این است که آیا برنامه به روشی که توسعه دهنده در نظر دارد رفتار می کند یا مشکلی را که برای رفع آن طراحی شده است را حل می کند.

به عنوان مثال، فرض کنید در حال ساختن یک سیستم معاملاتی سهام ساده هستید. معنای سطح بالای کد شما در مورد این است که مطمئن شوید سیستم سهام را به روش صحیح و با منطق تجاری صحیح معامله می کند. حتی اگر کد خطاهای نوع یا نحوی ایجاد نکند، باز هم ممکن است عملکرد مورد نظر را برآورده نکند.

مثال در جاوا اسکریپت:

بیایید به یک مثال جاوا اسکریپت از معناشناسی سطح بالا با استفاده از یک سناریوی معاملات سهام ساده نگاه کنیم:

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 });

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا، منطق تضمین می کند که اگر قبلاً یک معامله فعال برای همان نماد وجود داشته باشد، نمی توان یک معامله جدید باز کرد. این یک است رفع معنایی سطح بالا زیرا به منطق اصلی کسب و کار می پردازد که برنامه باید از آن پیروی کند، نه یک مشکل نحوی یا نوع.

عمل شناسی: پراگماتیک به آن جنبه‌هایی از زبان اشاره می‌کند که کاربران زبان را درگیر می‌کند، یعنی پدیده‌های روان‌شناختی و جامعه‌شناختی مانند سودمندی، دامنه کاربرد و تأثیرات بر کاربران. برای زبان های برنامه نویسی، عمل شناسی شامل موضوعاتی مانند سهولت اجرا، کارایی در کاربرد و روش برنامه نویسی است.

این فقط اطلاعات اولیه در مورد هر یک بود. برای اطلاعات بیشتر می توانید این موارد را مطالعه کنید:

اگر در حال یادگیری یک زبان هستید، احتمالاً کلمه “syntax” را شنیده اید و همیشه با آن سر و کار دارید. (خطای نحوی لعنتی).

چند شب پیش بود که با خودم فکر می کردم، هرگز پارادایم ها و تکنیک های برنامه نویسی را به طور جدی دنبال نکردم و امروز شروع کردم به یادگیری از کوچکترین موضوعاتی که همیشه می شنوم (حتی اگر قبلاً یادم باشد). من این مخزن را ایجاد کردم. مسیر یادگیری من مشخص است (در فایل LEARNING_LIST.md). بگذریم، برخلاف زبان‌های طبیعی که افکار و احساسات خود را با آن‌ها ارتباط برقرار می‌کنیم، زبان‌های برنامه‌نویسی را می‌توان به‌عنوان زبان‌های مصنوعی تعریف کرد که توسط مردان و زنان در ابتدا به منظور برقراری ارتباط با رایانه‌ها، اما مهم‌تر از همه، برای برقراری ارتباط الگوریتم‌ها بین افراد تعریف شده است. .
به عنوان مثال، تعاریف زبان از سه جزء تشکیل شده است:

  • نحو: سینتکس یک زبان برنامه نویسی مجموعه قوانینی است که ترکیبی از نمادها را تعریف می کند که به عنوان برنامه هایی با ساختار صحیح در آن زبان در نظر گرفته می شوند. نحو یک زبان شکل سطحی آن را مشخص می کند. زبان های برنامه نویسی مبتنی بر متن بر اساس دنباله ای از کاراکترها هستند. گرامر واژگانی یک زبان متنی مشخص می‌کند که چگونه کاراکترها باید به نشانه‌ها تقسیم شوند. نحو به روش‌هایی اشاره دارد که ممکن است نمادها برای ایجاد جملات (یا برنامه‌های) خوب در زبان ترکیب شوند. نحو روابط رسمی بین اجزای تشکیل دهنده یک زبان را تعریف می کند و بدین وسیله توصیفی ساختاری از عبارات مختلفی که رشته های قانونی در زبان را تشکیل می دهند ارائه می دهد. نحو صرفاً به شکل و ساختار نمادها در یک زبان می پردازد بدون اینکه به معنای آنها توجه شود، نحو مفهومی است که فقط به خود مربوط می شود که آیا جمله برای دستور زبان آن زبان معتبر است یا نه.

  • معناشناسی: معناشناسی به معنای معتبر بودن یا نبودن جمله است. معناشناسی معنای رشته های معتبر نحوی را در یک زبان آشکار می کند. برای زبان های طبیعی، این به معنای همبستگی جملات و عبارات با اشیاء، افکار و احساسات تجربیات ماست. برای زبان‌های برنامه‌نویسی، معناشناسی رفتاری را توصیف می‌کند که کامپیوتر هنگام اجرای یک برنامه در زبان از آن پیروی می‌کند. ما ممکن است این رفتار را با توصیف رابطه بین ورودی و خروجی یک برنامه یا با توضیح گام به گام نحوه اجرای یک برنامه بر روی یک ماشین واقعی یا انتزاعی فاش کنیم. معناشناسی اصطلاح کلی برای مطالعه معناست. در علوم کامپیوتر موضوع معناشناسی زبان برنامه نویسی به دنبال این است که معنای ریاضی دقیقی به برنامه ها بدهد.

معناشناسی سطح پایین:

در زبان‌های طبیعی، یک جمله می‌تواند از نظر گرامری درست باشد، اما از نظر معنایی بی‌معنی باشد. مثلاً جمله:

“مرد بی نهایت را از فروشگاه خرید.”

این از نظر گرامری درست است اما در دنیای واقعی معنی ندارد. به طور مشابه، در زبان‌های برنامه‌نویسی، یک عبارت می‌تواند از نظر نحوی درست باشد، اما از نظر معنایی نادرست باشد، زیرا قوانین زبان یا معنای مورد نظر آن را نقض می‌کند.

در معناشناسی سطح پایین در مورد برنامه نویسی، ما نگران این هستیم که آیا عبارتی که نحو درستی داشته باشد با توجه به سیستم نوع زبان یا قوانین دیگر نیز معنا دارد یا خیر. حتی اگر نحو ممکن است معتبر باشد، معنای معنایی عملیات ممکن است نامعتبر باشد. سیستم تایپ در زبان‌های دارای تایپ استاتیک، مانند جاوا، به اجرای این قوانین قبل از زمان اجرا کمک می‌کند، اما زبان‌هایی که به‌صورت پویا تایپ می‌شوند مانند جاوا اسکریپت همیشه این قوانین را تا زمان اجرا اجرا نمی‌کنند.

مثال در جاوا اسکریپت:

در جاوا اسکریپت که به صورت آزاد تایپ می شود، ممکن است محافظتی که با یک سیستم نوع سخت گیرانه ارائه می شود را نداشته باشید، و این زبان عملیات خاصی را که از لحاظ معنایی معنی دار نیستند اجازه می دهد. کد جاوا اسکریپت زیر را در نظر بگیرید:

let name = "Alice";
name = 42;  // No error, but semantically this doesn't make sense.
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا، نحو کاملا معتبر است و جاوا اسکریپت اجازه انتساب را می دهد، اما از نظر معنایی عجیب است. شما در حال تلاش برای اختصاص یک شماره هستید (42) به متغیری که احتمالاً برای نگه داشتن یک رشته (name). هیچ نوع بررسی در جاوا اسکریپت وجود ندارد که شما را از انجام این اشتباه باز دارد، اما این یک اشتباه است خطای معنایی سطح پایین زیرا با هدف توسعه دهنده مغایرت دارد.
اگر آن را اجرا کنیم. اجرا می شود. بدون هیچ خطایی!

در زبان‌های سخت‌گیرانه‌تر، مانند TypeScript یا Java، این امر بلافاصله در حین کامپایل کردن، یک خطای نوع ایجاد می‌کند.

مثال در TypeScript:

TypeScript، ابر مجموعه ای از جاوا اسکریپت، بررسی نوع را برای جلوگیری از این مسائل معنایی سطح پایین معرفی می کند:

let name: string = "Alice";
name = 42;  // Error: Type 'number' is not assignable to type 'string'.
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در TypeScript، کامپایلر خطای معنایی را تشخیص می دهد زیرا 42 یک عدد است و نمی توان آن را به متغیری که به عنوان رشته اعلام شده است نسبت داد. این اعمال انواع، توسعه دهنده را از اشتباهات ناخواسته محافظت می کند.

در جاوا اسکریپت، برای جلوگیری از این مسائل معنایی سطح پایین، توسعه دهندگان اغلب از بررسی های زمان اجرا استفاده می کنند:

let name = "Alice";

if (typeof name !== "string") {
    throw new Error("Expected a string!");
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

حتی اگر جاوا اسکریپت انواع را اعمال نمی کند، افزودن بررسی های دستی می تواند به جلوگیری از خطاهایی که در آن انواع نادرست منجر به مشکلاتی در برنامه می شود، کمک کند.


معناشناسی سطح بالا:

در سطح بالاتر، معناشناسی به آنچه برنامه شما قرار است به آن برسد مربوط می شود. این فقط در مورد این نیست که آیا برنامه دارای نحو معتبر است یا اینکه انواع به درستی تراز می شوند، بلکه در مورد این است که آیا برنامه به روشی که توسعه دهنده در نظر دارد رفتار می کند یا مشکلی را که برای رفع آن طراحی شده است را حل می کند.

به عنوان مثال، فرض کنید در حال ساختن یک سیستم معاملاتی سهام ساده هستید. معنای سطح بالای کد شما در مورد این است که مطمئن شوید سیستم سهام را به روش صحیح و با منطق تجاری صحیح معامله می کند. حتی اگر کد خطاهای نوع یا نحوی ایجاد نکند، باز هم ممکن است عملکرد مورد نظر را برآورده نکند.

مثال در جاوا اسکریپت:

بیایید به یک مثال جاوا اسکریپت از معناشناسی سطح بالا با استفاده از یک سناریوی معاملات سهام ساده نگاه کنیم:

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 });
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در اینجا، منطق تضمین می کند که اگر قبلاً یک معامله فعال برای همان نماد وجود داشته باشد، نمی توان یک معامله جدید باز کرد. این یک است رفع معنایی سطح بالا زیرا به منطق اصلی کسب و کار می پردازد که برنامه باید از آن پیروی کند، نه یک مشکل نحوی یا نوع.

  • عمل شناسی: پراگماتیک به آن جنبه‌هایی از زبان اشاره می‌کند که کاربران زبان را درگیر می‌کند، یعنی پدیده‌های روان‌شناختی و جامعه‌شناختی مانند سودمندی، دامنه کاربرد و تأثیرات بر کاربران. برای زبان های برنامه نویسی، عمل شناسی شامل موضوعاتی مانند سهولت اجرا، کارایی در کاربرد و روش برنامه نویسی است.

این فقط اطلاعات اولیه در مورد هر یک بود. برای اطلاعات بیشتر می توانید این موارد را مطالعه کنید:

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا