LINUX.ORG.RU

Вопрос по Scheme


0

0

В Gambit Scheme набираю в REPL

>(define f1 (lambda (f l) (eval (cons f l))))
>(define f2 (lambda (x y z) (+ x y z)))
>(f1 f2 '(1 2 3))
*** ERROR -- Ill-formed expression
>(f1 'f2 '(1 2 3))
6

В MZscheme работают оба варианта (с f2 и 'f2).
А как правильно?


А если так записать?
(define (f1 f l) (eval (cons f l)))
(define (f2 x y z) (+ x y z))

power
()
Ответ на: комментарий от power

>(define (f1 f l) (eval (cons f l))) (define (f2 x y z) (+ x y z))

В таком варианте разница только в синтаксисе,работает одинаково.

>И вообще, что ты пытаешься сделать?

Функцию (f1) которая принимает другую функцию (f) и список ее аргументов (l) и возвращает результат выполнения f с l.Собственно интересует возможность сделать это через eval.

capricorn20
() автор топика
Ответ на: комментарий от capricorn20

> работает одинаково
Это на всякий случай.

> Функцию (f1) которая принимает другую функцию (f) и список ее аргументов (l) и возвращает результат выполнения f с l.

Уже есть такая - apply :)

power
()
(define f1 (lambda (f l) (eval (cons f l))))
(define f2 (lambda (x y z) (+ x y z)))

Здесь

(f1 'f2 '(1 2 3))
ты пытаешься вычислить (eval) форму (f2 1 2 3).

А вот тут

(f1 f2 '(1 2 3))
- форму (<f2 function> 1 2 3). Т.е. первым элементом в форме идём символ, а объект функции.

Не помню точно что нам об этом говорит стандарт Scheme (кому не лень — гляньте). Но скорее всего, как и в CL, первый элемент формы должен быть или символом (тогда вызывается функция, связанная с этим символом), или lambda-выражением.

Sectoid ★★★★★
()
Ответ на: комментарий от capricorn20

Ну, как я понимаю, это можно сделать с помощью макросов.
А чтобы написать свой apply для простых функций, подходит map.
Работа eval и apply разбирается в 4й главе SICP - можешь посмотреть, а я пока до туда не дошел.

power
()

guile> (define f1 (lambda (f l) (eval (cons f l))))
guile> (define f2 (lambda (x y z) (+ x y z)))
guile> (f1 f2 '(1 2 3))

Backtrace:
In standard input:
3: 0* [f1 #<procedure f2 (x y z)> (1 2 3)]
1: 1 [eval (#<procedure f2 (x y z)> 1 2 3)]

standard input:1:26: In procedure eval in expression (eval (cons f l)):
standard input:1:26: Wrong number of arguments to #<primitive-procedure eval>
ABORT: (wrong-number-of-args)

Так понятнее? :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Ну да. Дело в порядке вычислений - нужно чтобы l не вычислялся внутри (eval (cons f l)).
Верно же? ^^

power
()

Если не изменяет память, по стандарту конструкции (eval x) нет вообще, есть её вариант с отдельно задаваемым environment-ом. Поэтому каждая реализация ведёт себя в этом случае как ей вздумается.

Legioner ★★★★★
()
Ответ на: комментарий от Sectoid

>Не помню точно что нам об этом говорит стандарт Scheme (кому не лень -- гляньте). Но скорее всего, как и в CL, первый элемент формы должен быть или символом (тогда вызывается функция, связанная с этим символом), или lambda-выражением.

Нашел вот в R5RS про eval: Expression must be a valid Scheme expression represented AS DATA <- выделено мной Так что правильный вариант похоже (f1 'f2 '(1 2 3))

capricorn20
() автор топика
Ответ на: комментарий от Legioner

R5RS вообще говоря требует environment поэтому guile дает Wrong number of arguments to #<primitive-procedure eval>

capricorn20
() автор топика
Ответ на: комментарий от tailgunner

> Так понятнее? :)

Фигасе! Лисповой ересью заболел?

mv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.