Zerop lisp что это
LISP. Атом первый
Привет, Хабр!
LISP заинтересовал меня уже давно, но, к сожалению, активно использовать свои знания и стремления на практике шанса не было. Скоро новый учебный год, а значит у меня опять будет возможность изучать и, уже второй год, преподавать студентам LISP. Еще одной проблемой, кроме традиционного отсутствия интереса к сложным вещам, кажется отсутствие литературы. Да и вообще, тема LISP-а в интернете, а тем более в рунете освещена слабо. Вот и на Хабре публикаций довольно мало.
Надеюсь, эта статья понравится общественности и откроет серию, повествующую об одном из наиболее интересных и наименее понятных (хотя до brainfuck и далеко) языков программирования – LISP. Ведь, как это не банально, еще один язык — еще одна жизнь
Начнем с базовых понятий LISP-а – атомов и списков. Немного позже, если будет интересно, в приквеле «Атоме нулевом» можно будет более подробно поговорить о философии и причинах возникновения LISP, а так же о современных направлениях его использования.
Краткая история
LISP был придуман Джоном Маккарти в 1958 году для решения задач нечислового характера и базировался на трех основных китах: алгебре списочных структур, лямбда исчислении, теории рекурсивных функций. Долгое время LISP использовался исключительно узким кругом специалистов по искусственному интеллекту. Но, начиная с 80-х годов прошлого века, LISP начал набирать обороты и сейчас активно используется, например, в AutoCad и Emacs.
Типы данных
Традиционно в LISP рассматривают два типа атомов: символы и числа. Символы могут обозначать числа, строки, сложные структуры, функции и другие объекты. Ограничения на имена символов зависят от используемого диалекта, но большинство из них не накладывает практически никаких ограничений на используемые в именах символы. Кроме того, опять же в большинстве диалектов, имена символов не зависят от регистра.
Некоторые символы имеют специальное назначение – это константы, встроенные функции, T (true, истина) и NIL (false, ложь).
Числа, в отличии от символов, не могут представлять другие объекты, таким образом число всегда является константным числом. Немного позже мы рассмотрим типы чисел в LISP.
Символы и числа представляют собой наиболее простые объекты LISP – атомы. Второй основной тип данных – точечные пары, которые синтаксически выражаются следующим образом:
Например, точечными парами являются выражения:
Атомы и точечные пары объединяют под общим названием S-выражения (S-expression, symbolic expression). Особым видом S-выражения является список, выражаемый следующим образом:
NIL в большинстве случаев определяется как пустой список, в таком случае определение списка можно переписать следующим образом:
Крылья, ноги… Главное хвост
И голова и хвост являются ключевыми понятиями в списочном контексте LISP. Первый элемент списка именуется головой списка, все остальные элементы – хвостом. Для работы с головой и хвостом существует набор базовых функций, рассмотренный немного ниже.
Пустой список эквивалентен паре пустых скобок:
NIL ().
Непустой список, состоящий из элементов a1, a2, a3… в соответствии с правилами записи S-выражений может быть записан следующим образом:
В LISP список можно записать и последовательностью элементов, заключенных в скобки и разделенных пробелами. По большему счету, список – это многоуровневая структура данных, для которой архиважна последовательность открывающих и закрывающих скобок.
Элементами списка могут быть атомы и списки, в том числе и пустой список. Например, () – пустой список, а (NIL) – список, состоящий из одного элемента NIL – что эквивалентно (()).
Следует понимать, что обычный синтаксис S-выражений может использоваться наравне со списочным синтаксисом, например, следующие выражение эквивалентны:
(a.(b.nil)), (a b.nil), (a b nil), (a b)
Если кому-нибудь интересно – можно будет рассказать и о внутреннем представлении списков в памяти. Это вполне самостоятельная и по интересу и по объему тема.
Основные функции и предикаты
В LISP существует довольно небольшой набор примитивных функций, обеспечивающий полноценную возможность обработки списков. В контексте списочных структур данные функции являются аналогом основных арифметических действий и образуют некую систему правил, к которой сводятся абсолютно все символьные вычисления.
Традиционном к базовым функциям относят QUOTE, CAR, CDR, CONS, ATOM, EQ.
Функция QUOTE
Для начала рассмотрим функцию QUOTE, предназначенную для блокирования вычисления выражения. Проще всего работу данной функции продемонстрировать простым примером:
Функцию QUOTE можно записать и короче:
Функция CAR
Предназначена для получения первого элемента точечной пары (или же головы списка). Использование данной функции возможно лишь в списочном контексте, использование для атома приведет к ошибке.
Для удобство головой пустого списка считается NIL.
Фунция CDR
Предназначена для получения второго элемента точечной пары (или же хвоста списка). Использование данной функции возможно лишь в списочном контексте, использование для атома приведет к ошибке.
Хвостом списка является весь список без первого элемента. Если список состоит из одного элемента, хвостом будет NIL. Хвостом пустого списка для удобства так же считается nil.
Несколько примеров:
Функции CAR и CDR реализованы во всех диалектах LISP, но в некоторых для них созданы и синонимы: FIRST и REST, HEAD и TAIL).
Функция CONS
Фактически функция CONS является антиподом функций CAR и CDR:
Функция ATOM
ATOM и EQ являются предикатами – т.е. функциями, проверяющих соответствие аргумента некоторому свойству и возвращающими T или NIL в зависимости от успешности проверки.
Предикат ATOM проверяет, является ли объект, переданный в качестве аргумента, атомом:
atom (S-выражение)
Функция EQ
Предикат, проверяющий идентичность двух символов.
eq (атом, атом)
Следует помнить, что предикат EQ применим лишь к атомарным аргументам и не может быть использован для списков. Так же не следует использовать EQ при сравнении чисел.
Более общим по сравнению с EQ является предикат EQL, позволяющий сравнивать однотипный числа:
Еще более общим для чисел является предикат =, позволяющий сравнивать значения чисел различных типов:
Более общим для списков является предикат EQUAL, позволяющий сравнивать идентичность двух списков:
Наиболее общим предикатом является EQUALP, позволяющий сравнивать произвольные объекты.
Функция NULL
NULL проверяет, является ли объект, переданный в качестве аргумента, пустым списком:
Судя по двум последним примером, можно сделать вывод, что функцию NULL можно использовать и как логическое отрицание. Для этих же целей в LISP существует и предикат NOT.
Что дальше?
Надеюсь, что смог заинтересовать. В следующий раз я планирую рассказать о существующих диалектах LISP (хотя на первых порах достаточно будет университетского XLisp), менее часто используемых базовых функциях, сворачивании CAR и CDR в что-то вроде CAAAADDAAR и определении собственных функций. Позже — рекурсия, управляющие структуры, область действия, ввод-вывод. Еще позже — если не надоем — о функционалах, макросах, свойствах символов и замыканиях. Ну и конечно, о том, о чем попросит общественность.
До встречи!
LISP — Предикаты
Предикаты — это функции, которые проверяют свои аргументы на наличие определенных условий и возвращают nil, если условие ложно, или если какое-либо значение, не равное nil, условие истинно.
В следующей таблице приведены некоторые из наиболее часто используемых предикатов —
Sr.No. | Предикат и описание |
---|---|
1 |
Команда: (vlax-get-acad-object) ; error: no function definition: VLAX-GET-ACAD-OBJECT |
Наберите в командной строке (vl-load-com) или (предпочтительнее) добавьте ее в начало lisp файла.
Теперь ваш lisp должен работать без ошибок.
Данная функция загружает большое количество функций, входящих в расширение AutoLisp, позволяющее работать с объектами, свойствами, методами и событиями ActiveX. Признаком необходимости загрузки расширения AutoLisp является наличие в тексте Вашей программы функций, начинающихся с префиксов vla- (например vla-get-activedocument), vlax- (например vlax-get-acad-object), vl- (например vl-catch-all-apply) и vlr- (например vlr-pers).
В любом случае никогда не помешает добавить (vl-load-com) в начало файла, чтобы избежать подобных ошибок.
Организация библиотеки лисп файлов.
Что делать, если набралось достаточное количество файлов? Каждый раз набирать _appload для загрузки того или иного приложения? Наиболее эффективным будет организация своей библиотеки. Для начала условимся, что все наши файлы будем складывать в одну папку. Например, D:\MyLisp. Пропишем эту папку в путях доступа Автокада. Для этого выбираем Сервис >> Настройка (Tools >> Options) или набираем в командной строке _options. Переходим на закладку Файлы (Files) и раскрываем список Путь доступа к вспомогательным файлам (Support File Search Path).
Мы должны увидеть диалоговое окно, как представлено ниже:
Используйте следующую последовательность, чтобы прописать папку в путях доступа:
Вместо текста мы должны будем подставлять имя нужной нам команды, а вместо текста имя того файла, в котором эта команда сохранена. Напоминаю, что файл должен иметь расширение .lsp. Более подробно по организации меню можно почитать еще здесь http://www.kulichki.com/cadhlp/pdmnu.htm
Автозагрузка файлов.
Если есть необходимость загружать свои lsp файлы при открытии чертежа, то нужно добавить необходимые файлы в список автозаргузки.
Запускаем Автокад и выбираем Сервис >> Автолисп >> Загрузить (Tools >> AutoLISP >> Load) или набираем в командной строке _appload.
В открывшемся диалоговом окне жмем на кнопку Приложения рядом с изображение портфеля
В следующем диалоговом окне жмем на кнопку Добавить и указываем на необходимые файлы.
Они должны появиться в списке приложений.
Теперь перечисленные файлы будут загружаться каждый раз при открытии рисунка.
Важно понимать, что (по крайней мере в полной версии AutoCAD) загрузка приложений, помещенных в Автозагрузку (Startup Suite), как правило, выполняется во все профили и сессии AutoCAD’a.
Кроме того, есть еще один момент. Если существует 2 или более файлов, в которых описаны функции с одинаковыми именами, выполняться будет та, которая загрузилась последней. Поскольку предсказать, в какой последовательности будет выполняться загрузка приложений, невозможно, подобных ситуаций следует избегать.
Автор статьи: Владимир Азарко aka VVA
Предикат zerop к каждому элементу списка
Здравствуйте, опять требуется помощь, буду очень благодарна
Определить рекурсивную функцию, которая применяет предикат ZEROP к каждому элементу списка (список может быть вложенным)
Такой вопрос уже поднимался на форуме и даже есть несколько решений.
Но как сделать так, чтобы функция пропускала символ (a, b, c. ), который может встречаться в списке, а не выдавала ошибку?
Добавление единицы каждому второму элементу списка
Передо мной стоит задач заполнить список и вывести его, при этом каждый второй символ должен быть.
Написать функцию, добавляющую заданное параметром x число к каждому числовому элементу списка.
В lisp не могу разобраться с функционалом, а точнее не могу решить вот эти задачи, с данными.
Функция, которая к каждому элементу уже заданного списка прибавляет число, введенное с клавиатуры
Нужно написать функцию, которая к каждому элементу уже заданного списка прибавляет число, введенное.
Списки. К каждому элементу списка прибавить значение следующего элемента списка. Последний элемент не менять
Данные списка должен ввести пользователь. Результат нужно сформировать в начальном списке, никаких.
Решение
Решение
Решение
Как прочитать содержимое списка (доступ к каждому элементу)
помогите примером как получить каждый элемент списка который на картинке
Добавить к каждому элементу списка его порядковый номер
Добавить к каждому элементу списка его порядковый номер
К каждому отрицательному элементу элементу матрицы прибавить количество положительных элементов в этой матрице
пожалуйста. еду в командировку по работе а надо сделать задачу Даны две матрицы А и В. К каждому.
подсчет по каждому элементу
ТЗ: Подсчитать кол-во животных по каждому виду. (Таблица в приложении). Так вот мой вопрос.
Предикат, переставляющий все отрицательные элементы числового списка в конец списка
Нужна программа, переставляющая все отрицательные элементы числового списка в конец списка.
Обращение к каждому элементу Адаптера
мне неужно обратиться к каждому элементу адаптера и изменить там TextView,но почему то изменяется.
А вы знаете, где сейчас используется Лисп?
Введение
Лисп — второй по старшинству из ныне живых высокоуровневых языков программирования (после Fortran) и первый функциональный язык. Он был разработан в 1958 году и сильно изменился с тех пор, породив множество диалектов и оказав значительное влияние на развитие других языков. На данный момент наиболее известные диалекты: Common Lisp, Scheme, Racket и Clojure.
Слева: Лисп-машина в музее MIT.
Справа: Лисп-машина Symbolics 3640, фото Michael L. Umbricht и Carl R. Friend (Retro-Computing Society of RI)
Лисп стал “первооткрывателем” многих идей, нашедших применение в современных языках программирования: древовидные структуры, динамическая типизация, функции высшего порядка и многое другое. В этом посте мы не будем углубляться во вклад Лиспа в теорию, а сосредоточимся на практической пользе.
Изначально Лисп предназначался для работ в области искусственного интеллекта, в частности как представление математической нотации для символьных вычислений. Но насколько широко диалекты Лиспа используются сейчас и в каких областях применяются?
Мы в Typeable любим и применяем функциональное программирование, а влияние Лиспа на функциональные языки всё ещё сильно, поэтому нам стало интересно разобраться в этом вопросе.
Кто и что пишет на Лиспе?
Во время учёбы мне часто приходилось иметь дело с диалектами Лиспа. Проведя поиск информации при подготовке этой статьи, я была приятно удивлена, когда находила упоминание кода на том или ином диалекте Лиспа в приложениях, которыми пользуюсь сама. Думаю, и вы найдёте знакомые названия в этом списке.
Заключение
Я попыталась включить в список примеры из разных прикладных областей, инструменты для разработчиков, готовые приложения для нетехнических пользователей и системы, входящие в состав того, чем регулярно пользуется довольно большое число людей, даже не задумываясь об этом.
Конечно, это список не полный, здесь выделены наиболее интересные на мой субъективный взгляд применения Лиспа в современном ПО. Более полные списки библиотек, готовых приложений и компаний, использующих диалекты Лиспа, можно посмотреть в следующих ресурсах:
Рассказывайте в комментариях, какие программы на Лиспах используете и делитесь своими pet-проектами!
- Как назывались века в истории
- у какого рэпера упал сын с окна