lambda функция объясните понятно. - Страница 2
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > lambda функция объясните понятно.

lambda функция объясните понятно.

Ответ
Поиск в этой теме
Непрочитано 21.11.2012, 16:31
lambda функция объясните понятно.
Kirill_Ja
 
Мурманск
Регистрация: 28.07.2008
Сообщений: 208

Функция Lambda очень часто встречается в текстах кодов на форуме. У Николая Полещука в книге описана как функция для того, чтобы прямо в тексте программы определить и тут же выполнить пользовательскую функцию. В документации для разработчиков AutoCad тоже какой-то неочевидный и не очень понятный пример.

В общем как-то так.

Объясните понятно на примере как это и зачем именно определять функцию одноразового применения.
Просмотров: 15734
 
Непрочитано 27.11.2012, 11:50
#21
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


1. Зачем вы создали l_f да еще таким извращенным способом (если она и нужна - можно было через defun).
2. ИХМО vl-remove nil идеологически не правильно (потом так-же будешь обрабатывать списки в которых изначально есть nil - забудешь на 300%), то есть вначале фильрация, потом преобразование (в других лиспах есть дефолтные конструкции делающие это одновременно - но ничего не мешает сделать их для себя в автолиспе) - (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget (car (entsel)))))
3. У тебя возращает не точку, а список значений по оси X.
4. В полилинии (и не только) полученную точку надо еще преобразовать в мировую систему (попробуй свой лисп на полилинии не в плоскости "сверху") - см. функцию (trans...
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 27.11.2012, 15:09
#22
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Если честно по 2. ниче не понял. Скажу проще: вместо того чтоб "занилять" ненужные подсписки, а потом удалять их, можно просто удалять их

Последний раз редактировалось gomer, 27.11.2012 в 15:23.
gomer вне форума  
 
Автор темы   Непрочитано 27.11.2012, 16:05
#23
Kirill_Ja


 
Регистрация: 28.07.2008
Мурманск
Сообщений: 208
<phrase 1=


Про фильтрацию впитал. Лисп в посте #20 подправил.

А почему способ извращенный? Дальше этой переменной присваиваются значения. Собственно, в нее уходит список с координатами.

А этот код можно сделать проще

Код:
[Выделить все]
 

(defun coor ( / )

(setq rec (lambda (name / n_a)
    (progn (setq n_a (entget name))  
       (cond
	 ( (= (cdr(assoc 0 n_a)) "VERTEX")
	   (append (list (assoc 10 n_a)) (apply (function rec) (list (entnext name))))
	); end vertex
          ( (= (cdr(assoc 0 n_a)) "SEQEND") '(nil)); end seqend
        ); end cond
     ); end progn
    );end lambda
  ); end setq

(setq rec (apply (function rec) (list (entnext (car (entsel))))))
(setq rec (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) rec)))
(mapcar (function (lambda (x) (trans x 1 0))) rec)

); end defun


Это уже для 2д/3д полилиний

Сорри за угребищное описание rec. Она большая и к ней не очень удобно обращаться по описанию.

Последний раз редактировалось Kirill_Ja, 27.11.2012 в 16:40.
Kirill_Ja вне форума  
 
Непрочитано 27.11.2012, 18:03
#24
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


сам то понял что написал?
Код:
[Выделить все]
 (defun GET-PLVLIST (EN)
  ((lambda (VLIST DXF) ; вообще эта лямбда тут 100 лет не нужна, но тема такая :)
     (while (/= "SEQEND" (DXF 0 (setq EN (entnext EN))))
       (setq VLIST (append VLIST (list (DXF 10 EN))))
     )
   )
    '()
    (lambda (x y) (cdr (assoc x (entget y))))
  )
)

(GET-PLVLIST (car (entsel)))
gomer вне форума  
 
Автор темы   Непрочитано 27.11.2012, 18:57
#25
Kirill_Ja


 
Регистрация: 28.07.2008
Мурманск
Сообщений: 208
<phrase 1=


Если я пойму как это работает - это будел level up
Kirill_Ja вне форума  
 
Непрочитано 27.11.2012, 20:59
#26
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от gomer Посмотреть сообщение
(append VLIST (list (DXF 10 EN)))
Опять, двадцать пять...
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 27.11.2012, 22:18
#27
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Дима_ Посмотреть сообщение
Опять, двадцать пять...
мопед не мой...
gomer вне форума  
 
Непрочитано 25.12.2012, 09:03
#28
PDM


 
Регистрация: 25.03.2012
Сообщений: 12


Подробно про "lambda" в книге "Мир Лиспа", Э. Хювенен, том 1.
PDM вне форума  
 
Непрочитано 26.12.2012, 14:13
1 | #29
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


В первую очередь извиняюсь - я не смог заставить себя прочесть всю ветку.

теперь по теме:
для многократного использования кода, имеет смысл создать специальную функцию, которая будет выполнять действие, например:

многократное выполнение a + b*2 можно написать программу:
Код:
[Выделить все]
 (defun f (a b) (+ a b b))
теперь в любом месте можно просто вызвать:
Код:
Это очень простой пример, в более сложных вычислениях, определение дополнительного кода в отдельную функцию действительно оправдано.

Но вернемся к lambda функциям. Допустим нам необходимо много раз выполнить подобную функцию, но только для одного списка. Получается определение самостоятельной функции избыточно. На такой случай, есть возможность создания временной функции, которая будет существовать только в рамках используемого места. Для временной функции не будет создаваться имя и как следствие ее нельзя вызвать еще раз. (обычным образом, но обо всем по порядку )

для нашего примера, можно создать вариант с временной функцией:
Код:
[Выделить все]
 ((lambda(a b)(+ a b b)) 5 6)
в этом случае, временная функция однократно выполнит функционал предыдущей функции, но используя lambda определение функции.

пришло время рассказать о списках - именно здесь и кроется все удобство использования lambda:
используем функцию F для обработки списков.
Код:
[Выделить все]
 (mapcar 'f '(1 2 3) '(4 5 6))
в этом коде, функция обработки списка последовательно подставляет в функцию F элементы из первого и второго списков - аргументов, сначала первые, потом вторые итд. т.е сначала выполняется код (f 1 4) потом (f 2 5) ...

В общем случае, использование в mapcar именованных функций, определенных подобно F, очень удобно. Но в случае, когда для каждого mapcar придется писать собственную функцию со своим определением, поддержка такого кода получается не самой удобной. В одном месте создается функция для обработки списка, а совершенно в другом происходит сама обработка. Для таких случаев и создана lambda. Например:
Код:
[Выделить все]
 (mapcar '(lambda(a b)(+ a b b)) '(1 2 3) '(4 5 6))


ps. как и обещал, поясню о сохранении функции lambda. никто не запрещает сохранить саму lambda функцию в переменную для многократного использования:
Код:
[Выделить все]
 (setq foo (lambda(a b)(+ a b b)))
(mapcar 'foo  '(1 2 3) '(4 5 6))
(mapcar 'foo  '(1 2 3) '(0 0 0))
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 26.12.2012, 14:30
#30
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
ps. как и обещал, поясню о сохранении функции lambda. никто не запрещает сохранить саму lambda функцию в переменную для многократного использования:
Если смотреть с точки зрения лиспа, то тут немного верх ногами - defun - это такая обертка сохраняющая функции в текущей области видимости (что в общем-то не всегда нужно).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 26.12.2012, 14:41
#31
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Цитата:
Сообщение от Дима_ Посмотреть сообщение
Если смотреть с точки зрения лиспа, то тут немного верх ногами - defun - это такая обертка сохраняющая функции в текущей области видимости (что в общем-то не всегда нужно).
Вы правы!

Код:
[Выделить все]
 (mapcar (defun f (a b) (+ a b b)) '(1 2 3) '(4 5 6))
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 26.12.2012, 19:43
#32
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Дима_ Посмотреть сообщение
defun - это такая обертка сохраняющая функции в текущей области видимости
Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
(mapcar (defun f (a b) (+ a b b)) '(1 2 3) '(4 5 6))
В данном случае это документ?

Но, особым извращением я считаю форму (lambda nil ... )
gomer вне форума  
 
Непрочитано 27.12.2012, 11:16
#33
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,701
Отправить сообщение для Do$ с помощью Skype™


А почему нет?
Код:
[Выделить все]
(setq sel (vl-catch-all-apply '(lambda nil (entsel "\nВыберите объект:"))))
(if (not (vl-catch-all-error-p sel)) <...>)
Do$ вне форума  
 
Непрочитано 27.12.2012, 11:37
#34
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


nil и '() - это синонимы (можно в любом месте поменять одно на другое - результат не изменится), просто в автолиспе нет как такогого булевского типа (то есть есть, но совмещенно-половинчатый) T или любое значение кроме nil (или '()) и собственно nil - который "по совместительству" пустой список. Кое-где это приносит выгоду:
Код:
[Выделить все]
 (if lst (cons (car lst) ...)
        а здесь ничего не нужно - т.к. вернет пустой список)
то есть мы сэкономили на предикате (null?) проверки и нам не нужно возращать пустой список. Но иногда бывают и излишние сложности когда, например надо что-то отфильровать из "смешанного списка" значений, а там есть как логика так и списки (которые могут быть пустыми). Лично я (для читабельности) использую обозначение nil - там где это подразумеват булевское значение и '() - в случае пустого списка.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 27.12.2012, 11:47
#35
Елпанов Евгений

программист
 
Регистрация: 20.12.2005
Москва
Сообщений: 1,439
Отправить сообщение для Елпанов Евгений с помощью Skype™


Цитата:
Сообщение от Do$ Посмотреть сообщение
(setq sel (vl-catch-all-apply '(lambda nil (entsel "\nВыберите объект:"))))
(if (not (vl-catch-all-error-p sel)) <...>)
ничем не отличается от:
Код:
[Выделить все]
 (if (setq sel (entsel "\nВыберите объект:")) <...>)
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны.
/Сунь Цзы/
Елпанов Евгений вне форума  
 
Непрочитано 27.12.2012, 11:59
#36
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,839


Цитата:
Сообщение от Елпанов Евгений Посмотреть сообщение
ничем не отличается от:
обработает esc...
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 27.12.2012, 16:13
#37
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Do$ Посмотреть сообщение
А почему нет?
в данном случае можно кетчить entsel, а не лямбду, впрочем я ж не против, просто по логике у функции должен быть хотя б один аргумент
gomer вне форума  
 
Непрочитано 27.12.2012, 16:28
#38
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,450


Цитата:
Сообщение от gomer Посмотреть сообщение
по логике у функции должен быть хотя б один аргумент
ИМХО далеко не обязательно
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 27.12.2012, 17:30
#39
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,701
Отправить сообщение для Do$ с помощью Skype™


Цитата:
Сообщение от gomer Посмотреть сообщение
в данном случае можно кетчить entsel, а не лямбду
Ну это простой слишком пример
Вот тут уже не так просто:
Код:
[Выделить все]
(setq pt (vl-catch-all-apply '(lambda nil (initget 1) (getpoint "\nУкажите точку:"))))
В общем-то, это все до боли знакомо, если приходилось использовать функцию
Do$ вне форума  
 
Непрочитано 27.12.2012, 17:39
#40
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Do$ Посмотреть сообщение
Вот тут уже не так просто:
переняся initget на строчку выше, приходим к исходной конструкции
а насчет каскадов ловушек с лямбдами, лучше написать свой нормальный *error*

Последний раз редактировалось gomer, 27.12.2012 в 17:48.
gomer вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > lambda функция объясните понятно.



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Научите лиспу на примере (или как kpblc, VVA и компания пытаются обучить чайника лиспу) Red Nova LISP 5025 20.08.2025 22:52
Выравнивание полилинии в одну линию. f0lk Программирование 50 13.03.2025 14:04
Растягивание Mtext по контуру замкнутой области PlayKid Программирование 7 27.08.2009 13:41
структурированный список Holon Программирование 22 11.09.2007 14:09