Как при помощи ф-ции mapcar обрабатывать сложные списки?

Автор Тема: Как при помощи ф-ции mapcar обрабатывать сложные списки?  (Прочитано 17396 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Всем привет!

данный пример использования ф-ции mapcar
Код - Auto/Visual Lisp [Выбрать]
  1. (mapcar '(lambda (x)   (+ 10 x))  '(1 2 3))  
           
возвращает список результатов (11 12 13)

но требуется обработать список с более сложной структурой
Код - Auto/Visual Lisp [Выбрать]
  1. (mapcar
  2.            '(lambda (x)   (+ 10 x))
  3.  
  4.             (list
  5.               1 2 3
  6.               (list 4 5 6)
  7.               (list (list 7 8 9) (list 10 11 12))
  8.             )
  9.          )
на выходе получаем
error: bad argument type: numberp: (4 5 6)

Не подскажете каким образом на выходе получить список результатов с такой же структурой как и на входе?
т.е. для данного примера -    (11 12 13 (14 15 16) ((17 18 19) (20 21 22)))
« Последнее редактирование: 02-02-2015, 15:37:37 от Александр Ривилис »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
В принципе для такой обработки практически идеально подойдет рекурсия. Немного погодя попробую нарисовать код, сейчас срочной работы многовато...
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
В качестве первой прикидки:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq lst '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
  2.  
  3. (mapcar
  4.   (function
  5.     (lambda (x / f)
  6.       (defun f (x1)
  7.         (cond
  8.           ((listp x1)
  9.            (mapcar (function f) x1)
  10.            )
  11.           (t (+ 10 x1))
  12.           ) ;_ end of cond
  13.         ) ;_ end of defun
  14.       (f x)
  15.       ) ;_ end of lambda
  16.     ) ;_ end of function
  17.   lst
  18.   ) ;_ end of mapcar
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Спасибо Алексей!

Все работает!!

Попытался на основе твоего кода создать универсальный mapcar для обработки сложных списков -

Код - Auto/Visual Lisp [Выбрать]
  1.        
  2. (defun $-mapcar (fnc sp)
  3. (mapcar
  4.   (function
  5.     (lambda (x / f)
  6.       (defun f (x1)
  7.         (cond
  8.           ((listp x1)
  9.            (mapcar (function f) x1)
  10.            )
  11.            (t (eval (read (strcat "(" fnc " x1)"))))
  12.           ) ;_ end of cond
  13.         ) ;_ end of defun
  14.       (f x)
  15.       ) ;_ end of lambda
  16.     ) ;_ end of function
  17.   sp
  18.   ) ;_ end of mapcar
  19. ); defun
  20.  
  21.  
  22.  
  23. (defun d (a)  (+ 10 a))
  24.  
  25. (defun c:test ()
  26.   (setq lst '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
  27.   (setq res ($-mapcar "d" lst))
  28.   (print res)  
  29. (princ)); defun
  30.  
  31.  
  32. Command: TEST
  33. (11 12 13 (14 15 16) ((17 18 19) (20 21 22)))
« Последнее редактирование: 02-02-2015, 15:38:02 от Александр Ривилис »

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
:) Правда, у меня сильные подозрения, что настолько заморачиваться особой необходимости нет: наверняка можно получить исходный список более однородной структурой.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Можно и без mapcar'ов:
Код - Auto/Visual Lisp [Выбрать]
  1. (defun rec1+ (lst)
  2.   (if lst
  3.      (cons ((if (listp (car lst))
  4.                 rec1+
  5.                 1+) (car lst))
  6.            (rec1+ (cdr lst)))))

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
И правда можно!
Проверил в AA-2014-eng и AA-2015-eng

Command: (rec1+ '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
(2 3 4 (5 6 7) ((8 9 10) (11 12 13)))


Работает!
И код короче.
Спасибо!

Вот только пока не смог добавить в эту функцию второй аргумент, чтобы исходный список обрабатывался не только ф-цией 1+, а любой произвольной, заданной вторым аргументом.







Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
наверняка можно получить исходный список более однородной структурой.
В моем случае структура определяется данными, извлекаемыми из помещения (space или zone) для формирования различных ведомостей и спецификаций архитектурно-строительных чертежей.
Поэтому хочется создать универсальную ф-цию извлечения данных в такой структуре в которая наиболее удобна будет для обработки в дальнейшем...


Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
А, может, выгоднее будет создать ассоциативный список по типу
Код - Auto/Visual Lisp [Выбрать]
  1. '(("space" ("Тип помещения" <Перечисление площадей>)
  2.                 ("Тип помещения" <Перечисление площадей>)
  3.                 ...
  4.                  )
  5.  ("zone" ("Тип зоны / группы помещений" <Перечисление площадей>)
  6.           ("Тип зоны / группы помещений" <Перечисление площадей>)
  7.           ...
  8.           )
  9.  )
  10.  
И обрабатывать уже отдельные типы объектов?
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Вот только пока не смог добавить в эту функцию второй аргумент, чтобы исходный список обрабатывался не только ф-цией 1+, а любой произвольной, заданной вторым аргументом.
Ну по "стандартам лиспа" только не вторым аргументом, а первым (второй список):
Код - Auto/Visual Lisp [Выбрать]
  1. (defun map-rec(fn lst)
  2.   ((lambda (frec) (frec lst))
  3.    (lambda (lst)
  4.      (if lst
  5.          (cons ((if (listp (car lst))
  6.                     frec
  7.                     fn) (car lst))
  8.                (frec (cdr lst)))))))

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Работает как и хотел!

Код - Auto/Visual Lisp [Выбрать]
  1. (defun d (a)  (+ 10 a))
  2. (setq lst '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
  3. (map-rec d lst)
  4. (11 12 13 (14 15 16) ((17 18 19) (20 21 22)))

Спасибо!
« Последнее редактирование: 04-02-2015, 12:12:32 от Алексей Кулик »

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
А, может, выгоднее будет создать ассоциативный список по типу
Код - Auto/Visual Lisp: [Выделить]
'(("space" ("Тип помещения" <Перечисление площадей>)
                ("Тип помещения" <Перечисление площадей>)
                ...
                 )
 ("zone" ("Тип зоны / группы помещений" <Перечисление площадей>)
          ("Тип зоны / группы помещений" <Перечисление площадей>)
          ...
          )
 )
 
И обрабатывать уже отдельные типы объектов?

У меня немного другой подход -
на первом этапе отбираются объекты нужного типа на нужном слое (или т.п.)
на втором определяется список для извлечения данных в нужной структуре

(
  (набор1 набор2 набор3)
  (набор1 характеристика3)
  (набор1 характеристика12)
  (
     (набор2 характеристика1)
     (набор2 характеристика3)
     (набор3 характеристика1)
  )
  ...
)
далее получаю список значений нужных характеристик при помощи ф-ции #9
далее обработка значений (вычисления, подчеты, упорядочивание, сортировка ) для получения данных вывода в таблицу
далее вставка таблицы




Оффлайн gomer

  • ADN OPEN
  • Сообщений: 4
  • Карма: 2
Если все таки хочется mapcar...
Код - Auto/Visual Lisp [Выбрать]
  1. (defun tree-apply (f lst)
  2.   (mapcar (function (lambda (x)
  3.              (if (listp x)
  4.                (tree-apply f x)
  5.                (apply (function f)
  6.                       (list x)))))
  7.           lst))

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Проверил ф-цию tree-apply
все работает

Код - Auto/Visual Lisp [Выбрать]
  1. (defun d (a)  (+ 10 a))
  2. (setq lst '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
  3. (tree-apply d lst)
  4. (11 12 13 (14 15 16) ((17 18 19) (20 21 22)))
  5.  

Спасибо за очередной вариант решения!

С лиспом у меня не очень, с точки зрения корректности и рациональности формирования кода.

И я затрудняюсь в определении того какая из представленных рабочих ф-ций лучше.

Поэтому оставляю выбор поста, соответствующего решению темы, за профессионалами в этой области...



Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13830
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Юрий! Просто отметьте ту функцию, которой будете пользоваться. А остальным можете просто "плюсануть в карму". :)
Мне кажется так будет справедливо.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
#9 lambda lambda ...   
мне показалось проще чем
#12 mapcar function lambda  ...  apply  function

если предположить, что проще это лучше то выбор за Димой #9
но в качестве ответа к вопросу темы больше подходит #12 от gomer

Оффлайн gomer

  • ADN OPEN
  • Сообщений: 4
  • Карма: 2
#9 lambda lambda ...   
мне показалось проще чем
#12 mapcar function lambda  ...  apply  function

если предположить, что проще это лучше то выбор за Димой #9
но в качестве ответа к вопросу темы больше подходит #12 от gomer


на самом деле
Код - Auto/Visual Lisp [Выбрать]
  1. (apply (function f)  (list x))
легко заменяется на
Код - Auto/Visual Lisp [Выбрать]
  1. (f x)
и функция выглядит совсем просто
Код - Auto/Visual Lisp [Выбрать]
  1. (defun tree-apply (f lst)
  2.   (mapcar (function
  3.             (lambda (x)
  4.               (if (listp x)
  5.                 (tree-apply f x)
  6.                 (f x))))
  7.           lst))

В классическом варианте это выглядит так
Код - Auto/Visual Lisp [Выбрать]
  1. (defun tree-apply (f lst)
  2.   (cond
  3.     ((null lst) nil)
  4.     ((listp (car lst))
  5.      (cons (tree-apply f (car lst))
  6.            (tree-apply f (cdr lst))))
  7.     (t
  8.      (cons (f (car lst))
  9.            (tree-apply f (cdr lst))))))
Код в #9 как раз и является танцами с бубном вокруг этой функции с целью уменьшить количество букаф
другой классический вариант выглядит так
Код - Auto/Visual Lisp [Выбрать]
  1. (defun tree-apply (f lst)
  2.   (cond
  3.     ((null lst) nil)
  4.     ((atom lst) (f lst))
  5.     (t
  6.      (cons (tree-apply f (car lst))
  7.            (tree-apply f (cdr lst))))))
Тоже достаточно простой
Вариант от Дима_ на самом деле достаточно сложен для понимания, но полезен для общего развития

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
gomer, спасибо за развернутые пояснения!
Проверил, все три ф-ции работают.

Но при наличии такого количества вариантов обработки сложных (структуризированных) списков возникает сл. вопросы.

1. Какой способ наиболее рациональный с точки зрения скорости выполнения?

2. В каких случаях целесообразнее использовать mapcar при обработке структуризированных списков если вполне можно обходиться без него?

3. В чем состоит особенность применения ATOM в последней ф-ции в отличии  от LISTP во всех предыдущих?



Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
В чем состоит особенность применения ATOM в последней ф-ции в отличии  от LISTP во всех предыдущих?
Проверяется тип передаваемого аргумента - атом или список.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
а атом, если я правильно понял из руководства,
это все то что не является списком

т.е. функция Atom - функция, обратная к LISTP
если Listp - проверка на список
то Atom - проверка  на "не список" т.е. атом

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
В каких случаях целесообразнее использовать mapcar при обработке структуризированных списков если вполне можно обходиться без него?
Да практически во всех. В автолиспе рекурсия очень "слабая" - нет "хвостовой" оптимизации, а в "стеке" хранит максимум на 20 тысяч "уровней" - то есть это только для самой простой "одноуровневой" рекурсивной структуры - например для создания списка - для более сложной в соответствующее кол-во раз меньше. Автолисп написан очень давно, когда байты и машинные такты еще приходилось считать - и задачи на него возлагались в более приземленном виде, а требование к "качеству" кода были выше. Если есть "большая" задача (и тут самое сложное заранее понять в каком измерении она может вылезти за разумные рамки автолиспа) автолиспом ее как правило реализовать-таки можно - но не эффективно - на него очень хорошо ложатся задачи до определенного уровня (быстро, просто и "красиво") - а сверх него - обрастает костылями сводя на нет все свои сильные стороны - а их не мало. Практически все "встроенные" функции написаны не на автолиспе (как это принято делать в "классических" лиспах), а являются менее высокоуровневыми скомпилированными структурами (хотя на момент создания автолиспа уже были эффективные трансляторы с лиспа - производительность которых не уступала, но автодеск пошел по более простому и менее затратному, но в конечном счете тупиковому пути).

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
В каких случаях целесообразнее использовать mapcar при обработке структуризированных списков если вполне можно обходиться без него?
Да практически во всех...

Дима, тогда получается, что лучшим на данный момент является решение от gomer  в  #12?

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1097
  • Карма: 172
Я думаю, что самым лучшим решением будет то, которое понятно. Скорость выполнения (мне кажется) будет сейчас далеко не на первом месте в перечне критериев выбора.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Алексей, по поводу скорости согласен, сейчас она далеко не на первом месте...
Вероятнее всего с ней можно будет поразбираться если программа будет медленно работать из-за больших объемов данных.

В дальнейшем все таки постараюсь разобраться во всех представленных решениях, чтобы было понятно...

Ни одно из решений не подошло для обработки данных вида -
(
  (набор1 характеристика3)
  (набор1 характеристика12)
  (
     (набор2 характеристика1)
     (набор2 характеристика3)
     (набор3 характеристика1)
  )
  ...
)

т.к. конечным элементом для обработки является список а не атом

попробовал подкорректировать одну из ф-ций  #16 (пока более понятную)
вроде получилось -
Код - Auto/Visual Lisp [Выбрать]
  1. (defun tree-apply (f lst)
  2.   (cond
  3.     ((null lst) nil)
  4.    
  5.     (
  6.       (= (type (car lst)) 'STR)
  7.       (cons (f (read(car lst)))
  8.            (tree-apply f (cdr lst)))
  9.     )
  10.    
  11.     ((listp (car lst))
  12.      (cons (tree-apply f (car lst))
  13.            (tree-apply f (cdr lst))))
  14.     (t
  15.      (cons (f (car lst))
  16.            (tree-apply f (cdr lst))))))
  17.  
  18.  
  19.  
  20. ;пример 1
  21. (defun d (a)  (+ 10 a))
  22. (setq lst '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
  23. (tree-apply d lst)
  24. (11 12 13 (14 15 16) ((17 18 19) (20 21 22)))
  25.  
  26. ;пример 2
  27. (defun d1 (a)  (+ 100 (car a)(cadr a)))
  28. (setq lst1 '("(1 1)" "(2 2)" "(3 3)" ("(4 4)" "(5 5)" "(6 6)") (("(7 7)" "(8 8)" "(9 9)") ("(10 10)" "(11 11)" "(12 12)"))))
  29. (tree-apply d1 lst1)
  30. (102 104 106 (108 110 112) ((114 116 118) (120 122 124)))
  31.  
« Последнее редактирование: 22-02-2015, 00:20:48 от Юрий Ананьев »

Отмечено как Решение Юрий Ананьев 22-02-2015, 00:17:07

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Подкорректировал функцию от gomer из #16, использующую mapcar lambda
Код - Auto/Visual Lisp [Выбрать]
  1. (defun tree-apply (f lst)
  2.   (mapcar
  3.     '(lambda (x)
  4.        (cond
  5.          ((null lst) nil)
  6.          ((=(type x)'STR) (f(read x)))
  7.          ((atom x)(f x))
  8.          (t(tree-apply f x))
  9.        );cond
  10.      )
  11.      lst)
  12. );defun
  13.  
  14. ;пример 1
  15. (defun d (a)  (+ 10 a))
  16. (setq lst '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
  17. (tree-apply d lst)
  18. (11 12 13 (14 15 16) ((17 18 19) (20 21 22)))
  19.  
  20. ;пример 2
  21. (defun d1 (a)  (+ 100 (car a)(cadr a)))
  22. (setq lst1 '("(1 1)" "(2 2)" "(3 3)" ("(4 4)" "(5 5)" "(6 6)") (("(7 7)" "(8 8)" "(9 9)") ("(10 10)" "(11 11)" "(12 12)"))))
  23. (tree-apply d1 lst1)
  24. (102 104 106 (108 110 112) ((114 116 118) (120 122 124)))
  25.  

на ней пока и решил остановиться в качестве решения
« Последнее редактирование: 22-02-2015, 12:04:37 от Юрий Ананьев »

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Подкорректировал Димину функцию  из #9, использующую lambda lambda cons

Код - Auto/Visual Lisp [Выбрать]
  1. (defun map-rec(fn lst)
  2.   (
  3.     (lambda (frec) (frec lst))
  4.     (lambda (lst)
  5.       (if lst
  6.          (cons
  7.            (
  8.              (if
  9.                (listp (car lst))
  10.                 frec
  11.                 fn
  12.              );if
  13.              (if
  14.                 (=(type (car lst))'STR)
  15.                 (read (car lst))
  16.                 (car lst)
  17.              );if
  18.            )
  19.            (frec (cdr lst))
  20.          ); cons
  21.       );if
  22.     );lambda
  23.   )
  24. );defun
  25.  
  26. ;пример 1
  27. (defun d (a)  (+ 10 a))
  28. (setq lst '(1 2 3 (4 5 6) ((7 8 9) (10 11 12))))
  29. (map-rec d lst)
  30. (11 12 13 (14 15 16) ((17 18 19) (20 21 22)))
  31.  
  32. ;пример 2
  33. (defun d1 (a)  (+ 100 (car a)(cadr a)))
  34. (setq lst1 '("(1 1)" "(2 2)" "(3 3)" ("(4 4)" "(5 5)" "(6 6)") (("(7 7)" "(8 8)" "(9 9)") ("(10 10)" "(11 11)" "(12 12)"))))
  35. (map-rec d1 lst1)
  36. (102 104 106 (108 110 112) ((114 116 118) (120 122 124)))
  37.  

% понимания растет )))
« Последнее редактирование: 22-02-2015, 12:04:10 от Юрий Ананьев »

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Если придираться - то проверка в строке 14 частично избыточна с строкой 9 (если ((car)lst) список - то он точно не строка*) - да так в общем можно делать - но если идет процесс увеличения "% понимания", то желательно, хотя-бы в целях самообразования подумать как это лучше исправить.

* хотя в некоторых диалектах функциональных языков строка представлена как последовательность символов.

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Если придираться - то проверка в строке 14 частично избыточна с строкой 9 (если ((car)lst) список - то он точно не строка*) - да так в общем можно делать - но если идет процесс увеличения "% понимания", то желательно, хотя-бы в целях самообразования подумать как это лучше исправить.

Подумать подумал ))
но безрезультатно (
Справиться с частичной избыточностью строки 14 так и не смог ((



Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
ну главное процесс...
Код - Auto/Visual Lisp [Выбрать]
  1. (defun map-rec(fn lst)
  2.   (
  3.     (lambda (frec) (frec lst))
  4.     (lambda (lst)
  5.       (if lst
  6.       (cons (if (listp (car lst))
  7.                 (frec (car lst))
  8.                 (fn (if (=(type (car lst))'STR)
  9.                         (read (car lst))
  10.                         (car lst))))
  11.             (frec (cdr lst)))
  12.       );if
  13.     );lambda
  14.   )
  15. );defun
а ведь еще есть cond...

Оффлайн Юрий АнаньевАвтор темы

  • ADN Club
  • Сообщений: 21
  • Карма: 1
  • Skype: ananiev-yuriy
Дима, спасибо, теперь понятно.

А с использованием cond похоже будет так -

Код - Auto/Visual Lisp [Выбрать]
  1. (defun map-rec(fn lst)
  2.   (
  3.     (lambda (frec) (frec lst))
  4.     (lambda (lst)
  5.      (if lst
  6.       (cons
  7.             (cond
  8.                 ((listp (car lst))   (frec (car lst)))
  9.                 ((=(type (car lst))'STR) (fn(read (car lst))))
  10.                 (t (fn (car lst)))
  11.             );cond         
  12.             (frec (cdr lst))
  13.       );cons
  14.      );if
  15.     );lambda
  16.   )
  17. );defun
  18.  
  19.