[nem-pl] Drugi rysunek już ze światłocieniem

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Sat Feb 28 16:43:31 CET 2004


W liście z sob, 28-02-2004, godz. 16:03, Kamil Skalski pisze:

> Hmm, to jak w takim razie właściwie definiujesz niehigieniczne zmienne?
> Bo ja je rozumiem jako takie, które mogą przykleić się do czegokolwiek.

Mogą się przykleić do tego, co było napisane na tym samym poziomie, co
użycie makra.

> Rzeczywiście generalnie nie powinny być nigdy używane - mechanizmy które 
> dajemy (w tym nazwy pokolorowane miejscem użycia makra) są bardzo bogate i 
> chyba wystarczające.

To jest trochę sprawa gustu. Ogólnie dobrze jest ich unikać, ale czasem
można uznać, że tak jest wygodniej.

Przykład: while i break jak w C. Higienicznie trzeba by przy pętli while
napisać jej nazwę, a przy breaku odwołać się do tej nazwy. W C jest to
zrobione niehigienicznie: znaczenie break zależy od tego, gdzie było
wpisane, mimo że nie było jawnie zdefiniowane; w szczególności
użytkownik nie może wybrać innej nazwy dla break, więc breaki zasłaniają
się nawzajem i trudno wyskoczyć z zewnętrznej pętli. To zasłanianie w
językach bardziej funkcyjnych nie jest takim problemem, jeśli można
napisać coś w stylu "let breakZewnetrzny = break" i później w
wewnętrznej pętli użyć breakaZewnetrznego.

Przykład z tej samej serii: this/self wprowadzane przez definicję klasy.
W OCamlu i w Pythonie jest nazywane jawnie, w większości języków jest
niejawnie - słowem kluczowym, które w języku z makrami może być
niehigienicznie wprowadzonym identyfikatorem.

Inny przykład: wyciąganie identyfikatorów ze stringów, np. interpolacja
jak w Perlu / szelu. Tutaj makro nie dostaje identyfikatora w formie już
pokolorowanego identyfikatora, tylko sam napis, więc musi go samemu
pokolorować, zgadując, w jakim środowisku ten string był wpisany (tego
nie wiemy na pewno, ale po prostu zakładamy, że w tym samym miejscu,
w którym makro jest użyte).

> > Na przykład niech makro m1 odwołuje się higienicznie do widocznego w
> > miejscu jego definicji globalnego symbolu x, a makro m2 niehigienicznie
> > wprowadza x i wstawia swój argument w zakres widoczności tego x. m2 było
> > przewidziane do bycia używanym w taki sposób:
> >    m2 (...coś zawierającego x...)
> > ale jeśli ktoś napisze
> >    m2 (...coś używającego m1...)
> > to m1 nie ma prawa się popsuć, bo to, że ono używa x, nie jest znane na
> > zewnątrz m1!
> 
> char buf[1024];
> for (i = 0; i <= 1024; i++) buf[i] = 0;
> 
> Twój argument jest taki jak powiedzenie, "ale operator przypisania pozwala na 
> pisanie powyższego kodu! tak nie może być!"

Zła analogia, bo psuje niepotrzebnie. Można tego łatwo uniknąć. Co
innego, gdyby nie dało się tak zorganizować łamania higieny, żeby to się
nie psuło - wtedy można by dyskutować, czy warto zapłacić ten koszt.

> Niehigiena z definicji pozwala coś zepsuć.

Nie musi psuć aż tyle. Psuje tylko to, że jeśli ktoś zapomniał, że makro
wprowadza x, to mu się przykryje; że ma ograniczoną możliwość wyboru,
jak ten identyfikator będzie się nazywał (tzn. zwykle makro nie oferuje
żadnej); że jeśli takie makro będzie obudowane innym makrem, to nie jest
jasne, które identyfikatory się przeniosą, a które nie (w modelu Scheme
i w moim nic się samo nie przenosi, a przy całkowitym braku higieny
Lispa wszystko się przenosi).

Ale nie ma powodu, żeby psuły się higieniczne makra używające x
prywatnie, które są użyte wewnątrz. W przypadku higienicznego makra
odwołującego się do identyfikatora znanego w miejscu jego definicji nie
ma powodu, żeby on się kiedykolwiek związał z czym innym, nawet jeśli to
makro będzie używane w niehigienicznych kontekstach.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak at knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/





More information about the devel-pl mailing list