لیسپ، که مخفف "پردازش لیست" است، خانوادهای از زبانهای برنامهنویسی است که دارای نحو خاصی مبتنی بر پرانتز هستند و عمدتاً بر روی دستکاری نمادها و لیستها متمرکز است. این زبان یکی از قدیمیترین زبانهای برنامهنویسی سطح بالا است که در اواخر دهه 1950 اختراع شد و در طول دههها به طور قابل توجهی تکامل یافته است. لیسپ به ویژه به خاطر ویژگیهای قدرتمند خود مانند نوعگذاری پویا، جمعآوری زباله و توابع درجه یک شناخته شده است که آن را برای تحقیقات هوش مصنوعی، محاسبات نمادین و نمونهسازی سریع مناسب میسازد.
لیسپ توسط جان مککارتی در سال 1958 به عنوان یک نماد ریاضی برای برنامههای کامپیوتری و به عنوان یک وسیله عملی برای پیادهسازی هوش مصنوعی ایجاد شد. این زبان از حسابان لامبدا، یک سیستم رسمی در منطق ریاضی و علوم کامپیوتر، مشتق شده است. اولین پیادهسازی بر روی IBM 704 انجام شد و به زودی، لهجههای متعددی ظهور کردند که هر کدام ویژگیها و پیچیدگیهای خاص خود را اضافه کردند.
چندین لهجه قابل توجه از لیسپ در طول زمان ظهور کردهاند، از جمله Common Lisp و Scheme. Common Lisp در دهه 1980 استانداردسازی شد تا لهجههای مختلف را یکپارچه کند، در حالی که Scheme که بر برنامهنویسی تابعی و حداقلگرایی تأکید دارد، در دانشگاهها محبوبیت پیدا کرد. تأثیرات لیسپ را میتوان در بسیاری از زبانهای برنامهنویسی مدرن مشاهده کرد، به ویژه در زبانهایی که از پارادایمهای برنامهنویسی تابعی پشتیبانی میکنند، مانند Clojure، Racket و حتی زبانهایی مانند Python و Ruby.
امروز، لیسپ در میان محبوبترین زبانهای برنامهنویسی نیست، اما همچنان تأثیرگذار است، به ویژه در تحقیقات، هوش مصنوعی و آموزش. جامعه به طور فعال لهجههای جدیدتری مانند Clojure را توسعه میدهد که بر روی ماشین مجازی جاوا (JVM) اجرا میشود و بر برنامهنویسی همزمان تمرکز دارد.
لیسپ از نحو منحصر به فردی استفاده میکند که از پرانتزها برای نشان دادن عبارات استفاده میکند، با کدی که در عبارات نمادین (S-expressions) نمایش داده میشود. به عنوان مثال:
(+ 1 2)
این عبارت نمایانگر جمع 1 و 2 است.
توابع در لیسپ میتوانند به عنوان آرگومانها منتقل شوند، از توابع دیگر بازگردانده شوند و به متغیرها اختصاص داده شوند:
(defun square (x) (* x x))
(mapcar #'square '(1 2 3 4)) ; برمیگرداند (1 4 9 16)
لیسپ نوعگذاری پویا دارد و به متغیرها اجازه میدهد تا مقادیر هر نوع دادهای را بدون اعلام قبلی نگه دارند:
(setq x 10) ; x اکنون یک عدد است
(setq x "hello") ; x اکنون یک رشته است
لیسپ دارای سیستمهای ماکرو قدرتمندی است که به توسعهدهندگان اجازه میدهد تا ساختارهای نحوی سفارشی ایجاد کنند:
(defmacro when (condition &body body)
`(if ,condition
(progn ,@body))
)
فرمهای if
و cond
جریان کنترل را در لیسپ تسهیل میکنند:
(if (> x 0)
(print "مثبت")
(print "غیر مثبت"))
لیسپ لیستها را به عنوان ساختارهای داده بنیادی در نظر میگیرد:
(setq my-list '(1 2 3 4))
(car my-list) ; برمیگرداند 1
(cdr my-list) ; برمیگرداند (2 3 4)
توابع با استفاده از ساختار defun
تعریف میشوند:
(defun factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
Common Lisp شامل یک سیستم شیءگرا به نام سیستم شیءگرای Common Lisp (CLOS) است:
(defclass person ()
((name :initarg :name :accessor person-name)
(age :initarg :age :accessor person-age)))
(defmethod say-hello ((p person))
(format t "سلام، نام من ~A است و من ~A ساله هستم."
(person-name p) (person-age p)))
لیسپ یک مکانیزم پیشرفته برای مدیریت خطاها با استفاده از handler-case
ارائه میدهد:
(handler-case
(/ 1 0)
(division-by-zero () (print "خطای تقسیم بر صفر شناسایی شد!")))
در برخی لهجهها، ادامهها پشتیبانی میشوند و به برنامه اجازه میدهند تا وضعیتهای اجرایی را ذخیره و بازیابی کند:
(call-with-current-continuation
(lambda (k)
(k 10)))
چندین محیط توسعه یکپارچه (IDE) و کامپایلر برای برنامهنویسی لیسپ وجود دارد. انتخابهای محبوب شامل:
برای ساخت یک پروژه لیسپ، معمولاً فایلی با پسوند ".lisp" یا ".lsp" ایجاد میکنید. با استفاده از SBCL، یک گردش کار معمول ممکن است شامل بارگذاری پروژه شما از REPL باشد:
(load "my-project.lisp")
برای پروژههایی که از Quicklisp، یک مدیر کتابخانه، استفاده میکنند، وابستگیها به راحتی مدیریت و بارگذاری میشوند.
لیسپ به ویژه به خاطر کاربردهایش در هوش مصنوعی، محاسبات نمادین و دانشگاه شناخته شده است، اما همچنین در زمینههای زیر نیز کاربرد دارد:
لیسپ اغلب با:
ترجمه از لیسپ به زبانهای دیگر معمولاً با استفاده از ابزارهای ترجمه منبع به منبع انجام میشود. به عنوان مثال، ابزارهای زیر وجود دارند:
هر یک از این ابزارها نقشههای خاصی را ارائه میدهند که اطمینان حاصل میکند که عملکردهای اصلی لیسپ میتوانند به طور مؤثر در زبانهای هدف نمایان شوند. برای ترجمههای پیچیدهتر، ممکن است نیاز به بازسازی دستی باشد، به ویژه برای کدهایی که به شدت بهینهسازی ماکرو شدهاند.