> 1 <

Автор Сообщение

wyvern

Members


Статус

5 сообщений

Где: Russia
Род занятий: Программист С++)
Возраст: 33

#1700   2010-03-28 01:33 GMT+3 часа(ов)      
Здравствуйте, мэтры!)

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

Вот моя реализация:

 
(defun my-some (f &rest values) (my-some-s f values))
 
(defun my-some-s (f l)
(cond
((null l) nil)
((funcall f (car l)) t)
(t (my-some-s f (cdr l)))))
 


Преподователь сказал заменить funcall на некий набор базовых функций. Я попытался использовать eval, получилось следующее: (eval (cons f (cons (car l) nil))), вогнал в repl команду (my-some 'atom '(1 2 3) '1 '(1 2)), получил ошибку "1 is not a function name". Но тут есть проблема - если я поставлю (quote ...) сразу после евала, то не выполнится cons. Что можно с этим сделать, подскажите, пожалуйста? Работаю с коммон лисп, решение нужно настолько примитивное, насколько возможно...

VH

Members


Статус

289 сообщений

Где: ---
Род занятий:
Возраст:

#1701   2010-03-28 03:30 GMT+3 часа(ов)      
Вообще можно
(defun MY-SOME (p &rest values)
(cond
((null values) nil)
((funcall p (car values)) T)
(T (apply (function MY-SOME) (cons p (cdr values))))))

А базовых функций обработки символьных выражений всего пять: (CAR) (CDR) (CONS) (ATOM) и (EQ). Что из них тут можно сконструировать вместо (funcall)?

Михаил

Members


Статус

120 сообщений

Где: ---
Род занятий:
Возраст:

#1702   2010-03-28 03:32 GMT+3 часа(ов)      
(define (some p . args)
(eval
(cons
'or
(map (lambda (x)
((eval p) x))
args))))
 
> (some 'pair? '(1 2 3) '1 '(1 2))
#t

wyvern

Members


Статус

5 сообщений

Где: Russia
Род занятий: Программист С++)
Возраст: 33

#1703   2010-03-28 03:33 GMT+3 часа(ов)      
Вот это сказал преподователь.

"При программировании первого задания разрешено пользоватья функциями: car,
cdr, cons, atom, eq, quote, eval, cond (это базовый набор), member, eql, а
также арифметическими функциями + - < > =."

Михаил

Members


Статус

120 сообщений

Где: ---
Род занятий:
Возраст:

#1704   2010-03-28 04:41 GMT+3 часа(ов)      
Замените (funcall f (car l)) на ((eval f) (car l)).

wyvern

Members


Статус

5 сообщений

Где: Russia
Род занятий: Программист С++)
Возраст: 33

#1705   2010-03-28 05:03 GMT+3 часа(ов)      
Хм... Спасибо за ответ... Но приходит странная ошибка:

Если скомпилировать функцию с этой заменой, приходит ошибка "not the name of a function: (eval f)"

Если попробовать в репле выполнить ((eval 'numberp) (car '(1 2 3))), то приходит "(eval 'numberp) is not a function name"

Это точно должно работать на коммон лисп? (версия стоит 2.33)

wyvern

Members


Статус

5 сообщений

Где: Russia
Род занятий: Программист С++)
Возраст: 33

#1707   2010-03-28 05:06 GMT+3 часа(ов)      
Я прошу прощения... Просто я далеко не очень хорош в лиспе, к сожалению...

Михаил

Members


Статус

120 сообщений

Где: ---
Род занятий:
Возраст:

#1708   2010-03-28 06:50 GMT+3 часа(ов)      
> Это точно должно работать на коммон лисп?

Оказывается, что нет (ох уж этот CL, второй раз прокалываюсь).
(defun my-some-s (f l)
(cond
((null l) nil)
((eval (cons f (cons (cons 'quote (cons (car l) nil)) nil))) t)
(t (my-some-s f (cdr l)))))
0] (my-some 'atom '(1 2 3) '1 '(1 2))
T

Михаил

Members


Статус

120 сообщений

Где: ---
Род занятий:
Возраст:

#1709   2010-03-28 07:08 GMT+3 часа(ов)      
Кстати, quote и cond не функции в смысле lisp (а он, преподаватель, имел ввиду именно "в смысле лисп", иначе бы он и defun добавил в список своих разрешенных функций) (их аргументы предварительно не вычисляются, скажите это своему преподавателю,
и еще, плюньте ему в лицо от меня
).

wyvern

Members


Статус

5 сообщений

Где: Russia
Род занятий: Программист С++)
Возраст: 33

#1710   2010-03-28 13:07 GMT+3 часа(ов)      
Спасибо огромное!

Пришлось реализовывать самому даже такие функции как null, and, or и equal... xD

отредактировал(а) wyvern: 2010-03-28 13:45 GMT+3 часа(ов)
> 1 <


Онлайн :

0 пользователь(ей), 27 гость(ей) :