Как мне исправить проблемы интернирования с помощью этого макроса? - PullRequest
0 голосов
/ 09 мая 2020

У меня в пакете «a» определен макрос, который определяет функцию «fun». Я хотел бы использовать этот макрос в пакете «b», ожидая, что «удовольствие» будет определено в «b», но в конечном итоге он будет определен в «a». Может кто-нибудь помочь?

Вот пример кода:

(defpackage #:a (:use #:cl) (:export makefun))
(in-package #:a)
(defmacro makefun (&optional (name (package-name *package*)))
  `(defun fun ()
     ,(format nil "hello ~a" name)))

(defpackage #:b (:use #:cl #:a))
(in-package #:b)
(macroexpand-1 '(makefun)) ; expands to (DEFUN A::FUN () "hello B")
(makefun)
(fun) ; fails

(defpackage #:c (:use #:cl #:a))
(in-package #:c)
(macroexpand-1 '(makefun)) ; expands to (DEFUN A::FUN () "hello C")
(makefun)
(fun) ; fails

1 Ответ

1 голос
/ 11 мая 2020

Если то, что вы действительно хотите сделать, это сделать имя функции в динамически текущем пакете, вы хотите сделать что-то вроде этого:

(defmacro makefun (&optional (name (package-name *package*)))
  (let ((funn (intern (symbol-name 'fun) *package*)))
    `(defun ,funn ()
       ,(format nil "hello ~a" name))))

Однако для меня это пахнет проблемой XY: Я не знаю, в чем проблема, которую вы пытаетесь решить, но, скорее всего, будет лучшее решение, чем множество разных функций с одним и тем же именем, но в разных пакетах.

...