[nem-pl] Uwagi różne

Kamil Skalski nazgul at omega.pl
Fri Feb 20 21:39:09 CET 2004


On Friday 20 of February 2004 19:33, Marcin 'Qrczak' Kowalczyk wrote:
> using Foo.A; // Wprowadza funkcje foo() i bar()
> macro m() {
>   <[
>     defrule bar {...}; // defrule to jakieś śmieszne makro
>     foo() + bar()
>   ]>
> }

Kluczowe pytanie czy 'def bar' jest widoczne tutaj czy dopiero po ekspansji 
makra.
Jeśli tutaj, to luz, zostanie automatycznie związane z 'bar()', jeśli 
natomiast sama definicja bar jest dopiero wyprodukowana przez ekspansję
to tej intencji co piszesz nie zachowamy. Na szczęście mam na to lepszą
odpowiedź - zasłonię się regułą lexical-scoping, bar zostanie związane z tym, 
co jest widoczne (a nie wygenerowane) w miejscu definicji makra. Czyli
nawet jeśli defrule wygeneruje 'def bar =' to prawidłowym zachowaniem jest 
związanie 'bar()' z Foo.A.bar. Jeśli ktoś chce inaczej, to to jest 
niehigieniczność i powinien sobie z tym poradzić robiąc z 'bar' jakiś 
NewSymbol (). 

Nie wiem, może w ten sposób ograniczamy się mocno, ale naprawdę zdziwię się, 
jeśli zobaczę program, w którym ta sterylność, bo to już nie jest tylko 
higieniczność, jest przydatna.

Ale jestem bardzo wdzięczny na wskazanie potencjalnych ulepszeń i luk w naszym 
podejściu. No i pewnie za jakiś czas (kiedy już będzie pierwsza implementacja 
naszego podejścia będzie gotowa) spróbuję wprowadzić coś bardziej 
skomplikowanego. Choć z naszej dyskusji nasuwa mi się, że to może przynieść
zbyt dużo kłopotów....  :) a może nie, o ile będzie naprawdę działać.

> Żeby je expandować, trzeba zmaterializować kawałek kodu wstawiany przez
> makro z wdolarkowanymi rzeczami. A żeby to zrobić i nie pomylić

Aha, my w ogóle zakładamy, że do makra nie da się przekazać $(...) ani
<[ ... ]> - te konstrukcje są rozwijane przed czymkolwiek, a co za tym idzie
tu nie moglibyśmy ich rozwinąć, bo ich wartość nie jest znana w tej 
kompilacji. Ale gdybyśmy implementowali wersję wypasioną, to to też trzeba 
przemyśleć.

> Najlepszy opis implementacji higienicznego systemu makr, jaki znam, jest
> w <http://www.cs.indiana.edu/~dyb/papers/syntactic.ps.gz>. Tyle że nie

Uhum, dzięki, dołożę do kolejki.

> Nie domyślałem mojego systemu do końca i nie jestem pewien, czy działa -
> tym bardziej go nie implementowałem. Ledwo mi się mieści w głowie.

No właśnie nasz system ma tą zaletę, że nawet mi się mieści w głowie - jest 
prosty i przejrzysty, więc może taki bedzie i dla userów.
"When in doubt, use brute force." -- Ken Thompson

>
> Ogólnie nazwy mają symbole, kolory i środowiska. Kolor jest listą
> unikalnych numerków, środowisk jest tyle ile elementów na tej liście.
> Główny program ma pusty kolor. Wstawienie cytatu dodaje unikalny element
> koloru oraz środowisko z miejsca definicji makra wszystkim nazwom, a
> wdolarkowane rzeczy są pozostawiane bez zmian.
>
> (U Dybviga tutaj jest inaczej: on robi jakieś podstawienia na nazwach
> w momencie rozwijania lambdy, które moim zdaniem u mnie są niepotrzebne;
> żeby złożoność nie ucierpiała, on robi te podstawienia leniwie;
> kolorowanie więc też musi być leniwe; technicznie to się komplikuje,
> kolorowane są wdolarkowane rzeczy a potem całość jeszcze raz i kolory
> się xorują, ale efekt chyba wychodzi podobny.)
>
> Jeśli teraz szukamy nazwy w środowisku, to najpierw sprawdzamy jego
> oryginalny kolor w pierwszym dołączonym środowisku - musi się zgadzać i
> symbol, i kolor; jeśli go tam nie ma, to znaczy że makro się rozwinęło
> do wolnego wystąpienia i szukamy jej z kolorem obciętym do ogona w
> kolejnym środowisku; i tak dalej, a na końcu szukamy z pustym kolorem
> w bieżącym środowisku.
>
> Funkcja implicit produkuje nazwę pokolorowaną tak jak nazwa makra użyta
> w jego wywołaniu, czyli makro udaje, że tę nazwę wpisał ten kto wołał
> makro. Symbol jest podany, a kolor i środowiska są brane z wystąpienia
> nazwy makra. W Schemie nazwa makra jest mu podana wprost i on ją sobie
> może przekazać jako argument datum->syntax-object, a u mnie zamiast
> jawnego przekazania wzorcowej nazwy kolor jest zawsze brany z
> wystąpienia nazwy makra z miejsca użycia. Sama funkcja implicit jest
> przekazana makru niejawnie (bo w różnych makrach jest różna).
>
> Główne komplikacje, jakich jeszcze nie rozpracowałem, to środowiska
> różnych metapoziomów. Czyli pytanie, co jest dostępne w języku używanym
> w treści makr, sama realizacja wykonywania przed chwilą kompilowanego
> kodu, odkładanie skompilowanego kodu makr na dysku (nie wiem, czy nie
> trzeba będzie serializować tych środowisk - jeśli tak, to trzeba jakoś
> poprawić system, żeby nie trzeba było) i widoczność nazw wprowadzanych
> przez wzajemnie rekurencyjne definicje, z których jedne definiują makra,
> a inne ich używają. Co do tego ostatniego, chyba trzeba będzie dzielić
> program na segmenty między definicjami makr i analizować je osobno,
> zabraniając odwoływania się z dołu do góry (bez makr wszystkie nazwy są
> widoczne we wszystkich definicjach).

No ideę chyba widzę. Zobaczymy... Ale na razie mamy podejście zrobić coś 
prostego co działa, a potem komplikować - w tej chwili mamy świetnie 
działający system niehigieniczny - ktoś coś zepsuje, to z bardzo dużym
prawdopodobieństwem zepsuje mu się w jakimś momencie kompilacji.

Niewątpliwie nasza dyskusja jest bardzo konstruktywna, przynajmniej na 
przyszłość.

Kamil




More information about the devel-pl mailing list