Jak określa się zakres zmiennych dla makr?

11

Weźmy następujące makro przykładowe, zdefiniowane w macro.el.

(defmacro some-macro (&rest body)
  `(let ((some-variable 1))
     ,@body))

I przyjąć następującą funkcję zdefiniowaną w innym pliku , function.el.

(defun some-function ()
  (some-macro (do-something)))

Kiedy function.elzostanie skompilowany bajtowo, zostanie some-variablepowiązany w powiązaniu leksykalnym lub dynamicznym?

Rozumiem, że zależy to od tego, czy plik używa -*- lexical-binding: t; -*-, więc moje pytanie dotyczy w szczególności następujących sytuacji:

  1. Jeśli function.elużywa powiązania leksykalnego, ale macro.elnie używa .
  2. Jeśli macro.elużywa powiązania leksykalnego, ale function.elnie używa .

Czy robi to różnicę, jeśli some-varzostał zadeklarowany jako globalny (z defvarsem) w środku function.el? Jeśli tak, jestem szczególnie zainteresowany przypadkiem, w którym tak się nie stało .

Malabarba
źródło
Myślę Jisang Yoo objęte tym dość szczegółowo w yoo2080.wordpress.com/2013/08/14/...
phils
Nie wiem na pewno, ale założę się, że rozwinięcie makra dziedziczy semantykę wiązania z miejsca rozwinięcia, a nie z definicji makra. Miałoby to sens, ponieważ rozszerzenie zostało faktycznie zastąpione w witrynie połączenia. Ale: dlaczego chcesz wiedzieć? Czy zamierzasz napisać kod, który faktycznie opiera się na tych szczegółach ?!
lunaryorn,
@lunaryorn makro nie opiera się całkowicie na tym, ale może powodować zaskakujące błędy dla użytkownika, jeśli nie przestrzega wiązania pliku, w którym jest używany.
Malabarba,
@Malabarba Napisz więc makro w sposób, który nie zależy od wiązania w buforze docelowym. Lub jeszcze lepiej, nie używaj makra w ogóle.
lunaryorn,
@lunaryorn Nie byłem całkiem jasny. Makro jest tylko formą let i działa tak, jak w reklamie. Chcę tylko upewnić się, że ten formularz pozwól śledzić zakres określony w pliku, w którym jest rozwinięty. To pytanie polega na ustaleniu, czy dzieje się to automatycznie, czy też muszę to zakodować w makrze.
Malabarba

Odpowiedzi:

9

Rodzaj scopingu aktywny (let ((some-variable ..)) ...)w twoim przykładzie jest taki, który jest aktywny w miejscu wywołania makra (tj. Ten, który dotyczy some-function).

Makro może wiedzieć, jaki rodzaj zakresu zostanie użyty dla kodu, który zwraca, sprawdzając wartość lexical-bindingzmiennej.

Stefan
źródło