При закрытии подписчики были переданы в рассылку "Блогосфера: продвижение сайта и многое другое" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Здравствуйте! В этом выпуске, мы с вами рассмотрим язык программирования LISP. Lisp давно признан одним из великих языков программирования. Фанатики восхищаются им на протяжении всей его истории - уже почти 50 лет. В MIT Lisp играет основную роль в учебных планах всех программистов. Предприниматели (например, Пол Грехэм (Paul Graham)) использовали невероятную производительность Lisp в качестве топлива для успешного начала бизнеса. Но, к огорчению своих последователей, Lisp так и не стал широко распространенным языком. Однако Java™-программист, потратив некоторое время на Lisp, этот затерянный город сокровищ, обнаружит множество технических приемов, которые изменят способ его кодирования к лучшему. В данном выпуске я использую GNU GCL, который можно бесплатно загрузить для многих операционных систем. Но вы можете использовать любую версию Common Lisp с минимальными изменениями. Подробная информация о доступных версиях Lisp приведена в конце выпуска. Начало работы Как и для большинства других языков, лучшим способом изучения Lisp является работа с ним. Откройте интерпретатор и начните кодировать вместе со мной. Lisp – это, в основном, компилируемый язык, поэтому его можно легко исследовать, просто набирая команды. В своей основе Lisp - это язык списков. Все в Lisp, от данных до кода приложения, является списком. Любой список состоит из атомов (элементарных объектов) и списков. Числа являются атомами. Ввод числа просто возвращает это число в качестве результата: Простые атомы >1
Если ввести букву, компилятор выдаст ошибку, как показано в листинге 1. Буквы являются переменными, поэтому необходимо присваивать им значение до использования. Если нужно указать букву или слово, отличное от переменной, используются кавычки. Указание перед переменной апострофа говорит Lisp задержать вычисление списка или атома, который следует за этим апострофом: Задержка вычисления и цитирование
Вывод простого списка
+ , * и sqrt . (+ 1 2 3) возвращает 6 , а (* 1 2 3 4) возвращает 24 .
Списками управляют два типа функций: конструкторы и селекторы. Конструкторы создают списки, а селекторы разбивают их на части. Базовыми селекторами являются
Если нужно создать списки, а не разобрать их на части, необходимы
конструкторы. Как и в языке Java, конструкторы создают новые элементы:
объекты в Java и списки в Lisp. Примерами конструкторов являются
cons
может создать любой список, если использовать его вместе с первым и остальными атомами. Операторы list и append
- это просто удобные атрибуты, но вы будете часто их использовать.
Фактически, можно создать любой список или возвратить любой фрагмент
списка, используя cons , first и rest . Например, для получения второго или третьего элемента списка нужно взять first из rest , или first из rest из rest , как показано в листинге 6. Для создания списка из двух или трех элементов можно использовать cons вместе с first и rest для имитации list и append .
Создание второго элемента, третьего элемента, списка и добавление в список
Объявления Lisp-функций являются, как вы конечно догадались, списками. В листинге, в котором создается функция, возвращающая второй элемент списка, показана форма объявлений функций: Создание функции second
defun - это функция, определяющая пользовательские
функции. Первый аргумент - имя функции, второй - список аргументов, а
третий - код, который вы хотите выполнить. Можно заметить, что весь
Lisp-код - это списки. Такая гибкость и мощь позволяют управлять
приложением так же, как и любыми другими данными. Позднее будут
приведены некоторые примеры, нивелирующие различие между кодом и
данными.
Lisp также обрабатывает такие условные конструкции как выражение
Lisp предоставляет программные структуры для итераций, но рекурсия
является намного более популярным способом навигации по спискам.
Комбинация
total в листинге принимает
список в виде единственного аргумента. Первое выражение if
останавливает рекурсию, если список пуст, возвращая ноль. Если нет,
функция добавляет первый элемент к сумме остальной части списка. Здесь
можно увидеть, почему first и rest сделаны именно такими. first может извлечь первый элемент из списка, а rest облегчает применение концевой рекурсии (tail recursion - тип рекурсии, использованной в листинге) к оставшимся элементам.
Рекурсия в языке Java ограничена по соображениям производительности. Lisp предлагает оптимизацию производительности, называемую оптимизацией концевой рекурсии. Компилятор или интерпретатор Lisp может транслировать определенные формы рекурсии в итерации, предоставляя более простой и понятный способ работы с рекурсивными структурами данных, например, древовидными списками. Lisp становится более интересным при нивелировании различий между данными и кодом. В последних двух статьях данной серии рассматривались функции высокого порядка в JavaScript и замыкания в Ruby. Обе эти функциональные возможности передают функции в виде аргументов. В Lisp функции высокого порядка являются тривиальными, поскольку функции не отличаются от любого другого вида списка. Возможно, самым традиционным применением функций высокого порядка является lambda-выражение, являющееся Lisp-версией замыкания. Функция lambda представляет собой определение функции, использующейся для передачи функций высокого порядка в Lisp-функции. Например, выражение lambda в листинге вычисляет сумму двух целых чисел: Выражения lambda
total . Вторая строка просто отображает функцию lambda, связанную с total . Наконец, последнее выражение применяет функцию lambda к списку, содержащему (101 102) .
Функции высокого порядка предлагают более высокий уровень абстракции, чем объектно-ориентированная концепция. Их можно использовать для выражения идей лаконичнее и понятнее. Святым Граалем программирования является обеспечение больших возможностей и большей гибкости при использовании меньшего количества строк кода, не жертвуя при этом читабельностью или производительностью. Функции высокого порядка делают все это. Возможно, Lisp староват в смысле возраста и даже синтаксиса. Но лишь немного узнав его, можно обнаружить невероятно мощный язык с высокоуровневыми абстракциями, и сегодня являющийся корректным и производительным, также как во время создания 50 лет назад. Многие современные языки программирования позаимствовали некоторые идеи Lisp, а большинство и по сей день не предоставляет такого количества возможностей. Если бы Lisp имел свою долю рынка вне Java или .NET и аналогичную поддержку в университетах, то, возможно, мы бы все сейчас писали именно на нем. Ресурсы
Текст выпуска заимствован у Брюса Тэйта, за что ему огромное спасибо! На этом наш выпуск завершен. Надеюсь он вам понравился! Выпуск получился на редкость содержательным и информативным ))). В следующем выпуске мы поговорим с вами о языке программирования Cobol. До встречи через неделю! |
В избранное | ||