2014-04-09 5 views
0

해당 매개 변수를 사용하는 다른 함수를 이름으로 정의하는 매개 변수로 함수를 정의하고 싶습니다. 일을 해달라고LISP가 함수를 동적으로 정의합니다.

예 :

(DEFUN custom (name op const var) 
    (DEFUN name (var) (op const var))) 

문제는 이름 밤은 평가 등 정의 된 함수는 항상 이름이라는 점이다.

나는 FUNCALLAPPLY 동적 매개 변수를 평가할 수 있다는 것을 알고,하지만 난 제대로 FUNCALLDEFUN...를 호출하는 방법을 모르겠어요.

+0

사용 방법에 대한 예를 들려 줄 수 있습니까? 실제 코드가 가장 좋습니다. – zck

답변

4

중첩 된 defuns 사용할 수 있다고 생각하지 않습니다.

당신은 lambda 반환하는 defun을 사용할 수 있습니다 :

(defun custom (op const) 
    (lambda (arg) (funcall op const arg))) 

을 다음 fdefinition를 사용

(setf (fdefinition '+42) (custom '+ '42)) 

또는 defmacro를 사용

(defmacro custom (name op const) 
    (let ((arg (gensym))) 
    `(defun ,name (,arg) 
     (,op ,const ,arg)))) 

(custom +42 + 42) 

PS합니다. 왜 당신이 이것을하려고하는지 설명해야한다고 생각합니다. 그러면 우리는 당신의 선택을 더 잘 설명 할 수있을 것입니다.

1

나는 카레 기능을 원할지도 모른다. 당신이 이런 짓을 상상해

(defun curry (op arg1) 
    (lambda (&rest args) (apply op (cons arg1 args)))) 

(funcall (curry #'+ 10) 20)  ; ==> 30 

(mapcar (curry #'+ 10) '(1 2 3 4)) ; ==> (11 12 13 14) 

지금 defun은 항상 전역 네임 스페이스의 기능을한다. 그것은 Scheme에서 클로저를 만드는 것과는 다릅니다.

(defun create-curried (name op arg1) 
    (setf (symbol-function name) 
     (lambda (&rest args) (apply op (cons arg1 args))))) 

(create-curried '+x #'+ 10) ; ==> function 
(+x 20)      ; ==> 30 

;; since it's a function, it even works with higher order functions 
(mapcar create-curried '(+x -x /x *x) (list #'+ #'- #'/ #'*) '(10 10 10 10)) 
(/x 2) ; ==> 5 

마지막 : 우리가 symbol-functionsetf를 사용 defun으로 동일한 작업을 수행합니다. 매크로를 사용하면 매크로를 미리 정의 할 수 있습니다. 이와 flet 또는 labels를 사용할 수 있도록

(defmacro defun-curried (newname oldname arg) 
    (if (and (symbolp newname) (symbolp oldname)) 
     `(create-curried ',newname (function ,oldname) ,arg) 
     (error "Newname and Oldname need to be symbols"))) 

(defun-curried +xx + 20) 
(+xx 10) ; ==> 30 

oldname

는 어휘 범위에서 가져하지만 그것은 단지 defun와 같은 글로벌되고 끝납니다.

1

가장 큰 문제는 DEFUN은 함수가 아니며 특별히 인수를 처리하는 매크로입니다 (구체적으로 "함수 이름", "인수 본문"을 평가하지 않고 "함수 본문"이 아닌)).

(defun define-custom-function (name op const) 
    (setf (symbol-function name) (lambda (var) (funcall op const var)))) 

이 당신에 "연산자"를 호출 유가에 일정 익명 함수에 심볼의 기능 정의를 결합 :

당신은 아마 (setf (symbol-function ...) ...)의주의 사용, 뭔가 등으로 뭔가 작품을 만들 수 . 당신이 절대적으로 동적으로 이러한 사용자 지정 함수를 정의 (또는 재 정의) 필요가없는

* (defun define-custom-function (name op const) 
     (setf (symbol-function name) (lambda (var) (funcall op const var)))) 

DEFINE-CUSTOM-FUNCTION 
* (define-custom-function 'add3 #'+ 3) 

#<CLOSURE (LAMBDA (VAR) :IN DEFINE-CUSTOM-FUNCTION) {1002A4760B}> 
* (add3 5) 

8 

그러나, 당신은 아마 사용자 정의 DEFUN -like 매크로를 정의하는 것이 더 낫다.

관련 문제