eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programming › Makra higieniczne w jezyku Scheme
Ilość wypowiedzi w tym wątku: 14

  • 1. Data: 2014-11-11 23:36:57
    Temat: Makra higieniczne w jezyku Scheme
    Od: g...@g...com

    W kolejnym poscie zamieszczam czwarty rozdzial swojego wywodu
    o makrach w Schemie.

    Poruszam w nim temat makr higienicznych "syntax-rules", starajac sie
    przy tym pokazac, jakie problemy rozwiazuja, a jakie tworza nowe.

    Sympatycy ogonkow moga sobie sciagnac zaktualizowana wersje PDF stad:
    https://bytebucket.org/panicz/slayer/raw/f62eab57112
    287c619310e72de5c17d9dc44cb1e/doc/makra.pdf


  • 2. Data: 2014-11-11 23:37:23
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: g...@g...com

    * MAKRA OPARTE NA PRZEKSZTALCANIU WZORCOW (syntax-rules)

    ** PROBLEMY Z "define-macro"

    W poprzednim rozdziale udalo sie uzyskac dosc zgrabna metodologie pisania
    makr, ktore sa stosunkowo proste w analizie. Pewien problem dotyczyl
    destrukturyzacji danych wejsciowych do makra -- uzywalismy do tego
    funkcji zbudowanych w oparciu o funkcje car i cdr.

    Innym problemem bylo to, ze moglismy niechcacy stworzyc makro, ktore
    wprowadza jakas zmienna kolidujaca z istniejaca zmienna. Z tym problemem
    jakos sobie poradzilismy, uzywajac funkcji gensym. Nalezy jednak zauwazyc,
    ze nie rozwiazuje to wszystkich mozliwych problemow. Niekiedy makro moze
    odnosic sie do jakichs zewnetrznych wiazan, ktore moglyby niechcacy
    zostac przesloniete przez uzytkownika makra w kontekscie jego uzycia.

    Na przyklad wartosc wyrazenia

    : (let ((if list))
    : (cond ((= 2 3) 'a)
    : (else 'b)))

    przy podanej wczesniej definicji makra "cond" moze okazac sie zaskakujaca:
    nie bedzie to bowiem symbol a, tak jak moglibysmy sie spodziewac, tylko lista
    (#f a (#t b)).

    Moglibysmy zatem oczekiwac od naszego systemu makr, zeby zachowywaly
    "przezroczystosc odniesieniowa", tzn. zeby uzywane w nich identyfikatory
    odnosily sie do wartosci z kontekstu definicji makra, a nie z do wartosci
    z kontekstu jego uzycia (chyba ze zazadamy tego explicite). Tylko bowiem
    w taki sposob mozemy uwolnic uzytkownika makr od koniecznosci martwienia
    sie jego szczegolami implementacyjnymi.

    Kolejnym problemem, o ktorym nie wspominalismy, byl brak mozliwosci
    tworzenia makr o ograniczonym zasiegu -- forma define-macro wprowadzala
    nowe makro w biezacym zasiegu. Dla odmiany, mozemy z latwoscia definiowac
    sobie pomocnicze funkcje wewnatrz innych funkcji. (Wprawdzie mozna
    sobie zdefiniowac makro pomocnicze wewnatrz funkcji, jednak nie mozna
    uzyc makra o ograniczonym zasiegu do utworzenia definicji w zasiegu
    globalnym.)

    ** ROZWIAZANIE: MAKRA HIGIENICZNE "syntax-rules"

    Standard R5RS jezyka Scheme definiuje trzy nowe podstawowe formy specjalne
    sluzace do definiowania makr, mianowicie define-syntax, let-syntax
    i letrec-syntax. W przeciwienstwie do define-macro, owe formy jako swoje
    argumenty przyjmuja procedury (np. stworzone przy pomocy wyrazen lambda).
    Specyfika tych procedur jest dosc skomplikowana i przyjrzymy sie jej blizej
    dopiero w nastepnym rozdziale.

    Tymczasem omowie pewna wtorna forme specjalna "syntax-rules", ktora
    ulatwia tworzenie odpowiednich procedur. Postac owej formy jest nastepujaca:

    : (syntax-rules (identyfikatory-specjalne ...)
    : ((wzorzec przeksztalcenie)
    : ...))

    Formy "wzorzec" i "przeksztalcenie" wyrazone sa w specjalnym jezyku
    wzorcow. Nie bedziemy zglebiac tego, w jaki sposob ow jezyk jest
    implementowany. Osoby zainteresowane moga zajrzec do implementacji
    stworzonej przez Abdulaziza Ghulouma i R. Kenta Dybviga w jezyku Scheme:

    https://www.cs.indiana.edu/l/www/chezscheme/r6rs-lib
    raries/

    Forma "wzorzec" jest odpowiedzialna za destrukturyzacje i opisuje,
    jakie jest zamierzone uzycie makra, natomiast forma "przeksztalcenie"
    jest odpowiedzialna za restrukturyzacje formy w terminach bardziej
    pierwotnych. Formy skladaja sie z dowolnie zagniezdzonych list
    symboli oraz ewentualnie specjalnego symbolu "..." (elipsy).

    Jezeli dane uzycie makra nie pasuje do danego wzorca, to procedura
    wygenerowana przez "syntax-rules" probuje je dopasowac do kolejnego
    wzorca, a jezeli zaden wzorzec nie pasuje do danego uzycia, procedura
    zglasza blad skladni.

    ** NOWA DEFINICJA FORMY "let"

    Zamiast szczegolowo wyjasniac jezyk wzorcow makra "syntax-rules",
    najlepiej przedstawic kilka praktycznych przykladow. Zaczniemy
    od redefinicji omowionego wczesniej makra "let". Nowa definicja,
    wyrazona w termiach jezyka wzorcow, bedzie miala postac:

    : (define-syntax let
    : (syntax-rules ()
    : ((let ((name value) ...) body + ...)
    : ((lambda (name ...) body + ...) value ...))))

    Warto zwrocic uwage na kilka rzeczy. Po pierwsze, nasza definicja
    wyglada prawie dokladnie tak, jak wczesniejsza specyfikacja makra "let".
    Glowna roznica jest taka, ze musimy owinac te specyfikacje w czarodziejskie
    zaklecie. Poza tym w specyfikacji nasz wielokropek traktowalismy nieformalnie,
    natomiast tutaj jest on uzyty jako literalny symbol o dobrze okreslonej
    semantyce -- musi on wystapic za jakims identyfikatorem (albo dowolnie
    zagniezdzona lista zawierajaca przynajmniej jeden zwykly identyfikator)
    i oznacza zero lub wiecej wystapien danego elementu.

    Ponadto, jezeli w formie "wzorzec" wielokropek wystepuje za jakims
    identyfikatorem (byc moze zagniezdzonym w liscie), to ilekroc uzyjemy
    tego identyfikatora w formie "przeksztalcenie", musimy za nim rowniez
    dostawic wielokropek.

    Kolejna uwaga dotyczy tego, ze w naszej definicji nazwa makra ("let")
    pojawia sie dwa razy: jako pierwszy argument formy "define-syntax" oraz
    jako pierwszy element formy "wzorzec".

    Tak naprawde tylko pierwsze z tych uzyc ma realne znaczenie -- pierwszy
    element formy "wzorzec" i tak jest ignorowany przez transformator, wiec
    mozna by bylo w jego miejsce wstawic dowolny symbol. Uzycie jakiegokolwiek
    symbolu innego niz nazwa makra mogloby byc mylace, ale powszechnie
    stosowanym idiomem jest uzywanie w tej pozycji symbolu "_":

    : (define-syntax let
    : (syntax-rules ()
    : ((_ ((name value) ...) body + ...)
    : ((lambda (name ...) body + ...) value ...))))

    Mozna tez zauwazyc, ze nasze makro jest stosunkowo proste -- wystepuje
    w nim tylko jedna para (wzorzec przeksztalcenie), zas lista
    identyfikatory-specjalne jest pusta.

    Do definiowania takich przypadkow moglibysmy zdefiniowac makro pomocnicze:

    : (define-syntax define-syntax-rule
    : ((_ (name . args) transfomation)
    : (define-syntax name
    : (syntax-rules ()
    : ((name . args)
    : transformation)))))

    Dzieki niemu nasza definicja przyjmie jeszcze prostsza postac:

    : (define-syntax-rule (let ((name value) ...) body + ...)
    : ((lambda (name ...) body + ...) value ...))

    ** NOWE DEFINICJE SPOJNIKOW LOGICZNYCH "and" i "or"

    Definicja formy "and" bedzie raczej prosta:

    : (define-syntax and
    : (syntax-rules ()
    : ((_ p)
    : p)
    : ((_ p q ...)
    : (if p (and q ...) #f))))

    Glowna roznica wzgledem poprzedniego makra jest taka, ze tym razem
    w formie "syntax-rules" pojawiaja sie dwa przypadki. Odpowiada to
    dwom przypadkom z formy "if" we wczesniejszym wariancie wyrazonym
    przy pomocy define-macro.

    Definicja formy "or" rowniez nie powinna nastreczac wiekszych trudnosci:

    : (define-syntax or
    : (syntax-rules ()
    : ((_ p)
    : p)
    : ((_ p q ...)
    : (let ((T p)) (if T T (or q ...))))))

    Skorzystalismy tutaj z faktu, ze makra zachowuja higiene, i transformator
    makr sam zadba o to, zeby uzyta przez nas nazwa zmiennej tymczasowej
    nie kolidowala z zadna nazwa wystepujaca w kontekscie uzycia makra.

    ** NOWA DEFINICJA FORMY "cond"

    : (define-syntax cond
    : (syntax-rules (else)
    : ((_ (else actions + ...))
    : (begin actions + ...))
    :
    : ((_ (condition actions + ...))
    : (if condition
    : (begin actions + ...)))
    :
    : ((_ (condition actions + ...) other-clauses ...)
    : (if condition
    : (begin actions + ...)
    : (cond other-clauses ...)))))

    Powyzsza definicja jest wprawdzie nieco dluzsza od tej wyrazonej
    przy pomocy define-macro, ale wydaje sie tez bardziej zrozumiala.
    Pojawil sie w niej wreszcie identyfikator specjalny "else", co stwarza
    okazje do wyjasnienia jego roli.

    Gdyby slowo kluczowe "else" nie znajdowalo sie na liscie identyfikatorow
    specjalnych, to dwa pierwsze wzorce w definicji makra bylyby nierozroznialne
    -- dla jezyka wzorcow w ogolnosci nie ma znaczenia, czy wystepujacy
    w nim symbol ma postac "condition", "else" czy jakakolwiek inna (za
    wyjatkiem symbolu "...").

    Umieszczenie slowka "else" na liscie identyfikatorow specjalnych sprawia,
    ze pierwszy wzorzec zostanie dopasowany tylko wtedy, gdy w przetwarzanej
    formie wystapi literalnie symbol "else".

    ** PROBA PONOWNEGO ZDEFINIOWANIA FORMY "while"

    W pierwszej chwili moglibysmy chciec zdefiniowac nasze makro "while"
    nastepujaco:

    : (define-syntax-rule (while condition actions ...)
    : (call/cc
    : (lambda (break)
    : (define (LOOP)
    : (if condition
    : (begin actions ... (LOOP))))
    : (LOOP))))

    Niestety, okazuje sie, ze oprocz tego, ze transformator makr ukrywa przed nami
    identyfikator "LOOP", to nie mamy tez sposobu, zeby dostac sie z zewnatrz
    do identyfikatora "break".

    Co gorsza, system makr syntax-rules robi wszystko, zeby nam ten dostep
    uniemozliwic, i chociaz w ogolnosci istnieja sposoby na omijanie higieny
    makr w tym systemie, sa one bardzo trudne, a ich zastosowanie powoduje
    powstanie kodu, ktorego analiza jest bardzo trudna.

    Jedyny "prosty" sposob obejscia tego problemu polega na tym, zeby uczynic
    slowo kluczowe sluzace do przerwania petli jednym z argumentow makra:

    : (define-syntax-rule (while/break break condition actions ...)
    : (call/cc
    : (lambda (break)
    : (define (LOOP)
    : (if condition
    : (begin actions ... (LOOP))))
    : (LOOP))))

    Trudno jednak uznac takie rozwiazanie za satysfakcjonujace. Znalezienie
    lepszego rozwiazania bedzie od nas wymagalo wyjscia poza system makr
    "syntax-rules" i przyjrzenia sie jego architektonice.


  • 3. Data: 2014-11-12 05:42:14
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: A.L. <a...@a...com>

    On Tue, 11 Nov 2014 14:36:57 -0800 (PST), g...@g...com
    wrote:

    >W kolejnym poscie zamieszczam czwarty rozdzial swojego wywodu
    >o makrach w Schemie.
    >
    >Poruszam w nim temat makr higienicznych "syntax-rules", starajac sie
    >przy tym pokazac, jakie problemy rozwiazuja, a jakie tworza nowe.

    A do czego to sie moze przydac?...

    A.L.


  • 4. Data: 2014-11-12 09:02:06
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: g...@g...com

    W dniu środa, 12 listopada 2014 05:42:15 UTC+1 użytkownik A. L. napisał:
    >
    > A do czego to sie moze przydac?...

    Zastosowaniom zamierzalem wprawdzie poswiecic osobny rozdzial,
    ale moge co nieco opowiedziec juz teraz. Ostatnio musialem napsiac
    taki kod w javascripcie:

    function allowedMoves(board, position) {
    var x = position[0];
    var y = position[1];

    var result = [];

    for(var i = x-1; i >= 0 && !board[i][y]; --i) {
    result.push([i,y]);
    }
    for(var i = x+1; i < board.length && !board[i][y]; ++i) {
    result.push([i,y])
    }
    for(var j = y-1; j >= 0 && !board[x][j]; --j) {
    result.push([x,j]);
    }
    for(var j = y+1; j < board[x].length && !board[x][j]; ++j) {
    result.push([x,j])
    }
    return result;
    }

    Sa tutaj cztery petle, z ktorymi niewiele tak naprawde mozna
    zrobic. Sa tez cztery okazje do popelnienia bledow. (Nawiasem
    mowiac, przy pisaniu tego kodu rzeczywiscie popelnilem blad,
    ktory byl dosc trudny do znalezienia)

    Gdybym mial w JS do dyspozycji system makr, moglbym napisac cos
    w stylu, powiedzmy

    function allowedMoves(board, position) {
    var x = position[0];
    var y = position[1];

    var result = [];
    var W = board.length;
    var H = board[0].length;

    with_syntax(mark($, <>, limit, n, over, p, q),
    for(var n = over $ 1; n <> limit && !board[p][q]; n = n $ 1) {
    result.push([p,q]);
    })
    {
    mark(-, >=, 0, i, x, i, y);
    mark(+, <, W, i, x, i, y);
    mark(-, >=, 0, j, y, x, j);
    mark(+, <, H, j, y, x, j);
    }
    return result;
    }

    Wprawdzie dlugosc kodu jest porownywalna, ale wszystkie pojawiajace
    sie w nim nietrywialne powtorzenia strukturalne zostaly wyekstrahowane
    do makra, co ulatwia utrzymanie kodu i zmniejsza mozliwosc popelnienia
    bledu.

    Pozniej postaram sie podac bardziej zaawansowane przyklady.


  • 5. Data: 2014-11-12 11:00:50
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: firr <p...@g...com>

    W dniu środa, 12 listopada 2014 09:02:07 UTC+1 użytkownik g...@g...com
    napisał:
    > W dniu środa, 12 listopada 2014 05:42:15 UTC+1 użytkownik A. L. napisał:
    > >
    > > A do czego to sie moze przydac?...
    >
    > Zastosowaniom zamierzalem wprawdzie poswiecic osobny rozdzial,
    > ale moge co nieco opowiedziec juz teraz. Ostatnio musialem napsiac
    > taki kod w javascripcie:
    >
    > function allowedMoves(board, position) {
    > var x = position[0];
    > var y = position[1];
    >
    > var result = [];
    >
    > for(var i = x-1; i >= 0 && !board[i][y]; --i) {
    > result.push([i,y]);
    > }
    > for(var i = x+1; i < board.length && !board[i][y]; ++i) {
    > result.push([i,y])
    > }
    > for(var j = y-1; j >= 0 && !board[x][j]; --j) {
    > result.push([x,j]);
    > }
    > for(var j = y+1; j < board[x].length && !board[x][j]; ++j) {
    > result.push([x,j])
    > }
    > return result;
    > }
    >
    jawaskrypt ciekawy jezyk, nieststy ciagle nie mam sily sie go nauczyc, tylko czasem
    wpadaja mi w oko kwiatki ktore rozumiem albo ktorych nie rozumiem

    mialbys moze chwile by wyjasnic mi co tutaj sie
    przykladowo dzieje


    io.sockets.on("connection", function (socket) {
    socket.unit = null;
    socket.on("connectServer", function (data, reply) {
    var unit = new IB.Player(data);

    worldHandler.addUnit(unit);
    }
    });

    mniej chodzi mi o sementyke ale o skladnie
    co to jest? cialo funkcji przekazywane jako argument? a dalej w srodku z tym
    socket.on to samo? sa to po prostu skrotowe zapisy by nie pisac 3 cial funkcji w
    trzech miejscach czy cos wiecej?


  • 6. Data: 2014-11-12 11:19:16
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: g...@g...com

    W dniu środa, 12 listopada 2014 11:00:53 UTC+1 użytkownik firr napisał:

    > jawaskrypt ciekawy jezyk, nieststy ciagle nie mam sily sie go nauczyc, tylko czasem
    wpadaja mi w oko kwiatki ktore rozumiem albo ktorych nie rozumiem
    >
    > mialbys moze chwile by wyjasnic mi co tutaj sie
    > przykladowo dzieje
    >
    > io.sockets.on("connection", function (socket) {
    > socket.unit = null;
    > socket.on("connectServer", function (data, reply) {
    > var unit = new IB.Player(data);
    >
    > worldHandler.addUnit(unit);
    > }
    > });
    >
    > mniej chodzi mi o sementyke ale o skladnie
    > co to jest? cialo funkcji przekazywane jako argument? a dalej w srodku z tym
    socket.on to samo? sa to po prostu skrotowe zapisy by nie pisac 3 cial funkcji w
    trzech miejscach czy cos wiecej?

    jest mniej wiecej tak jak mowisz. (jednak zamiast powiedziec, ze "cialo funkcji
    jest przekazywane jako argument", raczej bym powiedzial, ze "funkcja jest
    przekazywana jako argument")
    zgodnie z oczekiwaniem, moglbys alterniatywnie zapisac:

    function connectServerHandler(data, reply) {
    var unit = new IB.Player(data);
    worldHandler.addUnit(unit);
    }

    function connectionHandler(socket) {
    socket.unit = null;
    socket.on("connectServer", connectServerHandler);
    }

    io.sockets.on("connection", connectionHandler);

    nie ma duzej roznicy pomiedzy takim kodem, a np. kodem w C
    przekazujacym wskazniki do funkcji.

    w ogolnosci jednak sila ekspresji javascriptu jest wieksza,
    niz sila ekspresji C, poniewaz mozesz w js tworzyc tzw. "domkniecia"
    ("closures"), czyli funkcje ktore przechowuja swoje lokalne srodowisko.
    klasyczny przyklad wyglada tak:

    function make_counter() {
    var counter = 0;
    return function() { return ++counter; }
    }

    var c = make_counter();

    print c(); // 1
    print c(); // 2
    print c(); // 3

    w C mozesz oczywiscie uzyskac funkcjonalnie podobny efekt, przekazujac
    do funkcji osobna strukture (wiele bibliotek ma takie interfejsy, ze
    pobieraja wskaznik na funkcje i wskaznik void *, ktory funkcja
    ma sobie sama rzutowac do odpowiedniego typu)


  • 7. Data: 2014-11-12 11:41:42
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: firr <p...@g...com>

    W dniu środa, 12 listopada 2014 11:19:17 UTC+1 użytkownik g...@g...com
    napisał:
    > W dniu środa, 12 listopada 2014 11:00:53 UTC+1 użytkownik firr napisał:
    >
    > > jawaskrypt ciekawy jezyk, nieststy ciagle nie mam sily sie go nauczyc, tylko
    czasem wpadaja mi w oko kwiatki ktore rozumiem albo ktorych nie rozumiem
    > >
    > > mialbys moze chwile by wyjasnic mi co tutaj sie
    > > przykladowo dzieje
    > >
    > > io.sockets.on("connection", function (socket) {
    > > socket.unit = null;
    > > socket.on("connectServer", function (data, reply) {
    > > var unit = new IB.Player(data);
    > >
    > > worldHandler.addUnit(unit);
    > > }
    > > });
    > >
    > > mniej chodzi mi o sementyke ale o skladnie
    > > co to jest? cialo funkcji przekazywane jako argument? a dalej w srodku z tym
    socket.on to samo? sa to po prostu skrotowe zapisy by nie pisac 3 cial funkcji w
    trzech miejscach czy cos wiecej?
    >
    > jest mniej wiecej tak jak mowisz. (jednak zamiast powiedziec, ze "cialo funkcji
    > jest przekazywane jako argument", raczej bym powiedzial, ze "funkcja jest
    > przekazywana jako argument")
    > zgodnie z oczekiwaniem, moglbys alterniatywnie zapisac:
    >
    > function connectServerHandler(data, reply) {
    > var unit = new IB.Player(data);
    > worldHandler.addUnit(unit);
    > }
    >
    > function connectionHandler(socket) {
    > socket.unit = null;
    > socket.on("connectServer", connectServerHandler);
    > }
    >
    > io.sockets.on("connection", connectionHandler);
    >
    > nie ma duzej roznicy pomiedzy takim kodem, a np. kodem w C
    > przekazujacym wskazniki do funkcji.
    >
    > w ogolnosci jednak sila ekspresji javascriptu jest wieksza,
    > niz sila ekspresji C, poniewaz mozesz w js tworzyc tzw. "domkniecia"
    > ("closures"), czyli funkcje ktore przechowuja swoje lokalne srodowisko.
    > klasyczny przyklad wyglada tak:
    >
    > function make_counter() {
    > var counter = 0;
    > return function() { return ++counter; }
    > }
    >
    > var c = make_counter();
    >
    > print c(); // 1
    > print c(); // 2
    > print c(); // 3
    >
    > w C mozesz oczywiscie uzyskac funkcjonalnie podobny efekt, przekazujac
    > do funkcji osobna strukture (wiele bibliotek ma takie interfejsy, ze
    > pobieraja wskaznik na funkcje i wskaznik void *, ktory funkcja
    > ma sobie sama rzutowac do odpowiedniego typu)

    swietnie,
    moge dorzucic pare uwag

    1. nazwa handler tutaj jakiej uzywasz jest na pewno zła - powinno to sie nazywac
    raczej OnConnection, OnConnectServer - to słowo handeler wprowadza jezykową pianę i
    wydłuza 'językowo' kod a im krotszytym lepszy

    2. wiesz moze co te 3 funkcje wlasciwie robia?
    to pierwsze jest jakby jasne na sygnel polaczenia ustawia handler dla eventu
    connectServer - ale dlaczego to tak jest? tego jakos nie pojalem, to piwrwsze to jest
    pierwsze polaczenie a to drugie to sa eventy dla poszczegolnych przychodzących
    pakietow or what?

    3. jestes pewien ze to z closures jest to dzialajacy kod? nie do konca zrozumielem
    jak to dziala acz musze troche dluzej popatrzec

    4. system callbackow czy 'przekazywania funkcji do funkcji' w c jest raczej slaby,
    kiedys pisalem ntt i jeszcze kiedys pewnie napisze
    (ale nie teraz bo jest to glebszy temat)


  • 8. Data: 2014-11-12 12:11:37
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: g...@g...com

    W dniu środa, 12 listopada 2014 11:41:42 UTC+1 użytkownik firr napisał:
    >
    > swietnie,
    > moge dorzucic pare uwag
    >
    > 1. nazwa handler tutaj jakiej uzywasz jest na pewno zła - powinno to sie nazywac
    raczej OnConnection, OnConnectServer - to słowo handeler wprowadza jezykową pianę i
    wydłuza 'językowo' kod a im krotszytym lepszy

    to zalezy tez od konwencji przyjetych w reszcie projektu.
    ale nie do konca sie zgodze z tym, ze im kod krotszy tym lepszy.
    im kod bardziej zrozumialy, tym lepszy (w przeciwnym razie APL
    bylby najlepszym jezykiem programowania)

    w tym przypadku jednak moim celem bylo pokazanie rownowaznosci
    semantycznej dwoch form syntaktycznych, i mysle, ze temu celowi
    uzywanie nawet nieco rozwleklejszego zapisu sluzy dobrze.
    tak naprawde oryginalny kod jest pod wzgledem zwiezlosci lepszy
    od tego, co ja napisalem.

    > 2. wiesz moze co te 3 funkcje wlasciwie robia?
    > to pierwsze jest jakby jasne na sygnel polaczenia ustawia handler dla eventu
    connectServer - ale dlaczego to tak jest? tego jakos nie pojalem, to piwrwsze to jest
    pierwsze polaczenie a to drugie to sa eventy dla poszczegolnych przychodzących
    pakietow or what?

    pewnie musialbys poczytac wiecej o programowaniu sieciowym i o tej
    konkretnej bibliotece.
    na ile rozumem temat (zgadujac, ze kod jest oparty na gniazdach unixa),
    to jest tak, ze serwer nasluchuje na jednym porcie z ktorym zwiazane
    jest gniazdo, natomiast ilekroc jakis klient sie polaczy, jest tworzone
    nowe gniazdo do obslugi tego konkretnego klienta. Ale nie wiem.

    ten kod jest wziety z nodejs?

    > 3. jestes pewien ze to z closures jest to dzialajacy kod? nie do konca zrozumielem
    jak to dziala acz musze troche dluzej popatrzec

    jak masz chrome'a albo firefoxa, to mozesz wcisnac ctrl+shift+c,
    wejsc w konsole i wpisac ten kod i sprawdzic czy dziala.
    /* u mnie dziala */

    > 4. system callbackow czy 'przekazywania funkcji do funkcji'
    > w c jest raczej slaby, kiedys pisalem ntt i jeszcze kiedys pewnie napisze
    > (ale nie teraz bo jest to glebszy temat)

    jak to powiedzial Stanislaw Wyspanski, lepszen taken niz zaden (czy cos)


  • 9. Data: 2014-11-12 12:13:08
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: firr <p...@g...com>

    >
    > 4. system callbackow czy 'przekazywania funkcji do funkcji' w c jest raczej slaby,
    kiedys pisalem ntt i jeszcze kiedys pewnie napisze
    > (ale nie teraz bo jest to glebszy temat)

    to o czym pisałem bylo o tym (i to jest wazna uwaga) ze w c mozna przekazywac
    wskazniki na
    funkcje ale nie mozesz przekazac funkcji juz
    z argumentami, na przyklad powiedzmy ze
    mam funkcje profie() ktora mierzy czas wykonania (w nanosekundach) przekazanej jej
    funkcji

    profile( add(1,2,3) );

    profile( print(" [11:47] <omatkoboska> idę na szluga ") );

    profile( Beep(10,1000) );

    a takie cos jest b. potrzebne.. (skladnia jest zajeta ale mozna dodac jakies
    oznaczenie/slowo kluczowe informujace ze to nei ejst 'wywolywane na wejsciu tylko w
    srodku' itp)

    (co mozna zrobic w c to wiadomo.. tak jak zdaje sie mowisz mozna napisac sobie
    wrappery

    void add(void* args) { ....}
    void print(void* args) { ....}
    void Beep(void* args) { ....}

    i funkcje przyjmujaca te wrappery

    profile(pFunWrapper fun, void* args)
    {
    //... kod
    fun(args);
    // ... kod
    }
    )

    tymaczasem mozna by to w c zrobic automatycznie
    i jest to proste do zrobienia (czy to jest odpowiednik closures z innych jezykow to
    nie wiem, byc moze nie do konca bo te przekazywane funkcje nie maja tutaj dostepu do
    swoich jakichs tam kontekstow tylko po prostu ciagna swoje argumenty)

    druga rzecz ze tą warstwe kombinowanie funkci w c miedzy sobą mozna jeszcze o wiele
    bardziej rozbudowac o czym bylo pisane przeze mnie calkiem niedawno (chyba ze dwa
    tygodnie temu na plc)


  • 10. Data: 2014-11-12 12:20:17
    Temat: Re: Makra higieniczne w jezyku Scheme
    Od: g...@g...com

    W dniu środa, 12 listopada 2014 12:13:08 UTC+1 użytkownik firr napisał:
    > >
    > to o czym pisałem bylo o tym (i to jest wazna uwaga) ze w c mozna przekazywac
    wskazniki na
    > funkcje ale nie mozesz przekazac funkcji juz
    > z argumentami, na przyklad powiedzmy ze
    > mam funkcje profie() ktora mierzy czas wykonania (w nanosekundach) przekazanej jej
    funkcji
    >
    > profile( add(1,2,3) );
    >
    > profile( print(" [11:47] <omatkoboska> idę na szluga ") );
    >
    > profile( Beep(10,1000) );
    >
    > a takie cos jest b. potrzebne.. (skladnia jest zajeta ale mozna dodac jakies
    oznaczenie/slowo kluczowe informujace ze to nei ejst 'wywolywane na wejsciu tylko w
    srodku' itp)
    >
    > (co mozna zrobic w c to wiadomo.. tak jak zdaje sie mowisz mozna napisac sobie
    wrappery
    >
    > void add(void* args) { ....}
    > void print(void* args) { ....}
    > void Beep(void* args) { ....}
    >
    > i funkcje przyjmujaca te wrappery
    >
    > profile(pFunWrapper fun, void* args)
    > {
    > //... kod
    > fun(args);
    > // ... kod
    > }
    > )
    >
    > tymaczasem mozna by to w c zrobic automatycznie
    > i jest to proste do zrobienia (czy to jest odpowiednik closures z innych jezykow to
    nie wiem, byc moze nie do konca bo te przekazywane funkcje nie maja tutaj dostepu do
    swoich jakichs tam kontekstow tylko po prostu ciagna swoje argumenty)

    Akurat tego rodzaju rzeczy mozna dosc latwo rozwiazac przy pomocy
    makra preprocesora C:

    #define PROFILE(call) { \
    // ... kod \
    call; \
    // ... kod \
    }

strony : [ 1 ] . 2


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: