4

I am learning Racket (a Scheme-like Lisp), and i have tried to do something like (apply + '(1 2)) but without using apply, and i failed. I was almost sure before that apply can be somehow simulated using eval, but now i have doubts.

So, my question is: can apply be implemented in Racket (or other Lisp) using only eval and other basic operations? That is, how to make this work:

{ define [my-apply f arg]
  ;; what does go here?
}
(my-apply + (list 1 2)) ; => 3
Alexey
  • 3,843
  • 6
  • 30
  • 44
  • Sure it is. Hint: The trick is to pass a list of functor and arg to the `eval` without evaluating the list yourself, so you need to use `(list ... )` and `(quote ...)`. – Kilian Foth Mar 21 '13 at 14:42
  • 1
    Is there a solution that works if `arg` references a lexically-scoped variable? – finnw Mar 21 '13 at 15:45
  • 1
    Something you have to consider is that eval calls apply. So if you define my-apply by calling eval which in turn calls apply, have you really defined my-apply without using apply? – WuHoUnited Mar 21 '13 at 15:54
  • @WuHoUnited, this would be fine for me, i am not considering in this question how `eval` is implemented. – Alexey Mar 21 '13 at 15:55
  • .. but please do not do this in production code. :) – dyoo Mar 22 '13 at 01:31

2 Answers2

2

Sure.

(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. Note that you cannot do (my-apply #'+ '(1 2 3)), this would require an extra step.

  2. Note that you have to quote arglist elements to avoid double evaluation (Thanks to Ryan for catching that!)

sds
  • 58,617
  • 29
  • 161
  • 278
0

I've found this one (in Racket):

{ 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

Is there anything wrong with it?

Alexey
  • 3,843
  • 6
  • 30
  • 44
  • I see that there is an issue with the elements of args being evaluated themselves. I can probably quote args element-wise, like in the answer of sds, but it starts looking too complicated. – Alexey Mar 26 '13 at 20:31