2013-03-21 2 views
4

Я изучаю Racket (подобный схеме Lisp), и я попытался сделать что-то вроде (apply + '(1 2)), но без использования apply, и я потерпел неудачу. Я был почти уверен, что apply может быть каким-то образом смоделирован с использованием eval, но теперь у меня есть сомнения.Возможно ли реализовать `apply` в Lisp с использованием` eval`?

Итак, мой вопрос: может ли apply быть реализован в Racket (или другом Lisp), используя только eval и другие основные операции? То есть, как это сделать:

{ define [my-apply f arg] 
    ;; what does go here? 
} 
(my-apply + (list 1 2)) ; => 3 
+0

Несомненно. Подсказка: трюк состоит в том, чтобы передать список функторов и обратиться к 'eval', не оценивая список самостоятельно, поэтому вам нужно использовать' (list ...) 'и' (quote ...) '. –

+1

Есть ли решение, которое работает, если 'arg' ссылается на переменную с лексической областью? – finnw

+1

Что-то, что вы должны учитывать, это призывы к eval. Итак, если вы определяете my-apply, вызывая eval, который в свою очередь вызывает запросы, действительно ли вы определили my-apply без использования приложения? – WuHoUnited

ответ

2

Несомненно.

(defun my-apply (function arglist) 
    (eval (cons function (mapcar (lambda (x) (list 'quote x)) arglist)))) 
(my-apply '+ '(1 2 3)) 
6 
(my-apply '+ '(1 a 3)) 
*** - +: A is not a number 
  1. Обратите внимание, что вы не можете сделать (my-apply #'+ '(1 2 3)), для этого потребуется дополнительный шаг.

  2. Обратите внимание, что вы должны процитировать arglist элементы, чтобы избежать двойной оценки (спасибо Райану для ловли, что!)

+3

(eval (list * 'funcall (list' quote function) arglist)) –

+0

@RainerJoswig: Я тоже хотел избежать «funcall» – sds

+0

Как насчет '(my-apply '+' ((recursively-delete-all- файлы "/"))) '? –

0

Я нашел один (в Ракетка):

{ define [my-apply func args] 
    { define ns-for-eval (make-base-namespace) } 
    (eval (cons func args) ns-for-eval) 
} 

(my-apply + (list 1 2)) ; => 3 

Что-то не так?

+0

Я вижу, что есть проблема с самими элементами оценки args. Я могу, вероятно, процитировать args element-wise, как в ответе sds, но он начинает выглядеть слишком сложным. – Alexey

Смежные вопросы