قانون آف‌ساید (مبتنی بر تورفتگی)

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

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

زبان قانون خارج از سمت نیز به عنوان دارای **تورفتگی قابل توجه** توصیف می شود.

## تعریف
پیتر لندین در مقاله خود در سال 1966 " 700 زبان برنامه نویسی بعدی "، قانون آفساید را اینگونه تعریف کرد: "هر نشانه بدون فاصله در سمت چپ اولین نشانه در خط قبلی به عنوان شروع یک اعلان جدید در نظر گرفته می شود." 

## مثال
در زیر نمونه ای از بلوک های تورفتگی در پایتون آمده است. یک زبان قانون آفساید محبوب. در پایتون، قانون برای تعیین مرزهای عبارات به جای اعلان ها در نظر گرفته می شود.
```python
def is_even(a: int) -> bool:
    if a % 2 == 0:
        print('Even!')
        return True
    print('Odd!')
    return False
```
بدنه تابع از خط 2 شروع می شود زیرا یک سطح (4 فاصله) بیشتر از خط قبلی فرورفته است. بدنه بند `if` از خط 3 شروع می شود زیرا یک سطح اضافی تورفتگی دارد و به خط 4 ختم می شود زیرا خط 5 یک سطح کمتر فرورفته است.

کولون ( `:` ) در انتهای یک خط دستور کنترل، نحو Python است. جنبه ای از قانون آفساید نیست. قاعده را می توان بدون چنین نحو کولون تحقق بخشید.

قانون off-side را می توان در مرحله تحلیل واژگانی پیاده سازی کرد، مانند پایتون ، که در آن افزایش تورفتگی منجر به خروجی lexer توکن `INDENT` و کاهش فرورفتگی در خروجی lexer یک نشانه `DEDENT` .  این نشانه‌ها در زبان‌هایی که از پرانتز برای بلوک‌ها استفاده می‌کنند، مطابق با پرانتز باز `{` و بستن بریس `}` هستند و به این معنی است که عبارت دستور زبان به استفاده از پرانتز یا تورفتگی بستگی ندارد. این مستلزم این است که حالت نگهدارنده lexer، یعنی سطح تورفتگی فعلی، و بنابراین می‌تواند تغییرات در تورفتگی را هنگامی که این تغییر می‌کند، تشخیص دهد، و بنابراین گرامر واژگانی بدون متن نیست: `INDENT` و `DEDENT` به اطلاعات متنی سطح تورفتگی قبلی بستگی دارند.

## جایگزین ها
جایگزین اصلی برای تعیین حدود بلوک‌ها با تورفتگی، که با استفاده گسترده و تأثیر زبان C رایج شده است، نادیده گرفتن کاراکترهای فضای خالی و علامت‌گذاری بلوک‌ها به صراحت با براکت‌های فرفری (یعنی `{` و `}` ) یا برخی از جداکننده‌های دیگر است. در حالی که این امکان آزادی قالب‌بندی بیشتر را فراهم می‌کند – یک توسعه‌دهنده ممکن است تصمیم بگیرد که قطعات کوچکی از کد را مانند عبارت‌های break و continue تورفتگی نکند – کد با تورفتگی نامرتب ممکن است خواننده را به بیراهه بکشاند، مانند اشکال goto fail .

Lisp و سایر زبان‌های مبتنی بر بیان S ، عبارات را از عبارات متمایز نمی‌کنند و پرانتز برای کنترل محدوده تمام عبارات داخل زبان کافی است. مانند زبان‌های براکت فرفری، فضاهای خالی عمدتاً توسط خواننده (یعنی تابع خواندن) نادیده گرفته می‌شود. فضای خالی برای جداسازی توکن ها استفاده می شود.  ساختار صریح کد Lisp به تورفتگی خودکار اجازه می دهد تا یک نشانه بصری برای خوانندگان انسانی تشکیل دهد.

جایگزین دیگر این است که هر بلوک با کلمات کلیدی صریح شروع و پایان یابد. به عنوان مثال، در ALGOL 60 و پاسکال نسل آن، بلوک ها با کلمه کلیدی شروع می `begin` و با کلمه کلیدی `end` پایان می یابند. در برخی از زبان ها (اما نه پاسکال)، این بدان معنی است که خطوط جدید مهم *هستند* (برخلاف زبان‌های پرانتزی فرفری)، اما تورفتگی اینطور نیست. در BASIC و Fortran ، بلوک‌ها با نام بلوک شروع می‌شوند (مانند `IF` ) و با نام بلوک با `END` (مثلاً `END IF` ) پایان می‌یابند. در فرترن ، هر بلوک همچنین می‌تواند نام بلاک منحصربه‌فرد خود را داشته باشد که سطح دیگری از صراحت را به کد طولانی اضافه می‌کند. ALGOL 68 و پوسته Bourne (sh و bash ) مشابه هستند، اما انتهای بلوک معمولاً با نام بلوکی که به عقب نوشته می‌شود داده می‌شود (مثلاً `case` یک دستور switch را شروع می‌کند و تا زمانی که `esac` منطبق می‌شود، به طور مشابه مشروط می‌شود `if` ... `then` ...[ `elif` ...[ `else` ...]] `fi` یا حلقه‌های ''for'' `for` ... `do` ... `od` در ALGOL68 یا `for` ... `do` ... در bash `done` ).

یک نوع جالب از این در Modula-2 رخ می دهد، یک زبان پاسکال مانند که تفاوت بین بلوک های یک و چند خطی را حذف می کند. این اجازه می دهد تا بلوک بازکننده ( `{` یا `BEGIN` ) برای همه به جز بلوک سطح عملکرد، صرفاً به یک نشانه پایان دهنده بلوک ( `}` یا `END` ) رد شود. همچنین آویزان های دیگر را رفع می کند. سفارشی برای این است که نشانه `end` در همان سطح تورفتگی بقیه بلوک قرار می گیرد و ساختار بلوکی بسیار خوانا می دهد.

یکی از مزیت های رویکرد فرترن این است که خوانایی کدهای طولانی، تودرتو یا پیچیده را بهبود می بخشد. گروهی از خروجی ها یا براکت های بسته به تنهایی هیچ نشانه زمینه ای در مورد بسته شدن بلوک ها ارائه نمی دهد، که نیاز به عقب نشینی و بررسی دقیق تر در حین اشکال زدایی دارد. علاوه بر این، زبان‌هایی که پسوندی برای کلیدواژه‌های END مانند اجازه می‌دهند، این نشانه‌ها را بیشتر بهبود می‌بخشند، مانند `continue` در مقابل `continue for x` ، و نشانگر حلقه پایانی که متغیر شاخص `NEXT I` در مقابل `NEXT` را مشخص می‌کند، و حلقه‌هایی با نام منحصر به فرد `CYCLE X1` در مقابل `CYCLE` . با این حال، ویرایشگرهای کد منبع مدرن اغلب نشانگرهای بصری، مانند برجسته کردن نحو ، و ویژگی هایی مانند تا کردن کد را برای کمک به این اشکالات ارائه می دهند.

## بهره وری
در زبان اسکالا ، نسخه های اولیه فقط بریس های مجعد را مجاز می دانستند. Scala 3 گزینه ای برای استفاده از فرورفتگی در ساختار بلوک ها اضافه کرد. طراح مارتین اودرسکی گفت که این مهم‌ترین راهی بود که اسکالا 3 بهره‌وری خود را بهبود بخشید، این که برنامه‌ها را بیش از 10 درصد کوتاه‌تر می‌کند و برنامه‌نویسان را در جریان نگه می‌دارد و استفاده از آن را توصیه می‌کند.

## زبان های برنامه نویسی قابل توجه
زبان های برنامه نویسی قابل توجه با قانون آف ساید:

* ای‌بی‌سی
* آگدا
* بو
* کبرا
* کافی‌اسکریپت
* همگرا شوند
* کاری
* سنجد
* اف شارپ ، در نسخه های اولیه، زمانی که `#light` مشخص شده است. در نسخه‌های بعدی وقتی `#light "off"` نیست 
* گودو
* هسکل,  فقط برای `where`, `let`, `do`, یا `case ...` `of` بندهای زمانی که مهاربندها حذف می شوند
* اطلاع رسانی 7
* آی‌سوییم، زبان انتزاعی که قانون را معرفی کرد
* لایو اسکریپت
* خرچنگ 
* میراندا
* MoonScript  
* Nemerle ، حالت اختیاری
* نیم
* اوکام
* PROMAL
* پایتون
* اسکالا ، حالت اختیاری
* اسکیم، هنگام استفاده از یکی از چندین درخواست Scheme برای پیاده سازی ، که آخرین آنها SRFI 119 است.
* چرخش
* زن
* XL

## سایر فرمت های فایل
زبان غیر برنامه نویسی قابل توجه، فرمت های فایل متنی با تورفتگی قابل توجه:

* جی کد, گویش RepRapFirmware 
* همل
* خط ایجاد شده با زبانه نشان دهنده یک فرمان است
* Pug (سابق Jade)، به مقایسه موتورهای قالب وب مراجعه کنید
* restructuredText 
* ساس
* قلم
* YAML

## منابع

رده:زبان‌های برنامه‌نویسی