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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > AutoLISP: Просачивание локальных переменных в тело используемых в выражении функций

AutoLISP: Просачивание локальных переменных в тело используемых в выражении функций

Ответ
Поиск в этой теме
Непрочитано 25.10.2010, 20:26 #1
AutoLISP: Просачивание локальных переменных в тело используемых в выражении функций
Supermax
 
Руководитель фирмы
 
Москва
Регистрация: 28.03.2007
Сообщений: 1,831

Или я плохо читал книги по Автолиспу, или у меня глюки:

Случайно создал функцию, где напутал с именем локальной переменной

Код:
[Выделить все]
(defun proba (ss) (* x 2))
Видите, аргумент определен как переменная ss, а в формуле стоит не ss, а x.

Беру такое выражение:
Код:
[Выделить все]
(mapcar '(lambda (x) (vl-catch-all-apply  'proba (list x))) '(2 3 4))
и работает!

Каким-то макаром этот X "спустился" в тело функции через ее аргумент, хотя тот назван совсем иначе.

Кстати сказать
Код:
[Выделить все]
(defun proba (ss) (* ss 2))
так тоже работает.

Я очень часто использую локальное определение аргумента одной буквой, вот теперь призадумался.

Может кто знает более подробно про такие пироги?
Просмотров: 4414
 
Непрочитано 25.10.2010, 20:31
#2
Кулик Алексей aka kpblc
Moderator

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


Ты с областью видимости определись:
Код:
[Выделить все]
_$ (setq a 2)
2
_$ (defun test( / a) (setq a "qwert") (princ (strcat "\n" (vl-princ-to-string a))))
TEST
_$ (test)

qwert"\nqwert"
_$
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.10.2010, 20:46
#3
TararykovDG

Программист-энтузиаст
 
Регистрация: 17.07.2009
Воронеж
Сообщений: 571


Supermax, я тоже не очень понял, что Вас удивляет. Так Вы написали
(lambda(x) ...), то для (defun proba (ss) (* x 2)) которое вызывается через (vl-catch-all-apply 'proba (list x)) x - уже как бы "глобальная" переменная. Напишите так (defun proba (ss) (* y 2)) и Вы получите:
Код:
[Выделить все]
(defun proba (ss) (* y 2))
_$ (mapcar '(lambda (x) (vl-catch-all-apply  'proba (list x))) '(2 3 4))
(#<%catch-all-apply-error%> #<%catch-all-apply-error%> #<%catch-all-apply-error%>)
Я так понимаю, может что напутал, так поправьте
__________________
cadtools
TararykovDG вне форума  
 
Автор темы   Непрочитано 25.10.2010, 20:50
#4
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Offtop: Привет! Ты что, с мобильника пишешь в тему? Что это за кракозябры в строках?

Как ты заметил (если заметил) я нигде setq не использовал. Я вообще ни разу, ни одной переменной не создал (в смысле глобальной).

Так что с видимостью у меня все в порядке.
Я создал при определении функции ее аргумент, а в теле самой функции мои выражения начинают разговаривать с внешними переменными.
Если бы не этот аргумент (я его пробовал удалять) внутрь ничего не попадает. Только с его присутствием этот x в теле пашет. Или это что-то другое. Никак не пойму что происходит.
Supermax вне форума  
 
Непрочитано 25.10.2010, 20:53
#5
Кулик Алексей aka kpblc
Moderator

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


Хоссспидяяяя.... Ну сделай полноценную функцию, внутрь mapcar'a воткни точку останова и посмотри, чего чему равно.
Вот тебе код для отладки:
Код:
[Выделить все]
(defun proba (ss)
  (* x 2)
  ) ;_ end of defun

(defun test ()
  (mapcar
    (function
      (lambda (x)
        (vl-catch-all-apply
          (function
            (lambda ()
              (proba x)
              ) ;_ end of lambda
            ) ;_ end of function
          ) ;_ end of vl-catch-all-apply
        ) ;_ end of lambda
      ) ;_ end of function
    '(2 3 4)
    ) ;_ end of mapcar
  ) ;_ end of defun
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.10.2010, 20:55
#6
Li6-D


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


Локальная переменная x лямбда-выражения является глобальной для функции proba. И во втором выражении вместо (list x) можно подставить любой список с одним элементом, например так:
Код:
[Выделить все]
(mapcar '(lambda (x) (vl-catch-all-apply  'proba '(любой_список))) '(2 3 4))
PS Хммм уже ответили....
Li6-D вне форума  
 
Непрочитано 25.10.2010, 21:04
#7
gomer

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


Это есть все не карашоу Ущербный какой-то стиль программирования
gomer вне форума  
 
Непрочитано 25.10.2010, 21:17
#8
Кулик Алексей aka kpblc
Moderator

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


gomer, ты к кому обращался? Хоть аргументируй, что ли...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.10.2010, 21:37
#9
gomer

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


Это напоминает мне ситуацию, когда есть ГЛАВНАЯ функция/команда с кучей непонятных аргументов, а в ней куча маленьких подфункций которые используют эти переменные (для них (функций) эти переменные глобальны) Например, Прокат В.Кондрата... Все работает, вроде, но разобраться как... очень сложно...
Для меня глобальная переменная - это та которая хранит данные в течение сеанса работы с документом... все остальное - параметры функций... Локальные переменные я использую для уменьшения длины кода, при пользовательском вводе и в циклах при работе с коллекциями... другие функции в теле использую или без аргументов или с аргументами в качестве местных локальных и т.д. т.е. оперирую только локальными данными...
gomer вне форума  
 
Автор темы   Непрочитано 25.10.2010, 21:58
#10
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Во, блин! А че я раньше-то парился?

Li6-D, ты прав на все 100.

Код:
[Выделить все]
(defun proba () (* y 3 (* x 2)))
(mapcar '(lambda (x y) (proba)) '(2 3 4) '(5 6 7))
и все работает. А я раньше аргументами впихивал вниз верхние переменные, вот дурень...

От сюда вывод: Какой? - А вот такой!

"Не упоминай в суе имя господа твоего!" (в смысле имена переменных определенных как локальные, но в вышестоящей инстанции)

Или вот такой пример:
Код:
[Выделить все]
(defun proba () (* ss 3 (* nn 2)))

(defun proba2 (ss nn ) (proba))

(proba2 2 5)
Возвращает 60.

Последний раз редактировалось Supermax, 25.10.2010 в 22:18.
Supermax вне форума  
 
Непрочитано 25.10.2010, 22:20
#11
gomer

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


Supermax, только не делайте так при расчете конструкций, а то ведь рухнуть может
gomer вне форума  
 
Непрочитано 25.10.2010, 22:26
#12
Li6-D


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


Цитата:
Сообщение от gomer Посмотреть сообщение
Это напоминает мне ситуацию, когда есть ГЛАВНАЯ функция/команда с кучей непонятных аргументов, а в ней куча маленьких подфункций которые используют эти переменные (для них (функций) эти переменные глобальны) Например, Прокат В.Кондрата... Все работает, вроде, но разобраться как... очень сложно...
Чем плоха глобальная переменная в подфункциях? По моему, это не всегда является ущербным стилем программирования. Глобальную переменную определил один раз в главной функции (для нее она может быть и локальной) и дальше в подфункциях, где переменная используется, ее уже не надо определять заново или передавать подфункции как аргумент.
Выигрываем в скорости вычислений и размере кода, проигрываем в читаемости и универсальности. Конечно автор может сделать доброе дело и написать в комментариях к подфункции какие глобальные переменные она использует и какие создает. Прежде всего, чтобы самому не запутаться...

Последний раз редактировалось Li6-D, 25.10.2010 в 22:42.
Li6-D вне форума  
 
Автор темы   Непрочитано 25.10.2010, 22:37
#13
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Это не есть хорошо. Тут я с gomer-ом полностью согласен. Что же это получается? Я взял чужую библиотеку функций (допустим даже скомпилированную) и использую их в качестве подфункций в своих функциях, так мне надо чтобы я обозначал свои переменные совсем не так как они обозначены в этих подфункциях. Они ж мне весь Марлезонский балет могут испортить.

Есть такой милый способ временного хранения, сначала создавать переменную, а потом ее убивать. А если ее имя совпадает с глобальной переменной? Ай-яй-яй.
Supermax вне форума  
 
Непрочитано 25.10.2010, 22:53
#14
Кулик Алексей aka kpblc
Moderator

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


Мораль сей басня очень прост: сначала надо разобраться с вызовом и областью видимости переменных.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.10.2010, 23:09
#15
gomer

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


Переменные - зло, по определению... Функции не должны зависеть от переменных... они должны зависеть от аргументов...
gomer вне форума  
 
Непрочитано 25.10.2010, 23:10
#16
Кулик Алексей aka kpblc
Moderator

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


gomer, я понял, что ты сказал что-то очень умное... Я понял, что я что-то не понял, но что конкретно я не понял, я не понял
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 25.10.2010, 23:10
#17
Li6-D


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


Цитата:
Сообщение от Supermax Посмотреть сообщение
Это не есть хорошо. Тут я с gomer-ом полностью согласен. Что же это получается? Я взял чужую библиотеку функций (допустим даже скомпилированную) и использую их в качестве подфункций в своих функциях, так мне надо чтобы я обозначал свои переменные совсем не так как они обозначены в этих подфункциях. Они ж мне весь Марлезонский балет могут испортить.
Сие плохо по отношению к главной функции, т.к. ее глобальные переменные действительно могут испортить балет, если другой автор попытается ее включить в свою программу. А вот в подфункциях внутри главной функции это допустимо. Эти же переменные не вылезают наружу, за пределы главной функции. Если Вы заимствуете только кусок кода главной функции - например, подфункцию, разберитесь в нем или проконсультируйтесь у автора.

Последний раз редактировалось Li6-D, 25.10.2010 в 23:16.
Li6-D вне форума  
 
Автор темы   Непрочитано 25.10.2010, 23:14
#18
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Цитата:
Мораль сей басня очень прост: сначала надо разобраться с вызовом и областью видимости переменных.
Это мне напоминает матросские хохмочки. Идет работа, тащишь изделие для постановки на воду, заворачиваешь за угол какой-то надстройки и со всего маху лбом вписываешся в какю-то горизонтальную трубу ....
Тут как тут старпом или другой матрос с невозмутимым видом тебе сообщают, что это не .... а фок-гик. Вот так ходишь по кораблю и лбом изучаешь названия его элементов.
Supermax вне форума  
 
Непрочитано 25.10.2010, 23:16
#19
Кулик Алексей aka kpblc
Moderator

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


Supermax, все проще. Задай глобальную переменную, потом функцию с параметром, у которого такое же имя. Вызови функцию и внутри нее посмотри значение параметра. 90% вопросов снимется.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 25.10.2010, 23:29
#20
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Я вот о чем беспокоюсь:
Код:
[Выделить все]
(defun proba3 () (progn (setq ss 44) (* ss 2) (setq ss nil)))
(defun proba4 (ss) (proba3) (princ ss))
(proba4 5)
Возвращает nil
Проба3 создала и убила аргумент функции.

А вот так, возвращает 5
Код:
[Выделить все]
(defun proba3 ( / ss) (progn (setq ss 44) (* ss 2) (setq ss nil)))
(defun proba4 (ss) (proba3) (princ ss))
(proba4 5)
Поэтому перечисление пользовательских переменных, как локальных, не только борьба с замусориванием памяти, а еще и защита пользовательских переменных от глобальных интервенций. А также защита глобальных переменных от пользовательских определений.

В целом все стало на свои места.

Последний раз редактировалось Supermax, 25.10.2010 в 23:39.
Supermax вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > AutoLISP: Просачивание локальных переменных в тело используемых в выражении функций

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск