[nem-pl] Dalsze rozważania o higienicznych makrach
Kamil Skalski
nazgul at omega.pl
Mon Feb 23 17:53:30 CET 2004
Sunday 22 of February 2004 22:06, Marcin 'Qrczak' Kowalczyk wrote:
> W liście z nie, 22-02-2004, godz. 21:25, Kamil Skalski pisze:
> > >Ależ chciałby - w końcu po to wstawił definicję bar, żeby w jej zakresie
> > >bar oznaczał zdefiniowaną rzecz. Nie musi nawet pamiętać, które
> > >konstrukcje definicyjne są wbudowane, a które są makrami.
> >
> > Gdyby naprawdę tego chciał i był rozsądnym programistą, to napisałby
> > def $("bar" : var) =...
>
> Zupełnie nie. Po pierwsze bar było wprowadzane przez hipotetyczne makro
> defrule, a nie ręcznie przez def. Po drugie było higieniczne - napisane
> tylko w treści jednego makra i widoczne tylko tam.
Mieliśmy małą developer dyskusję o makrach i oto podsumowanie:
- W ogóle zabaniamy przeciekania definicji z makr. Już teraz prawie tak jest,
co przeoczyłem, bo <[ e_1; e_2; ... ]> jest tłumaczone na sekwencję
{ e_1; e_2; ... }, która z definicji "ulokalnia" definicji do obrębu swojego
ciała. Wyjątek to <[ def x = ... ]> co jest tłumaczone na def x = ... i to
się przydaje już w tych makrach, które są. Nie przeszkadza to jednak zmienić
w ekspansji makr:
expand_maro (name, list_of_macro_args) na E_sequence (expand_macro (...)).
Wszystko to utnie wiele problemów i uprości cały system, jednak nie wszystko
się łatwe....
Mamy takie makro 'using (x = Foo ()) { x.Compute (); }', które jest
tłumaczone na:
def x = (Foo () : IDisposable);
x.Compute ();
x.Dispose ();
Z nim jest taki sam problem - nie możemy naiwnie podmienić nazwy 'x' na
wygenerowaną, bo using (niehigienicznie zresztą, ale całkiem bezpiecznie)
definiuje x na podstawie jej nazwy "x".
Pozostaje zatem podobny problem co ostatnio, tylko chyba jest już o nim dużo
łatwiej myśleć.
- Michał mówi, że przerzucenie rozwijania nazw (x na Foo.A.x) do typowania (po
ekspansji makr) powinno być dość proste poprzez podmienianie kontekstów przy
uruchamianiu expand_macro (czyli tak jak wspominałem, bez przydzielania
każdej zmiennej jej kontekstu). Może to aczkolwiek ulec zmianie w ostatecznej
wersji, gdy wymyślimy jak rozwiązać pierwszy problem
A ja tu jeszcze mam inną wątpliwość, bo quotowanie jest używane nie tylko w
makrach - np. ja sobie piszę w algorytmie budowania quotowań używając
quotowań, które służą mi do niczego innego jak do skrócenia zapisu drzew
składniowych. Nic nie jest tu expandowane, wszystko dzieje się w tej samej
kompilacji. I co, mam w nich stracić możliwość automatycznego rozwijania
nazw?
- najpierw oczywiści zaimplementujemy metodę prostą, ale kontynuujemy dyskusję
jak rozwiązać kwestię 'using' - przypominam, wszystko jest z nim w porządku,
dopóki nie napiszemy
<[ using (x = Foo()) { x.Compute () } ]>, gdzie prosty system przemianuje to
na <[ using (x = Foo ()) { x_11.Compute () } ]> i wszystko się zepsuje
Uprzedzając wszelkie uwagi odnośnie do pierwszego punktu - to ma sens, np. w
Ocamlu jest 'let x = ... in ...' - 'x' nie jest widoczny poza wyrażeniem po
'in', które jest składniowym elementem związanym z 'let'. Nie dałoby się
zatem też napisać 'my_macro () in use(x)', gdzie 'my_macro ()' teoretycznie
wstawiałoby 'let x = ...'.
Kamil
More information about the devel-pl
mailing list