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

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

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

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

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

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

Объясните понятно на примере как это и зачем именно определять функцию одноразового применения.
Просмотров: 15734
 
Старый 21.11.2012, 17:03
#2
gomer

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


Код:
[Выделить все]
 (type (lambda (x) (/ 1. (* x x)))) 
(apply '+ (mapcar '(lambda (x) (/ 1. (* x x))) '(1 2 3)))
;; (1/1^2) + (1/2^2) + (1/3^2) сумма обратных квадратов
или так
Код:
[Выделить все]
 ((lambda (f lst)
   (apply (function +) (mapcar (function f) lst))
 )
  (lambda (x) (/ 1. (* x x)))
  '(1 2 3)
)

Последний раз редактировалось gomer, 21.11.2012 в 17:19. Причина: коряво получилось
gomer вне форума  
 
Старый 21.11.2012, 17:13
#3
Дима_

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


Цитата:
Сообщение от Kirill_Ja Посмотреть сообщение
У Николая Полещука в книге описана как функция для того, чтобы прямо в тексте программы определить и тут же выполнить пользовательскую функцию.
Не знаю не читал, но насчет "тут же выполнить" кто-то из Вас или ошибся, или не так понял.
Lambda это функция возращающая функцию созданную на основе ее тела. В "классическом" программировании функции (или операторы - в зависимости от семантики языка) обязательно должны иметь какое-то имя, в лиспе оно зачастую не нужно и функцию можно напрямую передавать другой функции (и внутри последней она будет носить имя аргумента), или применить к ней аргументы (то есть выполнить).
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Старый 21.11.2012, 17:28
#4
Do$

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


1. Для использования в функциях, принимающих в качестве аргумента какую-либо функцию. Пример такой функции - vl-remove-if-not. Мне нужно, например, пройтись по списку из ename блоков и найти в нем блоки с именем "Имя". Стандартной функции, которая одновременно извлекает из ename имя и сверяет с заданной строкой, не существует. Поэтому, я мог бы написать так:
Код:
[Выделить все]
(defun get-name-and-wcmatch (ent / name) (and (setq name (cdr (assoc 2 (entget ent)))) (= name "Имя")))
(vl-remove-if-not (function get-name-and-wcmatch) <тут ename-список>)
Но мне в дальнейшем моя функция get-name-and-wcmatch нигде не понадобится, поэтому мне бессмысленно ее запоминать. Проще "впихнуть" все в одно выражение, тут уже не обойтись без лямбды:
Код:
[Выделить все]
(vl-remove-if-not (function (lambda (ent / name) (and (setq name (cdr (assoc 2 (entget ent)))) (= name "Имя")))) <тут ename-список>)
2. Я частенько лямбду использую для отделения функциональных кусков кода, чтобы можно было "на месте" задать локальные переменные, а не тащить их к самому верхнему списку переменных:
Код:
[Выделить все]
(defun <программа> (<тут могут быть агрументы> / <основной список локальных переменных>)
<тут какой-то код>
((lambda (<тут могут быть аргументы> / <локальные переменные участка кода>) <участок кода>) <тут могут вычисляться/задаваться аргументы>)
<и тут какой-то код>
)
Надеюсь, что можно понять начинающему то, о чем я тут написал
Do$ вне форума  
 
Автор темы   Старый 21.11.2012, 17:29
#5
Kirill_Ja


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


Первый код я понял. Если по порядку мы задаем Lambda(x) и применяем ее ко всем элементам списка '(1 2 3) При этом Lambda не компилируется.
Потом применяем '+ к списку который получился после применения L к списку исх данных '(1 2 3)


Чего-то я второй пример не очень понял

Ладно. Книга мне в помощь. Ушел читать. Если есть еще примеры или можете разобрать второй -> буду благодарен.
Kirill_Ja вне форума  
 
Старый 21.11.2012, 17:43
#6
Кулик Алексей aka kpblc
Moderator

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


Еще кусок - http://autolisp.ru/2009/09/16/lambda-functions/
Хотя наверняка меня сейчас закидают гнилыми помидорами...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Старый 21.11.2012, 17:55
#7
gomer

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


Цитата:
Сообщение от Дима_ Посмотреть сообщение
Lambda это функция возращающая функцию
Код:
[Выделить все]
 (eq (type <=) (type (lambda (*) (*))))
добавим немного эротики... то, что возвращает лямбда больше похоже на указатель на пользовательскую функцию
>Кулик Алексей aka kpblc, не SUBR, а USUBR
gomer вне форума  
 
Старый 21.11.2012, 18:02
#8
Дима_

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


А строка возращает указатель на строку - нет такого понятия в лиспе - т.к. не нужно, т.к. списки (читай данные программы в том числе) не мутабельны - есть только переопределение.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Старый 21.11.2012, 18:09
#9
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от gomer Посмотреть сообщение
>Кулик Алексей aka kpblc, не SUBR, а USUBR
Это уже не ко мне, а к автору ответа ))
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Старый 21.11.2012, 18:21
#10
gomer

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


ну тады продолжаем усугублять

Цитата:
Сообщение от Kirill_Ja Посмотреть сообщение
Чего-то я второй пример не очень понял
Это примерно то ж, что и
Код:
[Выделить все]
 (apply
  (quote (lambda (f lst)
	   (apply (function +) (mapcar (function f) lst))
	 )
  )
  (list
    (lambda (x) (/ 1. (* x x)))
    '(1 2 3)
  )
)
что, в свою очередь как бы
Код:
[Выделить все]
 
(setq foo (lambda (f lst)
	    (apply (function +) (mapcar (function f) lst))
	  )
)


(foo (lambda (x) (/ 1. (* x x)))
     '(1 2 3)
)
gomer вне форума  
 
Старый 21.11.2012, 23:23
#11
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


http://lee-mac.com/mapcarlambda.html
http://ru.wikibooks.org/wiki/Лисп/Функции
http://homelisp.ru/help/lisp.html
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Старый 22.11.2012, 01:24
#12
gomer

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


Сорри за толстый троллинг, но продолжаем парад планет лямбд, собственно все ссылки хороши, но ничему не учат
Решаем задачку которую не могли решить аж! 90 лет http://hijos.ru/2011/02/27/summa-rya...basel-problem/
Код:
[Выделить все]
 (equal
  ;; Базельская задачка
  (/ (* pi pi) 6)			; вот чему равна вся эта хрень внизу

  ((lambda (f lst)			; применяем лямбду как функцию
     (apply (function +) (mapcar (function f) lst))
   )
    (lambda (x) (/ 1. (* x x)))		; применяем лямбду как аргумент функции
    ((lambda (x)
       ;; создаем рекурсивно список натуральных
       ;; чисел от 1 до 10000 с помощью лямбды 
       ((lambda	(f-rec)
	  ;; тут вообще все мрак и вверх тормашками задом наперед
	  (f-rec 1 x)
	)
	 (lambda (i n)
	   (if (<= i n)
	     (cons i
		   (f-rec (1+ i) n)
	     )
	   )
	 )
       )
     )
      10000
    )
  )

  0.0001

)

(equal
  ;;  Без всяких лямбд и рекурсий получаем точность на порядки выше.  Собственно
  ;; это  проблема не лямбды,  а рекурсии,  хотя итерационный метод  имеет свои
  ;; ограничения.
  (/ (* pi pi) 6)
  (progn
    (setq i 0
	  sum 0
    )
    (while (<= i 10e6)
      (setq i	(1+ i)
	    sum	(+ sum (/ 1. (* (float i) (float i))))

      )
    )
  )
  10e-6
)
точнее не решаем, а проверяем
gomer вне форума  
 
Автор темы   Старый 22.11.2012, 08:58
#13
Kirill_Ja


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


Очень хорошо))) Через Ваш парад уже кое-что понятно. Еще вопрос.
Функция (function). В книге тоже не очень понятно про нее написано. И, судя по примерам, одно без другого не бывает)
Kirill_Ja вне форума  
 
Старый 22.11.2012, 09:16
#14
gomer

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


Читайте справку хоть иногда, там же все понятно написано
gomer вне форума  
 
Старый 22.11.2012, 09:26
#15
Дима_

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


То gomer - перестарался с лямбдами - f и lst вобще не нужны (зачем их именовать если они применяется 1 раз в mapcar'е):
Код:
[Выделить все]
 (defun basel()
  ((lambda (ml) (apply '+ (mapcar '(lambda (x) (/ 1.0 (* x x))) (ml 1000))))
   (lambda (x) (if (not (zerop x)) (cons x (ml (1- x)))))))
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Автор темы   Старый 22.11.2012, 09:32
#16
Kirill_Ja


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


Все. Понял. Справка великая весчь.

Попробую сам сваять.

Последний раз редактировалось Kirill_Ja, 22.11.2012 в 09:42.
Kirill_Ja вне форума  
 
Старый 22.11.2012, 09:38
#17
Дима_

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


Примерно так.
Если углубляться то здесь вобще история долгая, в лиспе можно передать функцию как функцию (что по умолчанию используют например в Scheme) или как тело (простое или скомпилированное) - проще говоря список символов - что по умолчанию идет в AutoLisp, CommonLisp... В чем разница? в том что с ней предполагается делать. В Scheme предпологается использование т.н. лексических замыканий (то есть если какое-либо имя используется внутри функции - оно берется на момент ОПРЕДЕЛЕНИЯ это функции), а в автолиспе по барабану что там за имена - к ним обращаются только на момент выполнения - то есть в "голом" виде:
(defun x() (+ a b)) - в автолиспе вполне себе нормальная функция, но запустить (без фатальной ошибки) ее можно только при условии что "внешне" определенны a и b и их можно сложить между собой. В Sheme подобная конструкция не примется на этапе ввода - т.к. при сохранении функции ему необходимо "знать" a и b - если знакомы с ООП - то функция это типа объект, а a и b своего рода "приватные" свойства. Из-за этого в AutoLispe переодически возникает необходимость "обработать" список функции перед выполнением (хотя эта необходимость возникает при использовании определенного стиля программирования, что в общем случае не часто - а чаще используется передача аргументов, а еще чаще (и не правильней) установка "внешних переменных" (точнее говорить переопределение внешних имен), но, в определенных задачах, дает существенные выйгрыши).
p.s. Kirill_Ja не переправляй целиком посты - а то уже не ясно к чему этот - он посвящен quote и function.
__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 22.11.2012 в 10:15.
Дима_ вне форума  
 
Старый 22.11.2012, 18:05
#18
gomer

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


Цитата:
Сообщение от Дима_ Посмотреть сообщение
перестарался с лямбдами - f и lst вобще не нужны (зачем их именовать если они применяется 1 раз в mapcar'е):
для наглядности и вообще, я так старался так старался, такие лямбдочки получились красивенькие а Вы...
Впрочем, эта задача слишком тривиальна для лямбд, так как
Код:
[Выделить все]
 (defun basel (n)
  (if (zerop n)
    0
    (+ (expt n -2.) (basel (1- n)))
  )
)
Собственно как итог:
1. Лямбды применяют как аргумент функций типа mapcar, либо пользовательских
2. Для создания локальных пространств имен возможностью добавления аккумулирующих аргументов
gomer вне форума  
 
Старый 22.11.2012, 18:44
#19
Klo

Инженер-конструктор
 
Регистрация: 29.10.2007
Юбилейный МО
Сообщений: 269


Раз уж у автора есть книжка Полещука (надеюсь AutiLISP в среде AutoCAD), то неплохо бы потрудиться заглянуть на стр. 80 есть понятный пример:
Код:
[Выделить все]
 (vl-sort '((3.2 -1.1) (5.9 6.0) (1.9 1.3)) (function (lambda (e1 e2) (> (car e1) (car e2)))))
Klo вне форума  
 
Автор темы   Старый 27.11.2012, 10:27
#20
Kirill_Ja


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


Свой пример и моя благодарность, что объяснили.

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

(setq l_f (lambda (qqq) (if (= (car qqq) 10) (cdr qqq))))
(vl-remove nil (mapcar (function l_f) (entget (car (entsel)))))

Выдает базовую точку для объектов и список вершин для LWPolyline

Последний раз редактировалось Kirill_Ja, 27.11.2012 в 15:54.
Kirill_Ja вне форума  
Ответ
Вернуться   Форум 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