دستورالعملهاي پردازش ليست:
ليسپ دستورالعملهاي زيادي را براي دستيابي و کنترل ليستها فراهم ميکند . ليستها ميتوانند مستقيما با پردازه? ليست ايجاد شوند .ليست هر تعدادي از آرگومانها را ميپذيرد و تعدادي از آرگومانها را بر ميگرداند.
(list 1 2 ‘a 3 ); Output : (1 2 a 3 ) (list 1 ‘(2 3) 4 ); Output : (1 (2 3) 4)
به اين دليل راهي که ليستها ايجادمي شوند از جفتهاي Cons (Car,Cdr) پردازه? Cons ميتواند براي اضافه کردن يک عنصر به جلوي يک ليست استفاده شود. توجه کنيد که پردازه? Cons در هدايت و به کار بردن آرگومانهاي ليست نامتقارن است ، بدين دليل روشهاي ليستها ايجاد ميشوند.
(Cons 1 ‘(2 3)); Output: (1 2 3 ) (Cons ’(1 2) ‘(3 4)) Output : ((1 2) 3 4)
پردازه? Oppend دو يا چند ليست را با هم ادغام ميکند و يک ليست واحد ايجاد ميکند زيرا ليست ليسپ يک لينک ليست است و پيچيدگي زماني الحاق کردن ليستها از مرتبه? پيچيدگي زماني O(n) ميباشد.
ساختار اشتراکي: ليستهاي ليسپ لينک ليستهاي ساده ميتوانند با يکي ديگر از ليستها در ساختمان مشترک باشند به عبارت ديگر دو ليست ميتوانند دم يکساني داشته باشنديا رشته? پاياني از Consهاي يکساني داشته باشند مثلا:
(setf foo (list "a "b "c)) (setf bar (cons "x (cdr foo)))
ليست foo و bar به ترتيب به صورت (a b c) و (X b c ) هستند هرچند دم (b c ) در هر دو ليست ساختار يکساني دارند ولي مانند هم نيستند، خانههاي Cons اشاره گر به b و c در محل حافظه? يکساني براي هردو ليست قرار دارد.
ساختار اشتراکي سريع تر از کپي کردن ميتواند به صورت چشمگيري کارايي را بهبود بخشند. هرچند ، اين مهارت ميتواند متقابلا در راههاي نامطلوب با عملکردهايي که تغييرات ليستهاي گذشته روي آرگومانهاي آن تاثير بگذارد ، اثر کند.
تغييرات يک ليست از قبيل تغيير دادن C با يک goose روي ديگري نيز تاثير ميگذارد setf (third foo) "goose) که اين تغيير نتيجه را به صورت (a b goose) تغيير ميدهد اما bar هم تغيير ميکند (X b goose) که ممکن است يک نتيجه? غير منتظره باشد.
زبانهاي برنامه نويسي Lisp معمولا از يک خط دستور محاورهاي استفاده ميکنند،که ميتواند با يک محيط پيچيده? گسترش يافته ترکيب شود.کاربر اصطلاحات و دستورات را در خط دستور وارد کرده يا با رهبري IDE آنها را به سيستم Lisp ميفرستد. Lisp دستورات را ميخواند ، آنها را ارزيابي ميکند و نتايج را چاپ ميکند. به اين دليل است که خط دستور زبان Lisp به حلقه? Read-Eval-Print يا REPL معروف است.
نمونه? سادهاي از عمليات REPL در زير آمدهاست. اين يک شرح سادهاست که بسياري از المانهاي Lispواقعي در آن نميايد مانند ماکروها و کوئتها.
تابع read جملات متني را به عنوان ورودي ميپذيرد و آنها را به ساختار ليست تجزيه ميکند. به عنوان مثال ، وقتي شما رشته? (+ 1 2) را در اعلان تايپ ميکنيد، تابع read آن را به يک ليست پيوندي حاصل از 3 المان ترجمه ميکند: علامت + ، عدد 1 و عدد 2 . خيلي اتفاق ميافتد که ليست قسمت موثري از يک کد Lisp باشد که قابل ارزيابي است.به همين دليل است که يک قطار از ليست به يک تابع نام عملگر مع ميدهد.
تابع eval ساختار ليست را ارزيابي ميکند و نوعي ديگر از ساختار را به عنوان نتيجه باز ميگرداند.ارزيابي کردن لزوما تفسير کردن معني نميدهد؛ بعضي سيستمهاي Lisp هر عبارتي را به زبان ماشين تبديل ميکنند. خيلي ساده است؛ به هر حال؛ براي تعريف ارزيابي به عنوان تفسير : براي ارزيابي يک ليست که نام تابع دارد ، eval ابتدا تمام آرگومانهاي داده شده به cdr اش را ارزيابي ميکند و سپس تابع را روي آن آرگومانها اعمال ميکند.در اين مثال ، تابع عمل جمع است و به آرگومانهاي (1 2) اعمال ميشود که نتيجه 3 است.اين نتيجه? ارزيابي است.
اين وظيفه? تابع print است که نتيجه را به کاربر نمايش دهد. براي نتيجه? ساده? 3 اين کار ناقابل است. يک عبارت که با قسمتي از ساختار ليست ارزيابي ميشود مياز دارد که print ليست را به حرکت در آورد و در خروجي به شکل يک عبارت S نمايش دهد.
براي اجرا کردن يک REPL در Lisp ، تنها لازم است که اين سه تابع را اجرا کنيد و يک تابع حلقه بي نهايت را.(به طور طبيعي اجراي eval پس از اجراي عملگرهاي ويژهاي مانند if پيچيده خواهد شد.)يک REPL ساده به خودي خود با يک خط کد انجام شد: (loop(print(eval(red))))
ليست در اصل تعداد کمي ساختار کنترلي دارد. منتها در تکامل و گسترش زبان تعداد زيادي به آن اضافه شدند.(عملگر اصلي شرايط در زبان Lisp که cond بود بعدا متشکل شد از ساختار if-then-else )
برنامه نويسان در نسخه? Scheme حلقهها را به صورت بازگشت دم( tail recursion ) بيان ميکنند. موسسات متعارف علوم کامپيوتر Scheme بعضي دانشجويان را متعاقد ميکند که تنها راه تکرار در زبان Lisp استفاده از بازگشت دم است؛ اين اشتباه است. تمامي نسخههاي متداول ديده شده از Lisp داراي ساختارهاي الزامي براي تکرار هستند.درScheme دستور do به عنوان دستور حلقه پيچيده? Lisp است. علاوه بر اين مساله? اصلي که شي گرايي را مهمتر از مساله? فاعلي کرده اين است که Scheme نيازهاي ويژهاي براي کارکردن با فراخواني دم(tail calls )دارد، در نتيجه دليل ترغيب Scheme به استفاده از بازگشت دم اين است که روش صراحتا با تعريف خود زبان پشتيباني ميشود . در مقابل ، ANSI Common Lisp نيازي به بهينه سازي که معمولا به حذف فراخواني دم گفته ميشود ندارد. در نتيجه اين حقيقت که بازگشت دم به عنوان يک جايگزين تصادفي براي استفاده از ساختارهاي مبتني بر تکرار ( مانند do dolist loop ) توصيه نميشود تنها يک مساله? برتري ادبي نيست ، ولي بالقوه يکي از کارآمدهاست ( بعد از اين که اين روش فقط به عنوان يک پرش ساده به کار نرفت) و به عنوان يک تصحيح برنامهاست .
بعضي از ساختارهاي کنترلي Lisp عملگرهاي ويژهاي هستند ، هم ارز کليدواژههاي ترکيبي باقي زبانها. عباراتي که اين عملگرها استفاده ميکنند ظاهري شبيه فراخواني تابع دارد، تفاوت اينجاست که آرگومانها ضرورتا نبايد ارزيابي شوند يا در مورد تکرار شايد بارها ارزيابي شوند. در مقابل اکثر زبانهاي برنامه نويسي ، Lisp به برنامه نويسان اجازه ميدهد با خود زبان ساختاهاي کنترلي را پياده سازي کنند.ساختارهاي کنترلي زيادي در ماکروهاي Lisp پياده سازي ميشوند و برنامه نويسان ميتوانند هر ماکرو را گسترش دهند ،براي آناني که ميخواهند بدانند چطور کار ميکند.
هر دوي Lisp Commonو Scheme داراي عملگرهاي کنترلي غير محلي هستند.تفاوت اين عملگرها يکي از عميق ترين تفاوتها مابين اين دو نسخه? زبان است. Scheme از ورودي مستمر با استفاده از روش call/cc پشتيباني ميکند ، که به برنامه اجازه? ذخيره ( و بعدا بازيابي کردن) يک عمليات ويژه را ميدهد . Common Lisp از ورودي مستمر پشتيباني نميکند ولي از راههاي زيادي براي انجام رهايي از تکرار پشتيباني ميکند.