|
||
| Правила | Регистрация | Пользователи | Сообщения за день | | Поиск | | Справка по форуму | Файлообменник | |
|
![]() |
Поиск в этой теме |
![]() |
#1 | |
lambda функция объясните понятно.
Мурманск
Регистрация: 28.07.2008
Сообщений: 208
|
||
Просмотров: 15734
|
|
||||
Продуман Регистрация: 22.02.2007
Питер
Сообщений: 2,839
|
Цитата:
Lambda это функция возращающая функцию созданную на основе ее тела. В "классическом" программировании функции (или операторы - в зависимости от семантики языка) обязательно должны иметь какое-то имя, в лиспе оно зачастую не нужно и функцию можно напрямую передавать другой функции (и внутри последней она будет носить имя аргумента), или применить к ней аргументы (то есть выполнить).
__________________
Когда в руках молоток все вокруг кажется гвоздями. |
|||
![]() |
|
||||
1. Для использования в функциях, принимающих в качестве аргумента какую-либо функцию. Пример такой функции - vl-remove-if-not. Мне нужно, например, пройтись по списку из ename блоков и найти в нем блоки с именем "Имя". Стандартной функции, которая одновременно извлекает из ename имя и сверяет с заданной строкой, не существует. Поэтому, я мог бы написать так:
Код:
Код:
Код:
![]() |
||||
![]() |
|
||||
Регистрация: 28.07.2008
Мурманск
Сообщений: 208
![]() |
Первый код я понял. Если по порядку мы задаем Lambda(x) и применяем ее ко всем элементам списка '(1 2 3) При этом Lambda не компилируется.
Потом применяем '+ к списку который получился после применения L к списку исх данных '(1 2 3) Чего-то я второй пример не очень понял ![]() Ладно. Книга мне в помощь. Ушел читать. Если есть еще примеры или можете разобрать второй -> буду благодарен. ![]() |
|||
![]() |
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,450
|
Еще кусок - http://autolisp.ru/2009/09/16/lambda-functions/
Хотя наверняка меня сейчас закидают гнилыми помидорами...
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
|
|||
![]() |
|
||||
Продуман Регистрация: 22.02.2007
Питер
Сообщений: 2,839
|
А строка возращает указатель на строку - нет такого понятия в лиспе - т.к. не нужно, т.к. списки (читай данные программы в том числе) не мутабельны - есть только переопределение.
__________________
Когда в руках молоток все вокруг кажется гвоздями. |
|||
![]() |
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,450
|
Это уже не ко мне, а к автору ответа
![]()
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
Инженер LISP Регистрация: 11.05.2005
Минск
Сообщений: 6,996
|
http://lee-mac.com/mapcarlambda.html
http://ru.wikibooks.org/wiki/Лисп/Функции http://homelisp.ru/help/lisp.html
__________________
Как использовать код на Лиспе читаем здесь |
|||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
Сорри за толстый троллинг, но продолжаем парад планет лямбд, собственно все ссылки хороши, но ничему не учат
Решаем задачку которую не могли решить аж! 90 лет http://hijos.ru/2011/02/27/summa-rya...basel-problem/ Код:
|
|||
![]() |
|
||||
Продуман Регистрация: 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. |
|||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
Цитата:
Впрочем, эта задача слишком тривиальна для лямбд, так как Код:
1. Лямбды применяют как аргумент функций типа mapcar, либо пользовательских 2. Для создания локальных пространств имен возможностью добавления аккумулирующих аргументов |
|||
![]() |
|
||||
Продуман Регистрация: 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...
__________________
Когда в руках молоток все вокруг кажется гвоздями. |
|||
![]() |
|
||||
Регистрация: 28.07.2008
Мурманск
Сообщений: 208
![]() |
Про фильтрацию впитал. Лисп в посте #20 подправил.
А почему способ извращенный? Дальше этой переменной присваиваются значения. Собственно, в нее уходит список с координатами. А этот код можно сделать проще Код:
Это уже для 2д/3д полилиний Сорри за угребищное описание rec. Она большая и к ней не очень удобно обращаться по описанию. Последний раз редактировалось Kirill_Ja, 27.11.2012 в 16:40. |
|||
![]() |
|
||||
В первую очередь извиняюсь - я не смог заставить себя прочесть всю ветку.
теперь по теме: для многократного использования кода, имеет смысл создать специальную функцию, которая будет выполнять действие, например: многократное выполнение a + b*2 можно написать программу: Код:
Код:
Но вернемся к lambda функциям. Допустим нам необходимо много раз выполнить подобную функцию, но только для одного списка. Получается определение самостоятельной функции избыточно. На такой случай, есть возможность создания временной функции, которая будет существовать только в рамках используемого места. Для временной функции не будет создаваться имя и как следствие ее нельзя вызвать еще раз. (обычным образом, но обо всем по порядку ![]() для нашего примера, можно создать вариант с временной функцией: Код:
пришло время рассказать о списках - именно здесь и кроется все удобство использования lambda: используем функцию F для обработки списков. Код:
В общем случае, использование в mapcar именованных функций, определенных подобно F, очень удобно. Но в случае, когда для каждого mapcar придется писать собственную функцию со своим определением, поддержка такого кода получается не самой удобной. В одном месте создается функция для обработки списка, а совершенно в другом происходит сама обработка. Для таких случаев и создана lambda. Например: Код:
ps. как и обещал, поясню о сохранении функции lambda. никто не запрещает сохранить саму lambda функцию в переменную для многократного использования: Код:
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны. /Сунь Цзы/ |
||||
![]() |
|
||||
Продуман Регистрация: 22.02.2007
Питер
Сообщений: 2,839
|
Если смотреть с точки зрения лиспа, то тут немного верх ногами - defun - это такая обертка сохраняющая функции в текущей области видимости (что в общем-то не всегда нужно).
__________________
Когда в руках молоток все вокруг кажется гвоздями. |
|||
![]() |
|
||||
Цитата:
![]() Код:
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны. /Сунь Цзы/ |
||||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
|
|||
![]() |
|
||||
Продуман Регистрация: 22.02.2007
Питер
Сообщений: 2,839
|
nil и '() - это синонимы (можно в любом месте поменять одно на другое - результат не изменится), просто в автолиспе нет как такогого булевского типа (то есть есть, но совмещенно-половинчатый) T или любое значение кроме nil (или '()) и собственно nil - который "по совместительству" пустой список. Кое-где это приносит выгоду:
Код:
__________________
Когда в руках молоток все вокруг кажется гвоздями. |
|||
![]() |
|
||||
Цитата:
Код:
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны. /Сунь Цзы/ |
||||
![]() |
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,450
|
ИМХО далеко не обязательно
![]()
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
Ну это простой слишком пример
![]() Вот тут уже не так просто: Код:
|
||||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
переняся initget на строчку выше, приходим к исходной конструкции
![]() а насчет каскадов ловушек с лямбдами, лучше написать свой нормальный *error* Последний раз редактировалось gomer, 27.12.2012 в 17:48. |
|||
![]() |
|
||||
Thượng Tá Quân Đội Nhân Dân Việt Nam Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372
|
Цитата:
ESC для AutoLISP - "лом, против которого нет приема". А ловушки ошибок действуют наподобие try... except ... end. vl-catch-all-ххх - наилучшая новинка в LISP за последние 10 лет. С их помощью можно предотвратить любую ошибку на любом уровне вложения. |
|||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
Цитата:
ну это логично. Нажимаешь ты отмену, а тебе программа так ехидно Цитата:
К тому же vl-catch-all-apply по барабану на ошибки command, например, при вставке блока |
|||
![]() |
|
||||
Thượng Tá Quân Đội Nhân Dân Việt Nam Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372
|
Цитата:
Цитата:
Цитата:
|
|||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
если для вставки блока нужна точка масштаб и угол поворота, то без них блок вставить нельзя, не выдумывать же, это не правильно, более того, vl-catch-all-apply эту ситуацию не отловит, потому что command своя логика, да и вообще она с command работать не хочет, только с лямбдой
для примера (vl-catch-all-apply '(lambda nil (command "_.insert" "d:\\test" pause 1 1 pause))) - ошибка при нажатии еск во время выбора угла поворота ловится (vl-catch-all-apply '(lambda nil (command "_.insert" "d:\\test" pause))) - ошибка при нажатии еск во время выбора угла поворота не ловится (vl-catch-all-apply 'command (list "_.insert" pause "d:\\test" pause 1 1 pause)) - ; ошибка: неверная порядковая функция: COMMAND так что vl-catch-all-apply - не панацея |
|||
![]() |
|
|||||
Thượng Tá Quân Đội Nhân Dân Việt Nam Регистрация: 14.03.2005
44d32'44"С, 33d26'51"В
Сообщений: 13,372
|
Цитата:
Цитата:
Цитата:
Цитата:
Однако, раз тема про lambda, приведу пример использования как раз в ловушке ошибок. Сначала напишем саму функцию-ловушку. Код:
Как надо вызывать - схема: Код:
Конечно, "простому инженеру" (прикладному программисту), который механизирует свои типовые задачи, наподобие вставок блоков, с этим трудновато разобраться. Для упрощения работы прикладных программистов создаются библиотеки низкоуровневых функций, в которых спрятаны все сложности. А в конкретной программе (функции, конечно), навешиваемой "на кнопку", надо применять простые высокоуровневые функции. Надежные. Чтобы не писали муру наподобие (command "_.insert" "d:\\test" pause 1 1 pause) только потому что так проще. Если уж упомянули блоки, то каждому надо вставлять, например, блоки условных обозначений. Причем надо, чтобы вставка блочишки была многократная, в цикле. Чтобы при этом блок "висел" на курсоре. Чтобы можно было задать поворот или не задавать. Чтобы блок ещё и масштабировался правильно. Чтобы могли быть атрибуты, а могли и не быть. И чтобы это можно было легко применить. Чтобы на уровне меню можно было написать: Сантехнику: (ru-block-insert-from-lib "sanitary\\ru-lib-abok-schem-free-valves-ind" "abok_2_8_05_F-03" 1 1 1 nil)) Топографу: (ru-block-insert-from-lib "land\\ru-lib-topo" "ru_topo_0139" 1 1 1 T)) Строителю: (ru-block-insert-from-lib "common\\ru-lib-common" "number_door_ru" 1 1 1 T)) Здесь применяется библиотечная функция ru-block-insert-from-lib, которая объявлена так (ru-block-insert-from-lib block_lib_name block_name ins_code x_scale y_scale is_angle0) Она делает множественную вставку блока с заданными параметрами из библиотеки блоков. Эту функцию здесь не привожу для экономии места. Она внедряет в чертеж блок из библиотеки, вычисляет масштабы вставки и вызывает низкоуровневую функцию _ru-block-multi-insert-scaled-rotated-or-angleask с подготовленными параметрами. Вот её-то и покажу Код:
|
||||
![]() |
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,450
|
Касательно отлова ошибок - в свое время я пришел в выводу, что *error* лучше не переопределять (причины, в частности, рассматривал тут). Особенно при работе в вертикальных приложениях.
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
Геодезист Регистрация: 16.08.2009
г.Новосибирск
Сообщений: 86
![]() |
Объясните, пожалуйста, как с помощью Lambda получить максимальные и минимальные значения списка, т.е. есть список, например:
Код:
Код:
Код:
|
|||
![]() |
|
||||
Продуман Регистрация: 22.02.2007
Питер
Сообщений: 2,839
|
Ну с помощью голой лямбда наверное никак, тебе непонятно как алгоритм реализовать, или алгоритм понятен но не получается выразить его через лямбда выражения?
__________________
Когда в руках молоток все вокруг кажется гвоздями. |
|||
![]() |
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,450
|
Код:
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
Геодезист Регистрация: 16.08.2009
г.Новосибирск
Сообщений: 86
![]() |
Большое спасибо за варианты. С последним разобрался, а вот с первым….
gomer, правильно ли я понял первый вариант? Все первые элементы подсписков объединяются в один список Код:
Код:
|
|||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
да, собственно первый вариант, проистекает из второго в два действия, важно понять, что точка отсчета функции - содание списка (list), просто mapcar это делает неявно, причем шиворот-навыворот
|
|||
![]() |
|
||||
Программист-энтузиаст Регистрация: 17.07.2009
Воронеж
Сообщений: 575
|
А при чем тут lambda?
На тему Цитата:
__________________
cadtools |
|||
![]() |
|
||||
Геодезист Регистрация: 16.08.2009
г.Новосибирск
Сообщений: 86
![]() |
|
|||
![]() |
|
||||
а я, для поиска минимального списка использую другую конструкцию:
Код:
__________________
Чем гениальнее ваш план, тем меньше людей с ним будут согласны. /Сунь Цзы/ |
||||
![]() |
|
||||
строю, ломаю Регистрация: 03.04.2008
Украина
Сообщений: 5,515
|
Цитата:
|
|||
![]() |
![]() |
|
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Научите лиспу на примере (или как 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 |