[nem-pl] Uwagi różne

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Fri Feb 20 00:26:30 CET 2004


W liście z śro, 18-02-2004, godz. 23:11, Kamil Skalski pisze:

> :) join us 

Na razie mam dużo innych zajęć i będę tylko kibicował.

> To już chyba tak jest, że gdy ktoś coś wymyśli (Meta-Haskell, Meta-ML), to 
> idee szybko się rozprzestrzeniają i zostają ulepszane.

Do mnie makra akurat przyszły przez Scheme. W szczególności dolarki
przez quasiquotations, które stosowane do list są głupie, ale do kodu są
dobre. Scheme ma dobre założenia systemu syntax-case (parsowanie źródła
w abstrakcyjne drzewko przed rozwinięciem makr; higiena domyślnie,
łamalna przez funkcję zamieniającą goły symbol w identyfikator koloru
wziętego z kontekstu użycia makra), trochę gorsza realizacja (język i
metajęzyk w tej samej przestrzeni nazw; niewygodna składnia przez
wciśnięcie wszystkiego w sexpry; samo syntax-case niestandardowe,
a sensowne traktowanie metapoziomów - opisane w
<http://www.cs.utah.edu/plt/publications/macromod.pdf> - jeszcze
bardziej niestandardowe).

> W tej chwili wyzwaniem dla nas jest wymyślenie czegoś ładnego do operacji na  
> definicjach typów:

Bo macie statyczny system typów :-)

> mamy klasy Produkt, ProduktDuzy, .... i chcemy napisać makro, które doda do 
> nich metodę DumpToFile zapisującą wartości pól klasy gdzieś tam.

U mnie to jest funkcja, a nie makro. To nic, że trochę mniej efektywna.

> Skłaniamy się ku czemuś w stylu
> def l = c.Fields ();
> def body = <[ $(uzywamy l) ]>;
> c.AddMethod ("DumpToFIle", <[ type : void ]>, body);

Strzelałbym w coś takiego:

macro MakeDumperFor (c) : decl {
   def l = c.Fields ();
   def f = <[ f ]>; // gensym
   <[
      add_methods_for $c {
         // Nie wiem, jak u Was można dodawać metody do klasy po jej
         // zdefiniowaniu, jeśli w ogóle można. Jeśli nie można, to
         // język jest ograniczony.
         def DumpToFile ($f : file) : void {
            $(uzywamy l)
         }
      }
   ]>
}

Trzeba pilnować, co jest na poziomie programu, a co na metapoziomie.
O ile pobieranie informacji o klasie jest tu konieczne na metapoziomie,
jeśli chcemy generować przystosowany do danego zestawu pól kod, o tyle
byłoby niepokojące, jeśli dodanie metody do klasy polegałoby na skutku
ubocznym wykonania odpowiedniego makra zamiast na wyprodukowaniu przez
makro jakiejś deklaracji. Chyba że .NET to wyklucza, wtedy pewnie tak
jak piszesz.

> Dużo więcej o makrach jest w pracy, którą piszę 
> (http://www.nemerle.org/metaprogramming.ps).

Dziękuję, poczytam.

> <[ def $("g" : var) (x) { x + "aa" }; $("g" : var) ("bb") ]> a tutaj 'g' 
> zostanie wklejone w wynikowy kod takie jakim jest.

To znaczy złapie które wystąpienia "g" ze źródła / innych makr? Jeśli
wszystkie, to higiena jest iluzją i nigdy nie można być pewnym, że
identyfikator użyty lokalnie w rozwinięciu makra będzie prywatny dla
tego rozwinięcia. Trzeba kolorować na podstawie jakiegoś identyfikatora.

Co ma z kolei inny problem, AFAIK nieunikniony - jeśli jedno makro
niehigienicznie wprowadza jakiś identyfikator, a inne rozwija się do
użycia tego makra, to ten identyfikator będzie łapany tylko w treści
makra, a nie w kodzie, który go używa. Czasem to jest to, o co nam
chodzi, a czasem nie. Jeśli nie, to trzeba go ręcznie przeprowadzić do
nowego kontekstu, tzn. w tym drugim makrze też go jawnie niehigiencznie
wprowadzić jako alias na ten identyfikator wprowadzony przez pierwsze
makro.

Analogicznie jest przy niehigienicznym użyciu identyfikatora
wprowadzonego przez kod z kontekstu użycia makra.

> zastanawia mnie tylko jedna rzecz, którą uporczywie panowie od Haskella 
> powtarzają tu i tam:
> def x = <[ 1 ]>;
> def y = <[ x + 5 ]>
> 
> to u nich jest całkiem sensowny kod, a wg nas to totalne pomiszanie języka z 
> meta-językiem,

Zgadzam się, ale nie słyszałem, żeby oni coś takiego chcieli (nie
czytałem ich dokładnie ani ostatnio).

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





More information about the devel-pl mailing list