مقدمه

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

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

در زیر به برخی از مهمترین ویژگی های یک زبان خوب اشاره خواهیم کرد :



1. Simplicity, Unity and Clarity
یک فرد مبتدی به آسانی می تواند توسط یک کد مبهم و گنگ یا کدی که خواندن آن به آسانی ممکن نباشد، گیج و مبهوت شود. زبانی که Syntax آن معمول نباشد و دنبال کردن آن مشکل باشد، برای یاد گرفتن مشکل است و در صورتی که قدرت زیادی را نیز داشته باشد ممکن است از لیست انتخابی خیلی از افراد حذف شود. در زیر قطعه کدی از زبان ML و زبان C از برنامه معروف Hello World آورده شده است. هر دوزبان به علت پشتیبانی از تکنیک Structure و پشتیبانی از برنامه نویسی رویه ای از نظر دنبال کردن خوانا می باشند ولی Syntax زبان ML نسبت به C بسیار پیچیده تر است.



hello :- printstring("HELLO WORLD!!!!").

printstring[].

printstring[H|T] :- put(H), printstring(T).



C:

int main()

{

printf("Hello, World!\n");

}

2. Orthogonality (تعامد)
تعامد در یک زبان برنامه سازی به این معناست که زبان باید مجموعه ای از امکانات را معرفی کند که برای نیل به یک مفهوم مشابه استقلال خطی بین آنها وجود داشته باشد. به عبارت دیگر، برای انجام یک عملیات خاص نباید تعداد زیادی راه وجود داشته باشد.در حالی که این موضوع می تواند محدودیت سختی را بر روی Syntax یک زبان ایجاد کند ولی یک فرد تازه کار با مواجه شدن با زبان قدرتمند ممکن است وحشت کند. به عنوان مثال زبان Perl. تمامی خطوط برنامه زیر همگی یک کار انجام می دهند و با هم معادل هستند.

if ($x == 0) {$y = 10;} else {$y = 20;}

$y = $x==0 ? 10 : 20;

$y = 20; $y = 10 if $x==0;

unless ($x == 0) {$y=20} else {$y=10}

if ($x) {$y=20} else {$y=10}

$y = (10,20)[$x != 0];

و یا به عنوان مثالی دیگر زبان C به شما اجازه ی مراجعه به یک اندیس آرایه را به طرق مختلف می دهد : x[i] یا *(x+i) یا *++x. چنین خصوصیتی Syntactic Synonym نامیده می شود. عبارت مشابه دیگری با نام Syntactic Homonym وجود دارد به این معنی که ساختارهای متفاوتی وجود دارد که از نظر نگارشی شبیه به هم هستند ولی از نظر معنی متفاوت هستند. List و Turing از جمله زبان هائی هستند که این خاصیت را دارا می باشند. البته وجود راه های متفاوت برای انجام امری یکسان، انعطاف پذیری بیشتری به برنامه نویس می دهد که خود این امر متبهر بودن و هنرمند بودن برنامه نویس را طلب می کند. اکثر برنامه نویسان تازه کار با این امکانات کدهایی را ایجاد می کنند که اغلب یا ناخوانا هستند یا کم بازده و یا در برخی موارد نادرست.

3. Naturalness for the application
زبان یک ابزار است و هر ابزاری باید در جای مناسب آن استفاده شود. توجه به اهداف زبانها می تواند مشخصه ی تمایز میان آنها باشد. به عنوان مثال هنگامی که شما قصد ایجاد یک برنامه ی شبیه سازی کامپیوتری را دارید استفاده از زبانهای برنامه نویسی نظیر QBasic یا C و یا Java کار شما را به مراتب طولانی تر و چه بسا پرهزینه تر و مشکل تر می سازد حال آنکه انتخاب ابزار مناسب همانند زبان برنامه سازی GPSS یا Simula در این مکان انتخاب بسیار مناسب تر و عاقلانه تری می باشد.


4. Coverage
زبان برنامه سازی باید تمام مفاهیم و ساختارهای عمومی را پوشش دهد. در بخشی باید شامل ساختارهای شرطی (if…then..else, switch…case)، حلقه ای (while, for)، ساختارهای داده ای و اطلاعاتی متراکم (structures, classes, objects ) و مدیریت استثناعات باشد و در بخش مخصوص دیگری که خاص هر زبان است باید شامل ساختارها و امکاناتی که خاص آن زبان است باشد مثل Prolog (منطق) و ML (برنامه نویسی وظیفه ای).

5. Portability
یکی از ویژگی های بسیار مهم یک زبان برنامه سازی خوب قابلیت حمل آن است. به این معنا که با انتقال برنامه از یک ماشین به ماشین دیگر برنامه بدون هیچ مشکلی و همانند بار اول اجرا شود. هنگامی که بحث Portability یا قابلیت حمل یک برنامه مطرح می شود، واژه دیگری به نام Framework برای آن مطرح می شود. Framework چهارچوب کاری می باشد که هر ماشین برای اجرای برنامه های مربوط به آن باید آنرا همراه داشته باشد. به عنوان مثال JVM یا Java Virtual Machine چهارچوب کاری است که هر ماشینی که توانائی اجرای آن را داشته باشد توانائی اجرای برنامه های Java را نیز دارد. در حقیقت برنامه های نوشته شده به زبان Java بر روی JVM اجرا می شوند بی آنکه بدانند بر روی چه ماشینی در حال اجرا شدن هستند.

6. Turnaround Time and Debugging Support
سرعت انجام امور Verification و عمل Recompiling و Run برای برنامه نویسان تازه کار از اهمیت ویژه ای برخورد دار است. زیرا برنامه نویسان تازه کار در ابتدا کار خود را اغلب با برنامه های کوچکی شروع می کنند که سرشار از خطاهای نگارشی می باشد و پس از تغییرات کوچکی مجددا برنامه را Run می کنند.

7. Cost
یکی دیگر از ویژگی های یک زبان برنامه سازی هزینه آن است. در دنیای مهندسی هیچ وقت نمی گوئیم هزینه کمتر نشان از بهتر بودن آن است. هزینه در دنیای مهندسی چند بعدی است :

1. هزینه استفاده
2. هزینه انتقال برنامه
3. هزینه اجرای برنامه
4. هزینه ایجاد برنامه
5. هزینه نگاه داری برنامه
6. هزینه یادگیری زبان برنامه سازی

8. Regularity
خاصیت باقاعده به این معناست که زبان باید پایدار بماند هم به صورت نگارشی و هم به صورت مفهومی. در غیر این صورت همیشه باید برای اجرای برنامه دست به دعا باشید تا تاثیرات جانبی ناخواسته و یا خطاهای منطقی گریبانگیر برنامه های شما نشوند. نمونه معروف این مورد می تواند از زبان C به صورت زیر باشد :


if(x = 1) {

// do something;

}

وضعیت فوق صرف نظر از مقدار x همیشه درست است. C دارای یک قابلیت غیر طبیعی و ضعیف است که عمل تبدیل نوع هر نوع دیتائی را به نوع صحیح انجام می دهد بی آنکه در بیشتر حالت ها به برنامه نویس توجه کند و نتیجه این معمولا بروز خطاهای منطقی می شود که به آسانی برای برنامه نویس آشکار نمی شود. زبان های برنامه سازی نوع قوی مانند Java این مشکل را با محدود کردن استفاده از متغیر های نوع Boolean حل کرده اند.

نمود دیگری از پایداری نسبت به انواع داده ای مطرح می شود. مثال دیگری از C اینکه به عنوان مثال نوع داده ای int در برخی platformها 4 بایت اشغال می کند حال آنکه در برخی دیگر 2 بایت اشغال می کند. از طرف دیگر زبان Java این مشکل را با کلمه کلیدی exactly حل کرده است.

9. Easy Verification
یکی دیگر از ویژگی های یک زبان خوب بازبینی آسان برنامه می باشد. سه عمل اصلی در بازبینی که توسط یک زبان برنامه سازی باید پوشش داده شود عبارت است از :

Testing
Debugging
Proving

10. Excess Brevity
افراط در خلاصه نویسی اغلب در نگاه اول بسیار هوشمندانه تلقی می شود و ممکن است در برخی حالت ها نیز بسیار مفید واقع شود، اما این مطلب همیشه برای برنامه نویسان تازه کار خوشایند و آسان نیست. اکثر افرادی که تازه کار هستند مشتاقند تا مفاهیم و اصول را بیاموزند نه اینکه بیاموزند چگونه این مفاهیم می توانند به صورت خلاصه نوشته شوند. برای حفظ اصول نگارشی و مفهومی برنامه، در زبان باید از خلاصه نویسی افراطی دوری نمود. برای نمونه زبان هائی نظیر Lisp و Schema فقط یک نوع ساختمان داده دارند : لیست. این انتزاع به آسانی شرح داده می شود حال آنکه نتیجه آن در کدهای غیر قابل خواندن با یک ساختار داده ای محدود و کوچک ظاهر می شود. مثلا (* 2 3 4) که برابر عدد 24 است.

11.Excess Verbosity
از طرف دیگر دراز گوئی و اطناب نیز باب میل نیست. تازه کاران ممکن است احساس ناتوانی در یاد گرفتن نگارش زبان کنند و از فراگیری مفاهیم باز بمانند. بسیاری از تازه کارها هیچ وقت نفهمیدن که چرا تابع Main در Java به صورت static و void تعریف می شود ولی در C به اسن صورت نیست :

public class Hello{

public static void main(String args[]{

System.out.println("Hello, World!");

}

}

زبان های برنامه نویسی نوع قوی همانند Java محدودیت های زیادی را برای برنامه نویس ایجاد می کنند و برنامه نویس را مجبور می کنند تا با مفاهیم پیشرفته ای همچون Inheritance و یا Polymorphism آشنا باشد.

زبان برنامه نویسی COBOL، بسیار شبیه زبان انگلیسی طراحی شده و به حد افراطی شامل اطناب و دراز نویسی می باشد. برنامه Hello World از این زبان در زیر نوشته شده است :

000100 IDENTIFICATION DIVISION.

000200 PROGRAM-ID. HELLOWORLD.

000500 ENVIRONMENT DIVISION.

000600 CONFIGURATION SECTION.

000700 SOURCE-COMPUTER. RM-COBOL.

000800 OBJECT-COMPUTER. RM-COBOL.

000900

001000 DATA DIVISION.

001100 FILE SECTION.

001200

100000 PROCEDURE DIVISION.

100100

100200 MAIN-LOGIC SECTION.

100300 BEGIN.

100500 DISPLAY "HELLO, WORLD.".

100600 STOP RUN.

100700 MAIN-LOGIC-EXIT.

100800 EXIT.

12. Complex Grammar
مشکلات این دسته از خواصی همچون Syntactic Homonyms و Synonyms که اخیرا شرح داده شد، ناشی می شود. یکی دیگر از دلایل گیج کننده در برنامه سازی مفروضات بی سر و صدائی هستند که برای انواع پارامترها و مقادیر برگشتی و غیره که به صورت صریح تعریف نشده اند رخ می دهد. تعیین مکانیزم ارتباطی پارامترها نظیر (انتقال توسط مقدار، انتقال توسط مرجع، انتقال توسط نام، انتقال توسط نتیجه و انتقال توسط مقدار-نتیجه) برای افراد مبتدی پیچیده می باشد. اگر برای تازه کار خوب توضیح داده نشود، این پریشانی می تواند باعث شود مبتدی برنامه های اشتباهی را بنویسد که خطایابی آن بسیار مشکل می باشد. به عنوان مثال Java همیشه از مکانیزم انتقال توسط مقدار استفاده می کند، حال آنکه در همه جا از مراجع اشیاء (Object References) استفاده می کند. این مطلب مبتدیان را گیج می کند ولی جواب آن ساده است، Java متغیری را که حامل اشاره گری به یک شئ است را توسط مکانیزم انتقال توسط مقدار انتقال می دهد که این خود باعث انتقال توسط مرجع شئ می شود.

13. Variable Data Types
مبتدیان باید با تعداد زیادی انواع داده ای در هر زبانی آشنا باشند. در واقع، برنامه نویسان حرفه ای نیز گاهی در انتخاب نوع داده ای مورد نظر مشکل دارند و در پایان از انواع داده ای مرسوم استفاده می کنند. این مشکل اکثرا در انواع داده ای ابتدائی عددی و رشته ای ناشی می شود. نمونه ای از این مشکل که اختلاف بین انواع داده ای نقطه شناور را مطرح می کند ،زبان C می باشد : float و double. نوع داده ای float در این مورد بسیار بدنام است. کار کردن با این نوع داده ای مشکل و سخت می باشد و بسیاری از مردم ترجیح می دهند از نوع double استفاده کنند با اینکه به این دقت زیاد احتیاجی ندارند. مثال دیگر اینکه زبانهای C/C++‎ دارای 32 نوع داده ای عددی می باشند که هر کدام از آنها بسته به ماشینی که آنها را اجرا می کند حافظه ی متتفاوتی اشغال می کنند. مثلا نوع داده ای int از 16 تا 32 بیت، بسته به ماشین اجرا کننده آن حافظه اشغال می کند. واضح و مبرهم است که هنگام استفاده از انواع داده ای عددی، اغلب نیاز است تا کاربر به نحوه ی نمایش داخلی و محدودیت های آن واقف باشد. برای نمونه قطعه کد زیر هیچ وقت پایان نمی یابد :

int main()

{

for(double i = 0;i != 10;i += .1)

cout << i << endl;

return 0;

}

14. The Balance of Power
بعضی زبان ها قدرت زیادی را در اختیار برنامه نویسان قرار می دهند حال آنکه برخی دیگر او را بسیار محدود می کنند. به عنوان مثال زبانی که این امکان را می دهد تا توسط اشاره گرها امکان اشاره به هر نقطه ای از حافظه وجود داشته باشد نمی تواند عمل خودکار جمع آوری پس مانده (garbage collection) را انجام دهد. مثلا در زبان Java با محدود کردن برنامه نویس و خالی کردن زبان از کار با اشاره گرها امکان انجام خودکار جمع آوری پس مانده (garbage collection) وجود دارد. اشاره گرها امکانات و مفاهیم بسیار مهم و حیاتی و قدرتمندی هستند که درک و فهم آنها برای برنامه نویسان مبتدی مشکل است و برای کار با آنها نیاز به برنامه نویسی دقیق و بحرانی می باشد.

15. Readable Syntax and Natural Semantics
استفاده از کلمات کلیدی قابل پیش بینی ( if به جای cond، head/tail به جای car/cdr و != به جای <>)

16. Support for abstraction
یک زبان خوب می بایست از انتزاع پشتیبانی کند. یعنی می بایست به برنامه نویس امکاناتی ارائه دهد تا بتواند آنچه در سر می پروراند به رشته کد تبدیل کند. هر چه قدر پشتیبانی از انتزاع یک زبان قوی تر باشد، Orthogonality و Naturalness for the application آن زبان ضعیف تر است.

17. Pitch it Right
سطح انتزاع زبان باید در یک سطح مناسب قرار داشته باشد. نه زیاد بالا و نه زیاد پائین. انتزاع (The abstraction) باید انعطاف پذیری را بدون توجه به استفاده آسان آن تامین کند. به عنوان مثال Lisp فقط یک نوع ساختمان داده دارد : list. این ساختمان داده به راحتی استفاده می شود ولی در بسیاری از موارد برای حل هر مشکلی مناسب نیست.

18. Keep I/O Simple
ساده سازی کار با I/O توجه برنامه نویس را به حل مشکل و ساختارهای اساسی برنامه بیشتر می کند. برای مثال، I/O در Java به صورت افراطی خوب طراحی شده است : گسترش پذیر و قدرتمند. اگرچه استفاده از آن مستلزم تسلط بر مفاهیمی چون تفاوت های streamهای کاراکتری و داده ای و نحوه ی کار streamهای آبشاری می باشد. در C++‎ نیز، I/O هم ساده و هم قدرتمند تعریف شده است. برای استفاه از آن فقط کافی ست با توابعی چون printf/scanf و cin/cout آشنا باشید. و برای برنامه نویسان حرفه ای streamهای C++‎ تمام خصیصه های مورد نیاز آنها را فراهم می کند.

19. Development Support
خاصیت “پشتیبانی از توسعه” یک زبان شامل مراجع زبان، مستندات API، اشکال زداها و محیط های توسعه آن می باشد.

20. Structured یا Object Oriented
یکی دیگر از خصیصه های یک زبان برنامه سازی پشتیبانی از تکنیک های برنامه نویسی نظیر ساخت یافته و یا شئ گرائی است.

21. Program Design
اولین و سخت ترین نمود طراحی برنامه این است که بفهمیم و تصمیم بگیریم که برنامه می بایست چه کاری را انجام دهد، و سپس آن را به طرز صریح، روشن، دقیق و قابل قبولی فرموله سازی کنیم. اغلب موارد چیزی که مشکل است این است که بفهمیم چگونه باید این کار را انجام دهیم ! چگونه یک وظیفه بزرگ را به وظایف کوچکتر قابل حل تقسیم کنیم و یا هدف هر کدام از این وظایف کوچکتر را معین و مشخص کنیم و رابطی موثر بین آنها ایجاد کنیم ؟ یک زبان برنامه سازی خوب نباید فقط امکاناتی را جهت تشریح اینکه چگونه برنامه Run می شود ارائه کند، بلکه باید آن چیزی را که قصد انجام آن را دارد تشریح کند. و این باید در سطوح متفاوتی قابل بیان باشد از استراتجی های کلی گرفته تا نحوه ی کد نوشتن و استفاده از ساختمان های داده.

22. Security
یکی دیگر از ویژگی های یک زبان برنامه نویسی خوب امنیت آن است. معمولا به صورت گسترده ای از این مقوله پرش می شود و آن را به عهده ی برنامه نویس می گذارند. با یک زبان ایمن، امنیت برای اشکال زدائی و تولید یک محصول مستحکم تر می شود.

23. Efficient Object Code
یکی دیگر از آرگومانهای که در میان علاقه مندان طراحی زبان های برنامه سازی بسیار معمول است این است که تولید کد موثر برای اشیاء زیاد مهم نیست; هنگامی که سرعت و ظرفیت کامپیوترها روز به روز در حال افزایش می باشد و هزینه تهیه آنها نیز روز به روز کاهش پیدا می کند، این برای طراحان زبان های برنامه سازی خود یک مزیت کافی به شمار می رود. در حالی که در صورت عدم توجه به تولید کد کارآمد باعث ایجاد برنامه هائی می شود که نیاز به منابع سیستمی زیادی دارند و در سطح کلان این برنامه ها عملا بسیار پرهزینه می شوند. همانطور که منابع سیستمی هر روز در حال رشد و ارزان تر شدن هستند، نیازهای روز بازار و مردم، پردازش اطلاعات و ظرفیت ذخیره سازی بیشتری طلب می کند.

1- حجم وظایفی که نیاز به پردازش های کامپیوتری دارند بیشتر از سرعت رشد منابع سخت افزاری و ارزان شدن آنها می باشد.

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

3- در آینده ما باید انتظار داشته باشیم که طراحان سخت افزار بیشتر به افزایش قابلیت اطمینان توجه داشته باشند تا سرعت و هزینه.

4- سرعت، هزینه و قابلیت اطمینان وسایل جانبی همسان با سرعت پردازششان رشد نمی کنند.

5- اگر کسی اجازه دارد تا کد غیر موثر تولید کند، آن زبان برنامه سازی یا طراح زبان برنامه سازی نیست بلکه برنامه نویسی است.

24. Comment Conventions
اگر هدف یک زبان برنامه سازی کمک به مستند سازی برنامه می باشد، طراحی یک قرارداد مستند سازی عالی به طور بدیهی مهمترین امر است. یکی دیگر از ویژگی های یک زبان خوب داشتن یک قرارداد مستندسازی و امکانات مربوط به آن است.

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

 LDAX       [this is a comment

بسیاری از زبان های برنامه سازی جدید کاراکترهای خاصی را جهت درج توضیحات اختصاصی کرده اند. مثلا در زبان C#‎ توضیح مابین کاراکتر های /* Comment */ قرار می گیرد و یا استاندارد های جدیدی را جهت مستندسازی معرفی کرده است تا در تولید اسناد مستندسازی جامع برنامه از آن استفاده نماید.

منابع :
The ACM Student Magazine
Cambridge University Press - Concepts in Programming Languages
و ...

دانلود pdf

موفق باشید
سید محمد رضا فراحی (manager)