تبليغاتX
هوش مصنوعی
اولین منبع فارسی هوش مصنوعی
Lisp چهارشنبه یازدهم مرداد 1385 «

Common Lisp، که معمولاً به صورت CL مخفف مي شود، يک نوع از Lisp است که به وسيله ي
ANSI *30266 - 1994
استاندارد شده و براي استاندارد کردن نسخه هاي منشعب شده ي Lisp که بخش هايي از آن را دارا هستند، گسترش يافته است. CL در واقع يک پياده سازي نيست بلکه يک مشخصه ي زباني است که پياده سازي هاي Lisp با آن مطابقت دارد.

Common Lisp يک زبان برنامه نويسي همه منظوره است، در مقايسه با نسخه هاي Lispمانند Lisp Emacs و AutoLisp که زبان هاي جامع جاسازي شده در توليدات ويژه هستند. برخلاف بسياري از Lisp هاي اوليه، Common Lisp مانند Scheme از حوزه لغوي براي متغيرها استفاده مي کند.


Common Lisp
يک زبان برنامه نويسي چند نمونه اي است که:

·         تکنيک هاي برنلمه نويسي مانند برنامه نويسي زبان برنامه نويسي شي گرا، تابعي و آمرانه را پشتيباني مي کند.

·         به صورت پويا نوع دار شده است، اما با اعلان هاي نوع اختياري که مي تواند امنيت يا بازدهي را بهبود بخشد.

·         قابل گسترش در بين خصيصه هاي استاندارد مانند ماکروها و ماکروهاي خواننده است.

 

نحو

Common Lisp يک Lisp است؛ که از عبارات نحوي براي دلالت بر کد و ساختمان داده استفاده مي کند. فراخواني هاي ماکرو و تابع به صورت ليستي با آوردن نام تابع در ابتدا نوشته شده است، مانند مثال زير:
2
و 2 را جمع مي کند و نتيجه 4 مي دهد؛ ( + 2 2 )

به متغير "p" مقدار 3.1415 مي دهد؛ (setq) p 3.1415)) تعريف يک تابع که مجذور يک عدد را حساب مي کند ;

(defun)) square (x) (* x x))

محاسبه تابع;

"9" را برمي گرداند (square 3) ;

 

انواع داده

Common Lisp انواع داده اي زيادي حتي بيشتر از بسياري زبان ها دارد.




انواع اسکالر

انواع عدد شامل اعداد صحيح، کسري، مميز شناور و اعداد مختلط مي باشد. Common Lisp از bignums براي نشان دادن مقدارهاي عددي با دقت و اندازه دلخواه استفاده مي کند. نوع کسري، کسرها را با دقت نشان مي دهد، اين ويژگي در بسياري از زبان ها وجود ندارد. Common Lisp به صورت اتوماتيک مقدارهاي عددي را بين اين داده ها به صورت مناسب وارد مي کند.


نوع کاراکتر Common Lisp به کاراکترهاي ASCII محدود نمي شود- تعجب آور نيست وقتي Lisp، ASCII را نيز شامل مي شود. بعضي از پياده سازي هاي مدرن به کاراکترهاي يوني کد نيز اجازه استفاده مي دهد.

نوع سمبل نيز در زبان هاي Lisp رايج است، اما عموماً خارج از آنها شناخته شده نيست. يک سمبل يک شي داده اي نامدار واحد است. سمبل ها در Lisp شبيه شناسه ها در زبان هاي ديگر هستند، که به عنوان متغيرها براي نگهداري ارزش ها استفاده مي شوند. اگرچه، آنها بسيار عمومي تر هستند و مي توانند براي خودشان هم استفاده شوند. معمولاً وقتي يک سمبل ارزيابي مي شود، مقدارش به عنوان يک متغير برگردانده مي شود. استثناهايي نيز وجود دارد: سمبل هاي کلمات کليدي مثل: foo با خودشان ارزيابي مي شوند و مقدارهاي بولي در Common Lisp به وسيله ي سمبل هاي رزرو شده ي T و NIL نشان داده مي شوند.


ساختمان هاي داده

انواع ترتيبي در Common Lisp شامل ليست ها، بردارها، بردارهاي بيتي و رشته ها مي باشد. مانند Lispهاي ديگر، ليست ها در Common Lisp از consها ساختمان داده با دو بخش است که car و cdr ناميده مي شود. يک ليست يک زنجيره پيوندي از cons هاست. که car مربوط به cons به عضوي از يک ليست ارجاع مي کند (احتمالاً ليست ديگر). هر cdr مربوط به cons، به cons بعدي اشاره مي کند- - به جز آخرين cons که مقدارش به nil اشاره مي کند.consها به راحتي براي پياده سازي درخت ها و ديگر ساختمان هاي داده ي پيچيده استفاده مي شوند: اگر چه توصيه مي شود که از نمونه هاي کلاس يا ساختار به جاي آن استفاده شود.


Common Lisp
آرايه هاي چند بعدي را پشتيباني مي کند، و مي تواند به صورت پويا در صورت نياز آرايه ها را دوباره سايز دهي بکند. آرايه هاي چند بعدي مي تواند براي رياضيات ماتريسي به کار روند. بردار يک آرايه ي يک بعدي است. آرايه ها مي توانند هر نوع داده اي را به عنوان اعضاء داشته باشند (حتي انواع ترکيبي در همان آرايه) يا مي توانند براي شامل شدن نوع خاصي از اعضاء، تخصصي شوند مثلاً در برداري از اعداد صحيح. بسياري از پياده سازي ها مي توانند توابع آرايه اي را وقتي که آرايه ها در نوع هاي تخصصي شده به کار مي روند، بهينه کند. دو نوع آرايه اي تخصصي شده، استاندارد هستند: رشته برداري از کاراکترهاست در حالي که بردار بيتي، برداري از بيت ها است.
جداول Hash پيوستگي بين شي هاي داده اي را ذخيره مي کند. هر شي ممکن است به عنوان کليد يا مقدار استفاده شود. جداول Hash نيز مانند آرايه ها مي توانند به صورت اتوماتيک در مواقع نياز دوباره سايزدهي شوند.

بسته ها مجموعه اي از سمبل ها هستند که به طور عمده براي جدا سازي بخش هاي يک برنامه به فضاهاي نامي به کار مي روند. يک بسته بعضي از سمبل ها را خارج کرده و به عنوان بخشي از يک واسط عمومي مشخص مي کند.

 

ساختارها، شبيه struct ها در C و رکوردها در پاسکال، ساختمان هاي داده اي پيچيده ي دلخواه با هر عدد و نوعي از زمينه ها را نشان مي دهند.


توابع

در Common Lisp، نوع داده يک نوع دادهاي است. به عنوان نمونه، اين امکان وجود دارد که تابعي نوشته شود که توابع ديگر را به عنوان آرگومان مي پذيرد و همين طور به عنوان خروجي برمي گرداند. اين خواصيت اين امکان را فراهم مي کند که عمليات بسيار عمومي را به توان تشريح کرد.

کتابخانه Common Lisp شديداً به چنين توابع مرتبه بالاتري تکيه مي کند. مثلاً تابع sort عملگر مقايسه را به عنوان آرگومان مي پذيرد. بنابراين نه تنها مي تواند هر نوع داده اي را مرتب کند بلکه ساختمان داده را نيز مطابق با يک کليد مرتب مي کند.

(sort ( list 5 2 6 3 1 4) # ' >)

 ليست را با استفاده از اپراتور < به عنوان عملگر مقايسه کننده مرتب مي کند.

رابرمي گرداند ( 6 5 4 3 2 1 (


(
sort (list ' ( 9 a ) ' ( 3 b ) ' ( 4 c ) )

# ' ( lambda ( x y ) ( < ( car x ) ( car y ) ) ) )

ليست را مطابق با عنصر اول ( car) از هر زير ليست مرتب مي کند .

(3b) ( 4c ) ( 9a )را برمي گرداند.


مدل عرض يابي براي توابع بسيار ساده است. وقتي که عرضياب کننده با فرم (F A1 A2. . . ) مواجه مي شود بايد فرض کند که سمبولي که F ناميده مي شود يکي از گزينه هاي زير است:

1.         يک عملگر ويژه (به آساني در يک ليست ثابت چک مي شود(

2.         يک عملگر ماکرو (بايد قبلاً تعريف شده باشد(

3.         نام يک تابع ( پيش فرض، که ممکن است يک سمبل يا يک زير شکل باشد که با سمبل lambda شروع مي شود. (


اگر F نام يک تابع باشد، آنگاه آرگومان هاي A1, A2, ... An با ترتيب چپ به راست عرض يابي مي شوند و آن مقادير را به عنوان پارامتر مي گيرد.

 

فضاي نامي تابع

در اينجا يک تفاوت اساسي بين Common Lisp و Scheme وجود دارد.در CL، نام تابع در يک فضاي نامي جستجو مي شود که از فضاي نامي مربوط به متغيرها جدا مي باشد و فضاي نامي تابع ناميده مي شود. عملگرهايي که نام ها را در فضاي عمومي تعريف مي کنند شامل defun، flet و labels هستند.

براي فرستادن تابع با اسم به عنوان يک آرگومان به تابع ديگر، بعد از عملگر ويژه تابع که عموماً با علامت # ' خلاصه مي شود استفاده کرد. مثال sort اول به تابعي اشاره مي کند که نام < در فضاي نامي تابع، با کد #'> دارد.

مدل ارزيابي Scheme ساده تر است تنها يک فضاي نامي وجود دارد و همه مکان ها در فرم ارزيابي مي شوند (با هر ترتيب ) — نه فقط آرگومان ها.


گاهي براي برنامه نويسان با تجربه، کدي که در يک نسخه نوشته شده در نسخه هاي ديگر گيج کننده است. به طور نمونه، بسياري از برنامه نويسان CL ممکن است از نام هاي متغير توصيفي مثل ليست يا رشته استفاده کنند که در Scheme غير مجاز است و آنها با نام هاي توابع برخورد پيدا مي کنند. اگر چه فضاي نامي مجزا براي توابع يک حسن است، يک منبع مجادله در خانواده ي Lisp مي باشد. که معمولاً به عنوان Lisp-1 و Lisp-2 مورد ارجاع قرار مي گيرد. اين اسامي در مقاله اي در سال 1988 از ريچارد پ. گابريل ايجاد شد که به طور جامع اي دو روش را مقايسه مي کند.


سرانجام، در حالي که تعريف يک تابع شکل befunيک ليست است، توابع عموماً به صورت داخلي به صورت ليست نشان داده نمي شوند.

 

انواع ديگر

انواع ديگر داده اي در Common Lisp شامل موارد زير است:

·            نام مسير که نماينده فايل ها و شاخه ها در سيستم فايلي است. چون از لحاظ قدمت Lisp جداي از Unix بود، ويژگي نام مسير Common Lisp عمومي تر از قراردادهاي نام فايل بيشتر سيستم عامل ها است و اين ويژگي دسترسي به فيل ها را در برنامه هاي Lisp به طور گسترده اي قابل انتقال در سيستم هاي گوناگون مي کند.

·            جريان هاي ورودي و خروجي نشان دهنده تخليه و تغذيه ي داده هاي متني يا باينري هستند مانند فايل هاي باز يا نمايي.

·            Common Lisp داراي بلوک ساختماني توليد کننده اعداد تصادفي کاذب هستند. اشياء تصادفي نماينده منابع قابل استفاده ي مجدد اعداد تصادفي کاذب هستند و به کاربر اجازه مي دهند که PRNG را راه اندازي کند يا منجر به اجراي مجدد يک توالي از آن شود.

·            شرايط يک نوع ويژه است که براي نشان دادن خطاها، استثناها و ديگر وقايع که يک برنامه ممکن است به آنها پاسخ دهد استفاده مي شوند.


Common Lisp
در ضمن شامل جعبه ابزاري براي برنامه نويسي شي گرا به نام سيستم شي اي Common Lisp يا CLOS است.

 

ماکروها

يک ماکرو در Lisp به طور سطحي شبيه يک تابع در حال استفادده است. اگرچه، نشان دهنده ي عبارتي است که ارزيابي شده است، نماينده ي يک تغيير شکل کد اصلي برنامه نيز مي باشد. ماکروها به برنامه نويسان Lisp امکان ايجاد فرم هاي نحوي جديد در زبان را مي دهد. به عنوان نمونه، اين ماکرو شکل حلقه until را ايجاد مي کند، که ممکن است در زبان هايي مثل Perl آشنا به نظر مي رسد:

(defmacro until (test &body wbody)

(do ( )

( , test )

, @body ) )

; ; example

( until (+ (random 12 ) 0 )

( write-line "Hello" ) )


همه ي ماکروها بايد قبل از اين که کد اصلي شامل آنها ارزيابي يا کامپايل شود، گسترش يابند. ماکروها مي توانند به عنوان توابعي که درخت هاي نحوي انتزاعي را مي پذيرند و برمي گردانند ملاحظه شوند. اين توابع قبل از اينکه کامپايلر کد اصلي نهايي را توليد کند، احضار مي شوند. ماکروها در Common Lisp معمولي نوشته شده اند، و هر عملگر Common Lisp را مي توانند استفاده کنند. نکته اي که در بالا ذکر شد توسط Common Lisp براي ساده کردن مورد معمول از جايگزيني در قالب هاي يک کد، ايجاد شده است.

 

گرفتن متغيرها و سايه اندازي آنها


ماکروهاي Common Lisp قادر به گرفتن متغير هستند، موقعيتي که در آنها سمبل ها در بدنه گسترش يافته ي ماکرو با سمبل هاي متن فراخواني شده و منطبق مي شوند. گرفتن متغير ها گاهي اوقات اثر مطلوبي دارد: به برنامه نويسان امکان ايجاد ماکروها را جايي که سمبل هاي مختلف، معنايي ويژه دارند، مي دهد. اگرچه، مي تواند خطاهاي غير معمول و غير قابل انتظاري را نيز ايجاد کند.
بعضي از سيستم هاي Lisp مانند scheme، با استفاده از ماکرو ها از گرفتن متغير جلوگيري مي کنند — که ماکرو هاي تميز ناميده مي شوند. در Common Lisp مي توان بوسيله ي gensyms از گرفتن متغيرهاي ناخواسته جلوگيري کرد – gensyms سمبل هاي واحد گارانتي شده اي هستند که مي توانند در گسترش ماکروها بدون خطر گرفته شدن استفاده شوند.

مسئله ي ديگر سايه اندازي غير عمدي عملگرهاي استفاده شده در گسترش ماکروها است. مثلاً، کد (نادرست) زير را ملاحظه کنيد:

( mocrolet ( ( do ( . . . ) . . . something else . . . ) )

( until ( = ( random 10 ) 0 ) ( write- line "Hello" ) ) )


ماکرو UNTIL به شکلي گسترش مي يابد که DO را فراخواني کند، که به منظور ارجاع شکل ويژه پايه اي DO طرح ريزي شده است. اگر چه، در اين متن، DO ممکن است معناي کاملاً متفاوتي داشته باشد.

Common Lispمشکل سايه اندازي عملگر را با ممانعت از تعريف مجدد عملگرهاي ساختماني مثل DO در اين مثال، اصلاح مي کند. در ضمن، کاربران ممکن است کدهايشان را به بسته هايي تقسيم کنند. سمبل هاي ساختماني در بسته ي Common Lisp يافت مي شوند، که بوسيله ي سمبل ها در بسته ي کاربر سايه اندازي نمي شوند.

 

مقايسه با Lisp هاي ديگر

·         Common Lisp بسيار با Scheme مقايسه مي شود- - چون آنها دو نسخه ي معروف از Lispها هستند. Scheme از لحاظ تاريخي جديدتر از LC است، و نه تنها از همان Lisp مي آيد بلکه به وسيله بعضي از همان مهندسين نيز ارائه شده است- -

·         Guy L. Steele با Gerald Jay Sussman، Scheme را طراحي کردند و کميته استاندارد را براي Common  Lisp به کرسي نشاندند.

·         اغلب سيستم هاي Lisp که طراحي هايشان در Common Lisp توزيع شده - - مثل Zetalisp و Franz Lisp - - تنها از متغيرهايي که به صورت پويا محدود شده اند استفاده کرده اند. Scheme متغيرهايي را به Lisp معرفي مي کند که از لحاظ لغوي محدود شده اند و به صورت گسترده اي به عنوان يک ايده ي خوب شناخته شده و توسط CL اقتباس شده اند. CL متغيرهاي محدود شده ي پويا را پشتيباني مي کند اما بايد به طور صريح ذکر شود که آنها داراي اين مشخصه هستند.

·         Common Lisp گاهي Lisp2 ناميده مي شود و Scheme، Lisp1 که برمي گردد به استفاده ي CL از فضاهاي نامي مجزا براي توابع و متغيرها، (در حقيقت، CL فضاهاي نامي زيادي دارد مانند آنهايي که بري کلمات کليدي loop و نام هاي بلوکي و قالب go به کار مي روند.)

·         به علاوه پياده سازي ها قصد دارند به مجموعه هاي منشعبي از بسته هاي کتابخانه برسند که عملکردي را که در استاندارد پوشش داده نشده، تامين کنند. بعضي از اين خصيصه ها به استاندارد اضافه شدند مانند CLOS و قرارداد LOOP؛ بقيه ويژه ي پياده سازي باقي ماندند.

·         متأسفانه بسياري از وسايل ارزشمند براي برنامه نويس مدرن — مثل شبکه بندي TCP/IP--همچنان استاندارد نشده باقي مانده اند. اگر چه، بسته هاي با کد باز براي پشتيباني چنين خصيصه هايي به روش قابل انتقال ايجاد شده اند، يک نمونه قابل توجه آن پروژه ي مجمومه ي کد باز Common Lisp است.

·          Common Lisp براي پياده سازي وسيله ي کامپايليرهاي افزايشي طراحي شده است. تعريف هاي استاندارد به منظور بهينه کردن کامپايل در مشخصات زبان پيشنهاد شده است. اغلب پياده سازي هاي Common Lisp، توابع را براي بومي کردن کد ماشين کامپايل مي کنند. بقيه به کد بايت کامپايل مي کنند، که سرعت را کاهش مي دهد ولي قابليت انتقال کد باينري را آسان مي کند. اين تصور غلط که Lisp يک زبان کاملاً تفسير شده است، بسيار متحمل است در نتيجه ي اين حقيقت باشد که محيط هاي Common Lisp يک اعلان با اثر متقابل را تأمين مي کند و اينکه توابع يکي يکي به يک ترتيب افزايشي کامپايل مي شوند.

·         بعضي از پياده سازي ها براساس Unix مثل CLISP، مي توانند به عنوان مفسرهاي متني استفاده شوند; يعني به وسيله سيستم به صورت شفاف به ترتيبي که مفسر Perl ويا Unix shell است، احضار شوند.

 

ليست پياده سازي ها

پياده سازي هاي قابل توزيع مجدد رايگان شامل موارد زير است:

·            CMUCL در اصل از دانشگاه کارنگي ملون که در حال حاضر به وسيله ي کاربران متعدد استفاده مي شود. CMUCL از يک کامپايلر اصلي سريع مشهور استفاده مي کند و شامل مفسر نمي باشد، به طور گسترده اي از پياده سازي CL با کد منبع باز استفاده مي کند، در Linux و BSD براي اينتل x86 موجود هستند.

·            GNU CLISP

·             (Steel Bank Common) Lisp SBCL يک شاخه از CMUCL است. SBCL با تاکيد بيشتر روي قابليت نگهداري، از CMUCL باز شناخته مي شود. SBCL روي محيط CMUCL اجرا مي شود بجز HP/UX ؛ به علاوه روي لينوکس براي PowerPC، SPARC و MIPS و روي سيستم عامل Mac اجرا مي شود.

·             (GNU Common Lisp) GCL کامپايلر Lisp پروژه ي GNU. GCL هنوز کاملاً آماده ي انجام ANSI نيست ولي پياده سازيي از انتخاب براي پروژه هاي بزرگ مختلف شامل ابزارهاي رياضي Maxima و ACL2 است.

·             Common Lisp قابل جاسازي که براي جاسازي شدن در کاربردهاي C طراحي شده است.

 

·             OpenMCL يک شاخه ي کد منبع باز از Common Lisp مکينتاش. همانطوري که از اسم آن حاکي است،OpenMCL  ويژه ي مکينتاش است و روي سيستم عامل Mac، Darwin و يونيکس براي PowerPC اجرا مي شود.

·            Movitz محيط Lisp را براي کامپيوترهاي x86 بدون تکيه بر سيستم عامل تکميل مي کند.

·            Armed Bear Common Lisp يک نوع پياده سازي Common Lisp است که روي ماشين مجازي زبان برنامه نويسي جاوا اجرا مي شود و شامل کامپايلري براي بايت کدهاي زبان برنامه نويسي جاوا است و اجازه ي دسترسي به کتابخانه هاي جاوا را از Common Lisp مي دهد.

 

کاربردها

با وجود انتظارات بزرگ از کميته ي استاندارد CL (گاهي به عنوان جايگزيني براي C معرفي مي شود)، Common Lisp يک زبان برنامه نويسي مناسب باقي ماند، که اغلب در دانشگاه و يا محيط هاي کاربردي ويژه که در ارتباط با هوش مصنوعي است به کار مي رود.


اگرچه، داستان هاي موفقيت معروفي وجود دارد که حداقل، پتانسيل بزرگي از زبان را در صنعت نشان مي دهد. بسياري از کاربران Common Lisp براي معرفي زبان مطلوب شان مثال آشناي سايت بازرگاني yahoo را مي زنند که با Common Lisp گسترش يافته است.


درضمن کاربردهاي کد منبع باز موفقي به زبان Common Lisp وجود دارد مثل:

·            acl2، Common Lisp کاربردي، يک ثابت کننده نظريه با تمام خصيصه ها براي زير مجموعه اي از Common Lisp.

·            Maxima، يک سيستم جبري کامپيوتري خبره.

·            Compo، زباني که به ساختارهاي موسيقي پيچيده اجازه توصيف به يک روش طبيعي را مي دهد.

·            Lisa، سيستم توليد قانون براي ساختن نماينده هاي نرم افزاري "هوش"

اين ليست غير کامل اين نظريه را تأييد مي کند که Common Lisp وقتي مسائل مشکل مورد بررسي واقع مي شوند کاربرد دارد. به علاوه بسياري از کاربردهاي CL يک روش "زبان به زبان" را تکميل مي کند که براي آن برنامه، امکان دستکاري داده ها را مانند زبان فراهم مي کند (با نشان دادن عبارات نحوي و پشتيباني ماکروها)

نوشته شده توسط حسین | موضوع: برنامه | لینک ثابت | | | |

Python یکشنبه هشتم مرداد 1385 «

 
Copyright © 2007 by Hussein Taleghani