[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