[nem-pl] Dalsze rozważania o higienicznych makrach
Marcin 'Qrczak' Kowalczyk
qrczak at knm.org.pl
Sun Feb 22 23:20:11 CET 2004
W liście z nie, 22-02-2004, godz. 22:35, Kamil Skalski pisze:
> a jak chcesz higieniczny i parametryzowalny to
> proszę:
> macro m(id : string) { <[ def $(id : var) = ... ]> }
> macro m'() { def x = NewSymbol (); <[ m ($(x : string)); $(x : var) ]> }
Jeśli muszę używać NewSymbol, to równie dobrze mogę mieć niehigieniczne
makra Lispa z gensymem. Higiena nie polega na tym, że kombinując da się
jakoś uzyskać niekolidujące z obcymi zakresami nazwy - bo to można
zrobić i bez higieny - tylko że naturalny sposób zapisu makra, w którym
po prostu używamy identyfikatorów będących unikalnymi lokalnie, sam z
siebie domyślnie działa zgodnie z intuicją i identyfikator napisany w
danym miejscu zgadza się tylko z tak samo wyglądającym identyfikatorem
napisanym tuż obok.
> > I właśnie trzeba to robić i dołączać środowisko do identyfikatorów
> > wstawionych przez makro. Chyba że w ogóle nie damy możliwości łamania
> > higieny, wtedy zamiast całego środowiska wystarczy przechowywać
> > znalezioną w nim wartość dla konkretnego identyfikatora.
>
> Hmm, dlaczego do indentyfikatorów? Nie wystarczyłoby tak tweakować kontekstu
> typowania, żeby do wyniku ekspansji makra stosowało odpowiednie środowisko -
Wynik ekspansji może zawierać wywołania makr, które podzielą ten wynik
na kawałki (swoje argumenty) i umieszczą je innej konfiguracji, być może
mieszając z fragmentami pochodzącymi z argumentów pierwszego makra
(oryginalnie napisanymi w głównym programie, czyli bez dodatkowych
środowisk) oraz fragmentów dodanych od siebie (z innymi środowoskami).
Dopiero po tym wymieszaniu poskładany kod będzie kompilowany jako jedno
wyrażenie (jeśli to było makro-wyrażenie). Definicji występujących w nim
nazw-wyrażeń trzeba szukać biorąc pod uwagę ich pochodzenie.
Jeśli dana nazwa nie znajdzie się w bieżącym środowisku analizy kodu, a
ma doczepione środowisko, to znaczy że była wprowadzona przez makro.
To makro, w którego rozwinięciu ta nazwa była pierwotnie zapisana,
prawdopodobnie wstawiło wolne wystąpienie nazwy i trzeba jej szukać w
środowisku wziętym z miejsca definicji tego makra. To nie musi być
ostatnio rozwijane makro, tylko pierwsze makro, które wprowadziło daną
nazwę. Być może potem inne makra wzięły ją w argument i zwróciły
wewnątrz swojego rozwinięcia, ale liczy się to pierwsze - lexical
scoping.
Jeśli i w tym środowisku się nie znajdzie, to znaczy że definicja tego
makra sama była wygenerowana przez jakieś makro i w tej definicji
znalazło się wystąpienie czegoś znanego w generującym makrze (jeśli zaś
nie ma już następnego środowiska do przeszukania, to oczywiście jest
błąd - nieznana nazwa).
Jeśli makra nie mogą generować definicji makr, to w identyfikatorze może
się w sumie pojawić najwyżej jedno środowisko. Chyba. Ale w dalszym
ciągu różne identyfikatory umieszczone w jednym wyrażeniu mogą pochodzić
z różnych makr, a więc mieć różne środowiska, a identyfikatory
pochodzące z głównego programu nie będą miały żadnego środowiska.
> Natomiast co do tego jak to zrobić, to nadal nie jestem pewien - mam dziwne
> wrażenie, że to co jest opisane w pracy odnosi się do nieco innych założeń,
> no i jest kupa rzeczy do domyślenia.
Nie jestem pewien, czym się różnią założenia Dybviga od moich. Wciąż nie
wiem, z czego wynika, że on musi wykonywać podstawienia na ciele lambdy
wchodząc w lambdę (to podstawienie, jeśli już je robimy, trzeba robić
leniwie, żeby złożoność nie podskoczyła, a więc i kolorowanie trzeba
wykonywać leniwie, bo podstawienia mogą mieć wpływ na kolorowanie).
Ja nic nie podstawiam przy przejściu przez lambdę, tylko powiększam
lokalne środowisko i wchodzę głębiej.
--
__("< Marcin Kowalczyk
\__/ qrczak at knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
More information about the devel-pl
mailing list