Suppose I want to do the following:
(loop for i from 1 to n do
(defun ith(lst)
(nth i lst)))
Apparently what I really want to do is the following:
(defun 1th(lst)(nth 1 lst))
(defun 2th(lst)(nth 2 lst))
(defun 3th(lst)(nth 3 lst))
(defun 4th(lst)(nth 4 lst))
......
(defun 100th(lst开发者_如何学Go)(nth 100 lst))
How can I make that?
Here you go. Note that |1th|
would return the second value:
(defmacro make-nths (n)
`(progn
,@(loop for i from 1 to n
collecting `(defun ,(intern (format nil "~ath" i)) (list)
(nth ,i list)))))
As Xach pointed out in the comments, macrolet
might be preferable here, since you do not really need a globally defined macro:
(macrolet ((make-nths (n)
`(progn
,@(loop for i from 1 to n
collect `(defun ,(intern (format nil "~ath" i)) (list)
(nth ,i list))))))
(make-nths 3)) ; choose n here
Finally, here is a working version of ninjaaa's non-macro solution:
(loop for i from 1 to 3 ; choose n here
do (let ((i i)) ; introduce new bindings for each iteration
(setf (symbol-function (intern (format nil "~ath" i)))
(lambda (list) (nth i list)))))
Try this:
(loop for i from 1 to n do
(setf (symbol-function (intern (format nil "~dth" i)))
#'(lambda (lst) (nth i lst))))
精彩评论