Форум программистов, компьютерный форум, киберфорум
Lisp
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
3 / 3 / 1
Регистрация: 21.10.2015
Сообщений: 92
1

Синтаксис Lisp

30.11.2015, 01:06. Показов 1077. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте! Помогите пожалуйста разобраться.
Lisp
1
2
(defun f (mylist)
    (or (apply #'>= mylist) (apply #'<= mylist))
Мне не совсем понятен код. В частности использование диез и апострофа.

Добавлено через 52 минуты
Хотя, здесь же на просторах форума был найден ответ...
Google Common Lisp Style Guide

Цитата Сообщение от _sg Посмотреть сообщение
полезный текст, например - иногда расставляемая на этом форуме ловушка:
#'FUN vs. 'FUN
link ▽ You should usually refer to a function as #'FUN rather than 'FUN.
The former, which reads as (FUNCTION FUN), refers to the function object, and is lexically scoped. The latter, which reads as (QUOTE FUN), refers to the symbol, which when called uses the global FDEFINITION of the symbol.
When using functions that take a functional argument (e.g., MAPCAR, APPLY, :TEST and :KEY arguments), you should use the #' to refer to the function, not just single quote.
An exception is when you explicitly want dynamic linking, because you anticipate that the global function binding will be updated.
Another exception is when you explicitly want to access a global function binding, and avoid a possible shadowing lexical binding. This shouldn't happen often, as it is usually a bad idea to shadow a function when you will want to use the shadowed function; just use a different name for the lexical function.
You must consistently use either #'(lambda ...) or (lambda ...) without #' everywhere. Unlike the case of #'symbol vs 'symbol, it is only a syntactic difference with no semantic impact, except that the former works on Genera and the latter doesn't. You must use the former style if your code is intended as a library with maximal compatibility to all Common Lisp implementations; otherwise, it is optional which style you use. #' may be seen as a hint that you're introducing a function in expression context; but the lambda itself is usually sufficient hint, and concision is good. Choose wisely, but above all, consistently with yourself and other developers, within a same file, package, system, project, etc.
Note that if you start writing a new system in a heavily functional style, you may consider using lambda-reader, a system that lets you use the unicode character λ instead of LAMBDA. But you must not start using such a syntactic extension in an existing system without getting permission from other developers.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.11.2015, 01:06
Ответы с готовыми решениями:

Помогите пожалуйста переделать синтаксис MuLisp в Comon Lisp (обращение списка)
Добрый вечер! Помогите пожалуйста переделать синтаксис MuLisp в Comon Lisp 1. Определить...

Помогите пожалуйста переделать синтаксис MuLisp в Comon Lisp (является ли список атомарным)
Помогите пожалуйста переделать синтаксис MuLisp в Comon Lisp 3. Определить функции, которые...

Помогите пожалуйста переделать синтаксис MuLisp в Comon Lisp (проверка длины списка)
Помогите пожалуйста переделать синтаксис MuLisp в Comon Lisp 2. Определить функции, которые...

Книги или другой источник, где описана история версий Lisp и Common Lisp
Доброго времени суток.Такой вопрос,знаете какой-нибудь источник,где описана история версий Lisp и...

7
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
30.11.2015, 01:51 2
Обычно код на лиспе состоит из многоуровневых списков. Эти списки «вычисляются». Первый символ списка задаёт правило вычисления. Например, если первый символ — имя функции, правило такое: вычислить все последующие элементы списка и применить к ним функцию как к аргументам.

А если первый символ — defun, правило другое: если упрощённо (то есть немного соврать), то второй элемент должен быть символом, который не вычисляется и будет служить глобальным именем функции, третий элемент — список аргументов, а остальные элементы — формы, которые задают тело определяемой функции; основным результатом вычисления defun-списка является побочный эффект: создание глобальной функции с заданным именем.

Если первым списком является let, то предполагается, что второй элемент является перечнем локальных переменных, и последующие элементы вычисляются с учётом этих переменных.

И так далее. Более того, программист может определять собственные правила вычисления списков. Это значит, что программист может создавать новый синтаксис.

Цитата Сообщение от Virviglaz Посмотреть сообщение
В частности использование диез и апострофа.
Это отдельный вопрос. В лиспе есть несколько пространств имён. Особо важно понимать, что есть отдельное пространство имён для переменных и для функций.

Я напишу неформально, то есть не в терминах стандарта.

В качестве имён обычно выступают символы. Разные пространства имён обозначают, что в зависимости от контекста символ можен интерпретироваться или как переменная, или как имя функции (или как метка, например). Надо понимать, что есть такие объекты под названием функция, они могут иметь имя и могут быть значениями переменных.

При дефолтном вычислении списка символ интерпретируется как имя функции только в головной позиции списка. Но иногда мы хотим «достать» саму функцию, имя которой мы знаем — чтобы её как-то использовать. Это делается с помощью специального оператора function. Например, (function <=) — это функция (кусок кода) с именем <=, а (function sin) — функция вычисления синуса. Запись с #' является сокращённой формой того же самого: #'<= есть ровно то же, что (function <=). (#' — это так называемый макрос чтения, который ещё во время чтения файла заменит #'<= на (function <=)).

Функция apply в простейшем случае принимает два аргумента: функцию и список, и вычисляет функцию с аргументами, содержащимися в списке. Поэтому вы пишете (apply #'<= mylist) — здесь на втором месте, как было сказано, стоит сама функция «меньше или равно». Если написать (apply <= mylist), символ <= будет интерпретироваться как переменная, и если вы не заводили такой переменной, будет ошибка.
4
3 / 3 / 1
Регистрация: 21.10.2015
Сообщений: 92
30.11.2015, 02:15  [ТС] 3
helter
Ого! спасибо большое)
0
4820 / 2286 / 287
Регистрация: 01.03.2013
Сообщений: 5,970
Записей в блоге: 29
30.11.2015, 02:40 4
А если это Лисп-1 с общим пространством имен, да еще и с автоцитированием, то будет работать и так:
Lisp
1
2
3
4
(defmacro apply (foo args) (eval (cons foo args)))
 
(defn f (mylist) (or (apply '>= mylist) (apply '<= mylist)))
(defn g (mylist) (or (apply >= mylist) (apply <= mylist)))
1
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
30.11.2015, 02:51 5
Цитата Сообщение от Virviglaz Посмотреть сообщение
Хотя, здесь же на просторах форума был найден ответ...
Это не совсем то.

Например, mapcar применяет функцию к элементам списка:
Lisp
1
2
> (mapcar #'char-upcase '(#\a #\b #\c))
(#\A #\B #\C)
Здесь всё понятно: char-upcase — имя стандартной функции, #'char-upcase — сама стандартная функция, она применяется к элементам. Однако вот так тоже работает:
Lisp
1
2
> (mapcar 'char-upcase '(#\a #\b #\c))
(#\A #\B #\C)
Хотя на первый взгляд абсурд: 'char-upcase, то есть (quote char-upcase) — это сам символ char-upcase. Как функцию применять к элементам списка, ясно, а символ как применять? На самом деле здесь речь об особенности функции mapcar, которая вместо функции позволяет давать символ-имя функции. В процитированном куске написано, почему это работает, и что этим не надо злоупотреблять. Это тонкость, которую начинающим можно игнорировать.
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
37295 / 20729 / 4272
Регистрация: 12.02.2012
Сообщений: 34,116
Записей в блоге: 14
30.11.2015, 09:54 6
Цитата Сообщение от helter Посмотреть сообщение
и если вы не заводили такой переменной, будет ошибка.
- если заводили - тоже. Но в другом месте.

Когда использовать решетку? Вот примеры:

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CL-USER 1 > (mapcar 'list '(1 2 3))
((1) (2) (3))
 
CL-USER 2 > (mapcar #'list '(1 2 3))
((1) (2) (3))
 
;; Как видим - одно и то же
 
CL-USER 3 > (mapcar '(lambda (x) (* x x)) '(1 2 3))
 
Error: Argument to apply/funcall is not a function: (LAMBDA (X) (* X X)).
 
;; ошибка - лямбда не воспринимается как функц. выражение
 
CL-USER 4 : 1 > (mapcar #'(lambda (x) (* x x)) '(1 2 3))
(1 4 9)
 
;; а так -  правильно
1
4527 / 3521 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
30.11.2015, 16:42 7
Цитата Сообщение от Catstail Посмотреть сообщение
- если заводили - тоже. Но в другом месте.
Да вроде нет, откуда бы.

Решётка с лямбдой - особый разговор. Не вникая в детали, можно сказать так: её можно писать, а можно не писать, исключительно вопрос вкуса. Исключение: на первом месте списка её нельзя писать. Впрочем, на первое место списка лямбда залезает нечасто. Получается:
Lisp
1
2
3
4
5
6
(mapcar (lambda (x)
          (* x x))
        '(1 2 3))
(mapcar #'(lambda (x)
            (* x x))
        '(1 2 3))
работают одинаково хорошо,
Lisp
1
2
3
((lambda (x)
   (* x x))
 2)
работает,
Lisp
1
2
3
(#'(lambda (x)
     (* x x))
 2)
не работает.
1
Модератор
Эксперт функциональных языков программированияЭксперт Python
37295 / 20729 / 4272
Регистрация: 12.02.2012
Сообщений: 34,116
Записей в блоге: 14
30.11.2015, 16:48 8
Цитата Сообщение от helter Посмотреть сообщение
Да вроде нет, откуда бы.
- я имел в виду случай присвоения не функционального значения. Ошибка будет в том же месте (тут я неправ):

Lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CL-USER 1 > (setf z 6)
6
 
CL-USER 2 > (mapcar z '(1 2 3))
 
Error: Argument to apply/funcall is not a function: 6.
 
CL-USER 5 : 1 > (defun f (x) (* x x))
F
 
CL-USER 6 : 1 > (setf z 'f)
F
 
CL-USER 7 : 1 > (mapcar z '(1 2 3))
(1 4 9)
1
30.11.2015, 16:48
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.11.2015, 16:48
Помогаю со студенческими работами здесь

Организация циклов в Lisp (bee lisp demo)
разбираюсь с простыми задачами, эти пока не знаю, как решать... помогите пожалуйста. 1. Слова в...

Парсер lisp на lisp
Здравствуйте! Решил написать компилятор racket (диалект lisp) на racket, для того, чтобы легко...

PC-Lisp v.3.00
Как загрузить файл (исходный код программы) в PC-lisp?

lisp
Необходимо решить задания из текстового документа. Буду очень благодарен.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru