Lisp - енциклопедія мов програмування
Лісп (LISP, від англ. LISt Processing - «обробка списків») - сімейство мов програмування, заснованих на уявленні програми системою лінійних списків символів, які до того ж є основною структурою даних мови. Лисп вважається другим після Fortran найстарішим високорівневим мовою програмування.
Мова Лісп був запропонований Дж. Маккарті в роботі в 1960 році і орієнтований на розробку програм для вирішення завдань не чисельного характеру. Англійська назва цієї мови - LISP є абревіатурою виразу LISt Processing (обробка списків) і добре підкреслює основну область його застосування. Поняття "список" виявилося дуже ємним. У вигляді списків зручно представляти алгебраїчні вирази, графи, елементи кінцевих груп, безлічі, правила виведення і багато інших складні об'єкти. Списки є найбільш гнучкою формою подання інформації в пам'яті комп'ютерів. Тому не дивно, що зручний мову, спеціально призначений для обробки списків, швидко завоював популярність.
Великою перевагою Лиспа є його функціональна спрямованість, т. Е. Програмування ведеться за допомогою функцій. Причому функція розуміється як правило, зіставляє елементам деякого класу відповідні елементи іншого класу. Сам процес зіставлення не робить ніякого впливу на роботу програми, важливий тільки його результат - значення функції. Це дозволяє відносно легко писати і налагоджувати великі програмні комплекси. Ясність програм, чітке розмежування їх функцій, відсутність каверзних побічних ефектів при їх виконанні є обов'язковими вимогами до програмування таких логічно складних завдань, якими є завдання штучного інтелекту. Дисципліна в програмуванні стає особливо важливою, коли над програмою працює не одна людина, а ціла група програмістів.
Мова програмування Лісп призначений в першу чергу для обробки символьної інформації. Тому природно, що в світі Лиспа числа грають далеко не головну роль. Основні типи даних в Ліспі називаються "атом" і "точкова пара".
Елементи синтаксису:
Регулярний вираз ідентифікатора змінної
будь-яка комбінація символів, що не містить пробілів і не є числом
Регулярний вираз ідентифікатора функції
Результат виконання цього коду в інтерактивному режимі має наступний вигляд:
Hello, World!
NIL
Перший рядок містить стандартний потік виведення, друга - значення, що повертається кодом (в даному випадку - його відсутність).
Факторіал:
Цей приклад використовує рекурсивне визначення факторіала, природне для Lisp. Демонструє такі особливості мови:
- математичні оператори: (- n 1) - це префиксная запис, еквівалентна інфіксной записи n-1;
- оператори порівняння: (= n 0) повертає T, якщо n дорівнює нулю, і nil (використовується як false) в іншому випадку;
- умовний оператор if. вираження в Lisp визначаються по дужках і можуть запісиватся в кілька рядків;
- визначення функції з використанням defun;
- макрос Common Lisp loop;
- специфікації формату виведення в format.
D відповідає цілому числу, а
Числа Фібоначчі:
Використовується рекурсивне визначення чисел Фібоначчі. Частина finally макросу loop виконується після кінця циклу.
Числа Фібоначчі:
Цей приклад використовує итеративное визначення чисел Фібоначчі без запам'ятовування, виражене через рекурсивний виклик функції fib-iter.
Факторіал:
Внутрішній цикл з операцією collect створює список чисел від 1 до n. після чого до нього застосовується операція *.
Квадратне рівняння:
Common Lisp дозволяє працювати з комплексними числами і виводити їх на друк у форматі #C (real imag). Функція write-to-string перетворює число в рядок.
CamelCase:
Hello, World !:
Виведення рядка на друк - побічний ефект виконання цієї команди. Залежно від обраної реалізації, команда поверне або виведений текст, або Unspecified return value.
Hello, World !:
Факторіал:
Використовується рекурсивне визначення факторіала. Функція range з одним аргументом генерує список чисел від 0 включно до цього числа виключно. str - функція конкатенації рядків. Функція dec еквівалентна (- x 1). doseq - цикл for в Clojure.
Факторіал:
Для обчислення факторіала числа створюється інтервал чисел від 2 до цього числа, і обчислюється твір цих чисел (функція apply).
Числа Фібоначчі:
Використовується рекурсивне обчислення чисел Фібоначчі.
Факторіал:
Використовується рекурсивне визначення факторіала. Відзначимо, що GNU Guile і MIT / GNU Scheme виводить правильний результат, а в JScheme виникає переповнення, і факторіали з 13! обчислюються неправильно.
Числа Фібоначчі:
Використовується рекурсивне визначення чисел Фібоначчі.
Квадратне рівняння:
Квадратне рівняння:
Конструкція begin використовується для того, щоб виконати кілька команд поспіль.
CamelCase:
У цьому прикладі показана робота з регулярними виразами з модуля regex. Перші два рядки підключають потрібні модулі. Третя - Новомосковскет рядок з вхідних даних командою read-line (модуль rdelim) - на відміну від read. вона Новомосковскет все символи до кінця рядка, а не до першого пробілу - і переводить її в нижній регістр.
Четверта команда знаходить все послідовності букв нижнього регістру в рядку. Для кожної такої послідовності вона замінює її на результат застосування до неї певної функції (прив'язаної за допомогою lambda). В даному випадку це функція string-titlecase. переводить перший символ рядка в верхній регістр.
Нарешті, п'ята команда видаляє з рядка всі символи, які не є буквами.