ایپیال
APL مخفف عبارت «یک زبان برنامهنویسی» است. این زبان در بسیاری از زمینهها (ریاضیات، علوم، مهندسی، طراحی کامپیوتر، روباتیک و ...) کاربرد دارد. APL زبانی بسیار قوی و مختصر و مفید است که معمولاً در محیطهای اینتراکتیو استفاده میشود. در آغاز این زبان در زمینه دیگری تولید شد، ساختن یک نمادگذاری ریاضی برای توصیف کامپیوتر که بتوان آن را به وسیله یک کامیپوتر تفسیر کرد. یادگیری این زبان ساده است اما خوانایی کمی دارد و برای درک بعضی از برنامههایی که به زبان APL نوشته شدهاند، زمان زیادی لازم است. زبانهای کمی وجود دارند که عملیات آرایهای آنها به وسعت APL باشد.
پارادایم برنامهنویسی | array، برنامهنویسی تابعی، برنامهنویسی ساختیافته، برنامهنویسی پودمانی |
---|---|
طراحی شده توسط | کنت ای آیورسن |
توسعهدهنده | Kenneth E. Iverson |
ظهوریافته در | 1964 |
dynamic | |
پیادهسازیهای بزرگ | |
| |
گویش | |
| |
متأثر از | |
mathematical notation | |
تأثیر گذاشته بر | |
تاریخچه
APL یک زبان برنامهنویسی است که بر مبنای نمادگذاری که Kenneth E. Iverson در سال ۱۹۵۷ در دانشگاه هاروارد ابداع کرد، ایجاد شدهاست. هدف اولیه تولید این زبان، ایجاد یک زبان مشترک برای تدریس و تحلیل برنامههای کامپیوتری بودهاست. Iverson جایزهٔ تورینگ را به خاطر این کارش در سال ۱۹۷۹ برد.
دید کلی
APL در محیطی به نام workspace کار میکند. کاربر میتواند در این workspace برنامه یا داده تعریف کند. به عبارت دیگر دادهها خارج از برنامهها نیز وجود دارند و کاربر میتواند بدون تعریف کردن برنامه با داده کار کند. برای مثال عبارت زیر بردار ۷ ۶ ۵ ۴ را به N نسبت میدهد:
و عبارت زیر به تمام مقادیر ۴ را اضافه میکند (حاصل ۱۱ ۱۰ ۹ ۸) و آنها را چاپ میکند (حاصل عبارت به هیچ متغیری نسبت داده نشدهاست)
و عبارت زیر مجموع N، یعنی ۲۲ را چاپ میکند:
کاربر میتواند workspace را با تمام مقادیر، برنامهها و حالت اجرا ذخیره کند.
APL معروف است به استفاده از علائم غیر اسکی که به نمادگذاری سنتی حساب و جبر اضافه شدهاند. استفاده از نامهای تککاراکتری برای توابعی که روی بردارها عمل میکنند باعث میشود که با APL بتوان الگوریتمهایی که با دادهها سر و کار دارند را به صورت فشرده تعریف کرد، برای مثال بازی زندگی کانوی را میتوان با یک خط کد پیادهسازی کرد. تقریباً در تمام نسخههای APL از لحاظ تئوری میتوان هر تابع محاسباتی را در یک عبارت بیان کرد.
ایپیال به خاطر کاراکترهای غیراستاندارد و پیچیدهاش گاهی یک «زبان فقط نوشتنی» نامیده میشود و خواندن یک برنامهٔ APL بیشتر شبیه به خواندن یکی از کتیبههای مصر باستان است. بسیاری از برنامهنویسان از صفحهکلیدهای مخصوص که روی آن کاراکترهای APL چاپ شده برای نوشتن کدهای APL استفاده میکنند. البته روشهایی برای نوشتن کد APL با استفاده از کاراکترهای اسکی وجود دارد، اما در عمل از آنها استفاده نمیشود. در اغلب پیادهسازیها از صفحهکلیدهای استاندارد با نگاشت مخصوص یا از ویرایشگرهای مخصوص کاراکترهای غیر اسکی استفاده میشود. در گذشته قلمهایی که کد APL با آن نوشته میشد، حروف را به صورت بزرگ و ایتالیک و اعداد و نشانهها را به صورت عادی نمایش میداد. اما امروزه از قلمهای مختلفی استفاده میشود.
مدافعان APL ادعا میکنند که مثالهایی که اغلب فقطنوشتنی خوانده میشوند، مثالهایی هستند که در هر زبانی ممکن است رخ دهند. آنها همچنین ادعا میکنند که با استفاده از این زبان بازدهی آنها بسیار بالاتر از زمانی است که از زبانهای عادی استفاده میکنند و تولید یک نرمافزار احتیاج به زمان و برنامهنویسان کمتری دارد. APL به علت مختصر و مفید بودنش، سختی تولید نرمافزارهای بزرگ که پیچیدگی آنها به علت تعداد خطوط زیاد کد بالا میرود را به شدت کم میکند. و سرعت تولید نرمافزار نیز با استفاده از APL بسیار بالا میرود. بسیاری از طرفداران آن برنامهنویسی با زبانهای استاندارد نظیر کوبول و جاوا را کسلکننده میدانند.
Iverson بعدها زبان J Programming Language را ابداع کرد که در آن فقط از کاراکترهای اسکی استفاده میشد.
مثالها
عبارت زیر کلماتی که در آرایهٔ X ذخیره شدهاند را به ترتیب طول آنها مرتب میکند:
X[⍋X+.≠' ';]
تابع زیر (life) یک آرایهٔ بولین دریافت میکند و نسل بعدی را بر اساس بازی زندگی کانوی محاسبه میکند:
در مثال زیر، ابتدا یک تکه کد HTML به متغیر txt، منتسب میشود، سپس یک عبارت APL تمام تگهای HTML را حذف میکند و فقط متنی که در خط آخر آمده را باز میگرداند:
عبارت زیر تمام اعداد اول از ۱ تا R را میابد. زمان و حافظه اجرا از (O(R است:
(~R∊R∘.×R)/R←1↓⍳R
این مثال را از راست به چپ بررسی میکنیم:
- ιR یک بردار از اعداد صحیح از یک تا R تولید میکند.
- تابع ↓ چند عنصر از ابتدای بردار را حذف میکند. بنابراین
1↓ιR
برابر است با 6 5 4 3 2. - بردار حاصل با استفاده از علامت ← به R منتسب میشود.
- ضرب خارجی R در R با استفاده از تابع ×.° محاسبه میشود.
- در مرحله بعد، یک بردار با طول برابر با R ساخته میشود که در آن به ازای هر عددی که در ضرب خارجی وجود دارد، 1 گذاشته میشود، که حاصل برابر است با 1 0 1 0 0.
- تابع ~ بردار را از لحاظ منطقی معکوس میکند (صفرها را به یک و یکها را به صفر تبدیل میکند)
- تابع / اعضایی از R را که عنصر متناظر آنها 1 است را انتخاب میکند.
محاسبات
APL همیشه سرعت بسیار بالایی در انجام عملیات، مخصوصاً عملیات بر روی آرایهها داشتهاست. برای مثال یک ضرب ماتریسی بسیار بزرگ روی ماشینهای بسیار ضعیفتر از ماشینهای امروزی تنها چند ثانیه طول میکشیده است. وجود این مزایا دلایل تکنیکال و اقتصادی داشتهاست:
- مفسرهای تجاری موجود، کتابخانههای جبر خطی بسیار خوبی داشتند.
- سربار تفسیر برای هر آرایه وجود دارد نه برای هر عنصر.
- آیبیام در تعدادی از مینفریمهای IBM/370 خود میکروکدهایی برای APL قرار داد.
مقالهٔ معروف «یک ماشین APL» (به قلم فیل آبرامز) استفاده گسترده APL از محاسبات تنبل را توضیح داد که در این روش محاسبات تا زمانی که واقعاً به نتیجهٔ آنها نیاز باشد به تعویق میافتند.
مفسرها
APL2000 یک مفسر پیشرفته برای APL تولید کرده که تحت لینوکس، یونیکس و ویندوز اجرا میشود. این مفسر استفاده از dllها را پشتیبانی میکند و یک فایل سیستم پیشرفته برای APL دارد. این محصول APL2000 ادامه تلاشهای موفق STSC در تولید APL*Plus/PC و APL*Plus/386 است.
Dyalog APL یک مفسر پیشرفته دیگر است که تحت لینوکس، یونیکس و ویندوز اجرا میشود. Dyalog یک توسعه بر زبان APL است که قابلیتهای شیگرایی جدید و namespace به آن اضافه کردهاست. ضمناً Dyalog در ویندوز قابلیت ارتباط با Microsoft.Net و Microsoft Visual Studio را دارد. IBM یک نسخه از APL2 را برای IBM AIX، لینوکس، سولاریس و ویندوز ارائه کردهاست. این محصول نسل بعدی APL2 است که برای mainframesها مورد استفاده قرار میگرفت. APL2 مطرحترین سیستم APL بودهاست.
MicroAPL نیز یک مفسر برای سیستمهای ۶۴بیتی به نام APLX طراحی کرده که تحت لینوکس، ویندوز و Mac OS قابل اجراست.
کامپایل
عمدتاً برنامههای APL تفسیر میشوند و کمتر کامپایل میشوند. در واقع اکثر کامپایلرهای APL، متن برنامهٔ APL را به زبانهای سطح پایینتر مانند C ترجمه میکنند. با اینکه توسعه زبان APL خصوصاً اضافه شدن آرایههای تودرتو، کامپایل کردن APL را دشوار ساخته، ایدهٔ کامپایل کردن APL هنوز در حال بررسی است.
اصطلاحات
در APL تفاوت بین توابع و عملگرها واضح است. توابع ورودی میگیرند (متغیر یا ثابت یا عبارت) و حاصل را در خروجی بازمیگردانند. عملگرها توابع را میگیرند و تغییریافتهٔ آنها را بازمیگردانند. برای مثال تابع «sum» با اعمال عملگر «reduction» بر تابع «addition» بهدست میآید.
همچنین نمادهای APL primitive نامیده میشوند. اغلب primitiveها یا تابع هستند یا عملگر. فرایند نوشتن کد APL بیشتر شامل نوشتن توابع غیر primitive است. البته بعضی از primitiveها نه عملگر هستند و نه تابع. برای مثال نماد انتساب.
شیءگرایی
قابلیت شیءگرایی در Dyalog APL و APLX به زبان APL اضافه شدهاست. قابلیتهایی که در این نسخهها پشتیبانی میشود، مشابه قابلیتهای زبانهای شیءگرای معمول (مانند ++C و جاوا) است. اما خصوصیات خاص APL در برنامهنویسی آرایهای، به کلاسها و اشیا نیز تسری داده شدهاند. هر دو نسخه، اجازه استفاده از کلاسها NET. را علاوه بر کلاسها خود APL میدهند، اما تفاوتهایی نیز دارند:
- Dyalog APL قابلیتهای بیشتری نظیر وراثت چندگانه دارد.
- APLX امکان استفاده از کلاسهای جاوا و روبی را نیز میدهد.
زمانی که شما یک شیء جدید تولید میکنید، چیزی که بازگردانده میشود، تنها reference آن شیء است نه خود شیء. همچنین زمانی که شما یک شیء را به یک کلاس منتصب میکنید، تنها reference کپی میشود و اشیا در جدولی توسط خود APL مدیریت میشوند. در ضمن شما میتوانید از کلاسها نیز reference داشته باشید. با این کار میتوانید توابع عمومی را روی کلاسها بدون توجه به عملکرد کلاس، اعمال کنید.
کاراکترها و طرحبندی صفحهکلید
با توجه به اینکه در برنامههای APL کاراکترهای غیر اسکی زیادی استفاده میشوند، طرحبندی صفحهکلید برای نوشتن سریعتر برنامههای APL اهمیت زیادی دارد، یکی از طرحبندیهای رایج به شکل زیر است:
تمام کاراکترهای APL در یونیکد هستند. این کاراکترها را در زیر میبینید:
' ( ) + , - . / : ; < = > ? [ ] \ _ ¨ ¯ × ÷ ← ↑ → ↓ ∆ ∇ ∘ ∣ ∧ ∨ ∩ ∪ ∼ ≠ ≤ ≥ ≬ ⊂ ⊃ ⌈ ⌊ ⊤ ⊥ ⋆ ⌶ ⌷ ⌸ ⌹ ⌺ ⌻ ⌼ ⌽ ⌾ ⌿ ⍀ ⍁ ⍂ ⍃ ⍄ ⍅ ⍆ ⍇ ⍈ ⍉ ⍊ ⍋ ⍌ ⍍ ⍎ ⍏ ⍐ ⍑ ⍒ ⍓ ⍔ ⍕ ⍖ ⍗ ⍘ ⍙ ⍚ ⍛ ⍜ ⍝ ⍞ ⍟ ⍠ ⍡ ⍢ ⍣ ⍤ ⍥ ⍦ ⍧ ⍨ ⍩ ⍪ ⍫ ⍬ ⍭ ⍮ ⍯ ⍰ ⍱ ⍲ ⍳ ⍴ ⍵ ⍶ ⍷ ⍸ ⍹ ⍺ ⎕ ○
با توجه به اینکه تمام این کاراکترها را نمیتوان روی صفحهکلید قرار داد، سایر کاراکترها با توجه به ویرایشگری که مورد استفاده قرار میگیرد، با فشردن پشت سر هم دکمههای صفحهکلید تولید میشوند، برای مثال علامت لگاریتم با فشردن پشت سر هم shift-p و shit-o تایپ میشوند.
کنترل خطاها
در برنامههای APL چند نوع خطا ممکن است بروز کند:
خطا در حالت محاسباتی
اگر عبارتی محاسباتی را وارد کنید که دارای دادههای نامناسب باشد، مفسر معمولاً خطای domain error را باز خواهد گرداند. در مثال زیر از عملگر v استفاده شدهاست که تنها بر اعداد صفر و یک عمل میکند. همانطور که میبینید مفسر خطی که خطا دارد را چاپ کرده و با علامت ^ مکانی را که تصور میکند خطا در آن رخ داده را مشخص کردهاست.
1 1 0 11 ∨ 1 1 0 0
DOMAIN ERROR
1 1 0 11 ∨ 1 1 0 0
^
خطا در توابع و عمگرهای تعریف شده توسط کاربر
اگر در تابع یا عملگری که توسط کاربر خطایی بروز کند، اجرای برنامه متوقف میشود. پیام خطای مناسب به همراه شمارهٔ خطی که اجرا در آن متوقف شدهاست و نام تابع و همچنین عبارتی که خطا در آن است به همراه علامت ^ که نمایشگر محل خطا است نمایش داده میشوند. در مثال زیر خطا در تابع C و خط دوم رخ داده است.
LENGTH ERROR
C[2] 1 2 - 1 2 3
^
نمایانگر حالت
ممکن است اجرا در تابعی متوقف شود که توسط تابع دیگری فراخوانی شدهاست، در این حالت میتوانید با اجرای تابع سیستمی SI( حالتی که اجرا در آن قرار دارد را ببینید:
)SI
C[2] *
B[8]
A[5]
در مثال بالا تابع C در خط هشتم تابع B و تابع B نیز در خط پنجم تابع A فراخوانی شدهاست و تابع C در خط دوم متوقف شدهاست و پایان اجرای دو تابع دیگر نیز وابسته به پایان اجرای تابع C است. آن ستاره نشاندهندهٔ تابعی است که توقف در آن رخ داده است. (طرز نمایش حالت در تمام مفسرهای یکسان نیست، این طرز نمایش متعلق به APLX است).