Implementacja identikon w PLT Scheme

Synthroid Without Prescription Inderal No Prescription Nexium For Sale Prevacid Generic Buy Elimite Online Prevacid Without Prescription Ultram No Prescription Prevacid For Sale Ultram Generic Buy Prednisone Online

Gdy w sieci przeczyta??em o identikonach o wiele bardziej urzek??a mnie estetyka ich wyglÄ?du ni?? ich techniczne zalety. Identikony, w formie zaimplementowanej przez Dona Parka, s??u??yÄ? majÄ? jako graficzna reprezentacja to??samo??ci osoby w sieci. Za??o??enie jest takie, ??e kolorowe wzory sÄ? ??atwiejsze do por??wnania i zapamiÄ?tania przez cz??owieka, ni?? numer IP. Dodatkowo, przepuszczajÄ?c IP u??ytkownika przez funkcjÄ? haszujÄ?cÄ? z sekretnym ziarnem mo??emy zachowaÄ? w??a??ciwo??ci identyfikujÄ?ce bez potrzeby ujawniania samego numeru IP.

BÄ?dÄ?c zainteresowany samymi wzorami, szybko odnalaz??em opis sposobu ich generowania i zaczÄ???em zastanawiaÄ? siÄ? nad implementacjÄ?. Pomy??la??em bowiem, ??e to ??wietna okazja na wypr??bowanie mo??liwo??ci Scheme i bli??sze poznanie wybranego ??rodowiska. Pad??o na PLT, g????wnie ze wzglÄ?du na mojÄ? wcze??niejszÄ? z nim styczno??Ä? i dobre do??wiadczenia wyniesione z eksperyment??w w DrScheme.

Jak siÄ? p????niej dowiedzia??em, bloczki, z kt??rych zbudowane sÄ? identikony, zosta??y poczÄ?tkowo opisane przez Jareda Tarbella na podstawie majÄ?cej d??ugÄ? historiÄ? sztuki quiltu. A to z kolei pamiÄ?tam, ??e gdzie?? ju?? widzia??em.

Przede wszystkim zachÄ?cam do ??ciÄ?gniÄ?cia i wypr??bowania kodu. Do prawid??owego dzia??ania wymaga on PLT z serii 3.99 (lub 4.0, kt??ry ma wyj??Ä? ca??kiem nied??ugo). Poni??ej za?? kilka komentarzy i wniosk??w, kt??re nasunÄ???y mi siÄ? podczas implementacji.

BibliotekÄ? wrzuci??em na PlanetÄ? PLT, by jej u??yÄ? wystarczy wiÄ?c jedna linijka kodu:
(require (planet “identicons.ss” (“mk” “identicons.plt”)))
Implementacja identikon zostanie automatycznie ??ciÄ?gniÄ?ta i zainstalowana.

System obiektowy

System obiektowy PLT Scheme funkcjonalnie nie r????ni siÄ? bardzo od tych zawartych w jÄ?zykach takich jak Java, Python, czy Ruby. Filozofia jest jednak trochÄ? inna, g????wnie z tej przyczyny, ??e system obiektowy nie jest podstawÄ? jÄ?zyka, ale jednym z wielu sposob??w organizacji programu. Po za??adowaniu modu??u scheme/class nie do??wiadczymy wiÄ?c wielkich zmian. Podstawowe typy danych, takie jak liczby, symbole, czy ciÄ?gi znak??w nie zostajÄ? wciÄ?gniÄ?te w hierarchiÄ? klas. PrawdÄ? m??wiÄ?c, poza klasÄ? object% i interfejsem externalizable<%> hierarchia ta jest ca??kiem pusta i zadanie wype??nienia jej le??y w rÄ?kach programisty. Po bibliotekach standardowych pÄ?kajÄ?cych od podstawowych klas i obiekt??w jest to ca??kiem od??wie??ajÄ?ce do??wiadczenie, muszÄ? przyznaÄ?. W za??o??eniu tw??rc??w PLT obiekty majÄ? s??u??yÄ? do sprawnego zamodelowania dziedziny problemu, przed jakim staje programista. A do tego nie potrzeba baga??u historycznego jaki czÄ?sto niosÄ? ze sobÄ? hierarchie starszych jÄ?zyk??w obiektowych.

Podstawowe konstrukcje sÄ? do??Ä? dobrze opisane w dokumentacji, a pomiÄ?dzy liniami mo??na te?? poznaÄ? kilka konwencji. Nazwy klas ko??czÄ? siÄ? %, a nazwy interfejs??w <%>. W obrÄ?bie wyra??enia definiujÄ?cego klasÄ? dostÄ?pnych jest kilka form specjalnych s??u??Ä?cych do definiowania atrybut??w i metod. Do komfortowej pracy wystarczy znajomo??Ä? czterech z nich:

  • init-field do definiowania atrybut??w, kt??re mo??e ustawiÄ? u??ytkownik podczas tworzenia obiektu
  • field do definiowania pozosta??ych atrybut??w
  • define/public do definiowania publicznych metod
  • define do definiowania metod prywatnych

Dla przyk??adu przyjrzyjmy siÄ? implementacji identikony:

(define identicon%
  (class object%
    (init-field seed)
 
    (field (32-bits            (make-bit-stream seed))
           (center-patch-shape (list-ref center-patch-shapes (32-bits 2)))
           (side-patch-shape   (list-ref patch-shapes (32-bits 4))))
 
    (define (get-patch-size dc))
 
    (define/public (draw dc))
 
    (super-new)))

Kod zdaje siÄ? m??wiÄ? sam za siebie. seed jest atrybutem ustawianym podczas konstrukcji obiektu. 32-bits, center-patch-shape i side-patch-shape sÄ? ukrytymi atrybutami przyjmujÄ?cymi zadane warto??ci. Warte zauwa??enia jest to, ??e 32-bits zale??y od atrybutu seed, podczas gdy samo 32-bits jest u??ywane w nastÄ?pujÄ?cych po nim definicjach. get-patch-size jest metodÄ? dostÄ?pnÄ? tylko dla pozosta??ych metod tej klasy (czyli jest metodÄ? prywatnÄ?), a draw jest metodÄ? publicznÄ?. Wywo??anie (super-new) ko??czÄ?ce definicje klasy jest potrzebne do w??a??ciwej inicjalizacji obiektu przez nadklasÄ? object%.

Konstrukcja obiekt??w jest bezbolesna. Przyk??adowo, by utworzyÄ? nowÄ? identikonÄ? wystarczy napisaÄ?:

(make-object identicon% 1234567890)

i dostaniemy z powrotem identikonÄ? pokazanÄ? poni??ej. By zapisaÄ? identikonÄ? do pliku, wystarczy wywo??aÄ? na niej metodÄ? save-to-file z podaniem nazwy pliku i rozmiarem identikony w pikselach:

(send identicon save-to-file “1234567890.png” 200)

O ile do tego momentu nie mia??em wiÄ?kszych zastrze??e?? do systemu obiektowego PLT to do sposobu wywo??ywania metod muszÄ? siÄ? ju?? przyczepiÄ?. :-) System obiektowy z przekazywaniem komunikat??w (ang. message passing) moim zdaniem idzie trochÄ? na przek??r lispowej filozofii. Common Lispowe procedury og??lne (ang. generic procedures) nie do??Ä?, ??e potÄ???niejsze, to moim zdaniem bardziej idÄ? z duchem Lispa. Pisanie kodu podobnego do:

(send identicon draw 30)

wydaje siÄ? nienaturalne, umieszczajÄ?c nazwÄ? wykonywanej operacji dopiero na trzeciej pozycji wyra??enia. NaturalnÄ? sk??adniÄ? dla wo??ania metody draw jest nastÄ?pujÄ?ca postaÄ? powy??szego wyra??enia:

(draw identicon 30)

Co prawda, mo??na by zaczÄ?Ä? dodawaÄ? dla wszystkich metod publicznych odpowiadajÄ?cÄ? im procedurÄ?, np.:

(define (draw object . args)
  (send/apply object draw args))

i mo??e nawet powiÄ?zaÄ? ten efekt z define/public, ale wtedy mieliby??my ju?? nowy system obiektowy, ??amiÄ?cy ??wiÄ?tÄ? w ??wiecie Scheme makrowÄ? higienÄ?. Oczywi??cie ??wiat nie jest czarno-bia??y i istniejÄ? zalety podej??cia u??ywanego przez PLT. Jednym z niewÄ?tpliwych plus??w jest fakt, ??e jedynym symbolem, jaki trzeba eksportowaÄ? z modu??u jest nazwa klasy - nazwy metod bowiem rozwijane sÄ? jedynie w kontek??cie konkretnego obiektu. Metody “podÄ???ajÄ? za” obiektami, co w systemie z przekazywaniem komunikat??w ma sens.

W PLTowym pakiecie Swindle jest dostÄ?pny system obiektowy bli??szy Common Lispowemu CLOSowi, bÄ?dzie wiÄ?c jeszcze okazja przyjrzeÄ? siÄ? innemu podej??ciu.

InnÄ? ciekawostkÄ? zwiÄ?zanÄ? ze standardowym PLTowym systemem obiektowym jest to, ??e klasy same nie sÄ? obiektami:

(object? identicon%) ;; => #f 
 

Nie mo??emy wiÄ?c na nich wywo??ywaÄ? metod i definiowaÄ? atrybut??w. Nie jest to jednak potrzebne, w PLT istniejÄ? bowiem modu??y, w kt??rych mo??emy zawrzeÄ? zar??wno lokalny stan, jak i grupÄ? procedur. O zabawach z metaklasami mo??emy jednak zapomnieÄ? (co prawdopodobnie jÄ?zykowi wychodzi na zdrowie ;-).

Modu??y i kontrakty

Wraz z nadej??ciem R6RS doczekali??my siÄ? standardowego wsparcia dla modu????w (bibliotek) w Scheme, zanim jednak ten czas nastÄ?pi?? ka??da z implementacji musia??a rozwiÄ?zaÄ? ten problem po swojemu. Modu??y w PLT, w ograniczonym zakresie jakim mia??em okazjÄ? ich u??ywaÄ?, spe??niajÄ? swojÄ? funkcjÄ? doskonale. By obudowaÄ? ca??Ä? zawarto??Ä? pliku w modu?? wystarczy dodaÄ? na jego poczÄ?tku linijkÄ? z okre??leniem u??ywanego podzbioru jÄ?zyka przy pomocy #lang. Przyk??adowo, by u??yÄ? jÄ?zyka rozszerzonego o mo??liwo??ci operowania oknami i grafikÄ? nale??y u??yÄ?:

#lang scheme/gui

OsiÄ?gamy w ten spos??b efekt podobny do modu????w pythonowych - ka??dy plik stanowi modu??, kt??rego nazwa wywodzi siÄ? bezpo??rednio z nazwy pliku, z pominiÄ?ciem rozszerzenia. Plik identicons.scm zawiera wiÄ?c modu?? o nazwie identicons.

Pr??cz tej jednej linijki modu?? prawdopodobnie nie bÄ?dzie wymaga?? ??adnych zmian. require wciÄ??? dzia??a, a wszystkie definicje sÄ? szczelnie zamkniÄ?te dla zewnÄ?trznego ??wiata. UdostÄ?pnianie symboli na zewnÄ?trz odbywa siÄ? przy pomocy formy specjalnej provide, ja jednak od pierwszego wejrzenia zakocha??em siÄ? w formie provide/contract. Przy jej pomocy bowiem mo??emy nie tylko okre??liÄ? eksportowane symbole, ale r??wnie?? okre??liÄ? kontrakt, kt??ry bÄ?dzie obowiÄ?zywa?? pomiÄ?dzy modu??em, a jego u??ytkownikiem. Przyk??adowo, kontrakt funkcji degrees->radians zdefiniowanej w module util wyglÄ?da nastÄ?pujÄ?co:

[degrees->radians (number? . -> . number?)]

Oznacza on, ??e degrees->radians jest funkcjÄ?, kt??ra oczekuje liczbÄ? jako argument i obiecuje zwr??ciÄ? liczbÄ?. Proste. Jak widaÄ?, kontrakty mogÄ? s??u??yÄ? do dynamicznego sprawdzania typ??w, ale ich mo??liwo??ci siÄ?gajÄ? daleko poza. Kontrakt mo??na zbudowaÄ? z dowolnego predykatu, a te mogÄ? sprawdzaÄ? nie tylko typ, ale i warto??ci i stan obiekt??w przekraczajÄ?cych granice kontraktu. ??wietne w kontraktach jest to, ??e sÄ? ca??kowicie opcjonalne. Nie ma wiÄ?c ??adnego problemu w tym, by dojrzalsze czÄ???ci budowanego przez nas systemu posiada??y kontrakty i jednocze??nie wsp????pracowa??y z nowszymi modu??ami, kt??rych projekt wciÄ??? jest niejasny - a przez to - pozbawiony kontrakt??w. Poza oczywistymi wzglÄ?dami technicznymi kontrakty posiadajÄ? r??wnie?? niewÄ?tpliwÄ? warto??Ä? dokumentacyjnÄ?. Odpowiednio dobrane nazwy predykat??w mogÄ? wiele powiedzieÄ? o oczekiwaniach, jakie k??adziemy na argumenty funkcji i o obietnicach jakie sk??adamy co do warto??ci przez te funkcje zwracanych.

Co ciekawe, kontrakty mo??na stosowaÄ? nie tylko w kontek??cie modu????w, ale r??wnie?? bezpo??rednio do definicji, jak i do metod i atrybut??w obiekt??w.

Sk??adnia infixowa

Jak wspomina przypis na stronie dokumentacji kontrakt??w PLT Scheme udostÄ?pnia specjalnÄ? sk??adniÄ? z dwoma kropkami. Jej dzia??anie jest bardzo proste. Ka??de wyra??enie o postaci:

(a b . x . c d)

przekszta??cane jest na:

(x a b c d)

jeszcze przed interpretacjÄ?. Opr??cz tego, ??e sk??adnia ta jest bardzo przydatna przy definiowaniu kontrakt??w, mo??na jÄ? (nad)u??yÄ? chocia??by do pisania wyra??e?? algebraicznych. Przyk??adowo:

(a . * . (b . + . c))

jest tym samym co:

(* a (+ b c))

Osobi??cie jednak odradza??bym posuwanie siÄ? z u??yciem tego sk??adniowego lukru zbyt daleko. ;-)

NarzÄ?dzia graficzne

Moje zainteresowanie grafikÄ? w PLT zaczÄ???o siÄ? od tego wspania??ego tutoriala wstÄ?pnego. Polecam go tym, kt??rzy chcÄ? zaczÄ?Ä? przygodÄ? z Lispem, ale nudzi ich operowanie wy??Ä?cznie na liczbach. A w zasadzie to polecam go ka??demu, tak dobry jest. :-)

Niestety do implementacji identikon biblioteka prezentacyjna jest niewystarczajÄ?ca. G????wnym jej minusem jest brak mo??liwo??ci obracania obiekt??w graficznych. Indeks szybko jednak zaprowadzi?? mnie do metody rotate klasy dc-path%, kt??ra to stanowi czÄ???Ä? wiÄ?kszej biblioteki graficznej dostÄ?pnej wraz z PLT. Klasa dc-path% umo??liwia narysowanie, wype??nienie i manipulacje dowolnym kszta??tem, z??o??onym z odcink??w, czy ??uk??w. Konstrukcja takiej ??cie??ki jest bardzo prosta. Przyk??adowo, by narysowaÄ? tr??jkÄ?t najpierw tworzymy nowy obiekt dc-path%:

Ca??y poni??szy kod musi byÄ? uruchamiany z linii polece?? mred lub w ??rodowisku drscheme; funkcjonalno??Ä? graficzna nie jest dostÄ?pna z poziomu mzscheme.

(define path (make-object dc-path%))

Po tym okre??lamy punkt startowy (”punkt przy??o??enia o????wka do kartki”):

(send path move-to 0 0)

i zaczynamy rysowaÄ? jednÄ? z dostÄ?pnych metod, przyk??adowo line-to:

(send path line-to 100 100)
(send path line-to 0 100)
(send path line-to 0 0)

??eby zobaczyÄ? efekt musimy przygotowaÄ? odpowiedni kontekst do rysowania (ang. drawing context), czyli w praktyce cokolwiek, co implementuje interfejs dc<%>. Skorzystajmy z kodu identikon i u??yjmy do tego celu zwyk??ej ramki (czy te?? “okna”):

(define (make-frame-dc)
  (let* ((frame (new frame% (label “New frame”) (width 200) (height 200)))
         (canvas (new canvas% (parent frame))))
    (send frame show #t)
    (sleep/yield 1)
    (send canvas get-dc)))

Utw??rzmy wiÄ?c w??a??ciwy obiekt i narysujmy na nim nasz tr??jkÄ?t:

(define dc (make-frame-dc))
(send dc draw-path path)

W tym momencie na ekranie powinni??my zobaczyÄ? zarys tr??jkÄ?ta. Pokolorowanie go to tylko kwestia u??ycia odpowiedniego pÄ?dzla. Wybierzmy dla niego jaki?? pozytywny kolor i przerysujmy nasz tr??jkÄ?t ponownie (oczywi??cie wszystko bez restartowania interpretera, czy otwierania nowej ramki):

(send dc set-brush “green” ’solid)
(send dc draw-path path)

Gotowe, nasz tr??jkÄ?t jest teraz zielony. A stÄ?d ju?? niedaleko do generowania kolorowych identikon. Po szczeg????y zapraszam do ??r??de??.

Wnioski

PodsumowujÄ?c, PLT jest dojrza??Ä? i bogatÄ? w rozszerzenia implementacjÄ? jÄ?zyka Scheme. DziÄ?ki obszernej i dok??adnej dokumentacji ??atwo siÄ? jej nauczyÄ? i korzystaÄ? z jej mo??liwo??ci. Dla tych, kt??rzy wolÄ? zaczÄ?Ä? od ??agodniejszej ni?? strony dokumentacji lektury jest blisko z PLT zwiÄ?zana ksiÄ???ka “How to Design Programs”. Tw??rcy PLT nie bojÄ? siÄ? eksperymentowaÄ? - dystrybucja PLT pe??na jest ciekawych minijÄ?zyk??w i odwa??nych pomys????w, jest wiÄ?c prawdziwÄ? kopalniÄ? wiedzy dla zainteresowanych mo??liwo??ciami Scheme i implementacjÄ? jÄ?zyk??w programowania og??lnie.Viagra versus levivia Feldene Women using viagra Accutane Xanax and pregnancy Information phentermine Indomethacin Adipex phentermine xenical Cefamandole Adenosine Lanoxin Tramadol cod Oxprenolol Methylergonovine Ibuprofen Nicorette Pulmonary hypertension and viagra Probucol Cialis drug impotence Cialis impotence drug eli lilly co Lortab and xanax without a prescription Levivia viagra compared Meropenem Viagra herbal alternative Saccharin Flexeril Colace Buy phentermine online same day delivery Mecamylamine Phentermine dangers Info on meridia Aldara Cheap price on phentermine Reglan Purchase xanax Hydrocodone ap ap Cialis soft Levoxyl Buy phentermine with no prescription Pyridoxine Cialis drug for impotence Order buy phentermine online Metronidazole Pharmacy phentermine sister Ipratropium Fioricet Clomocycline Cheap pharmacy viagra Pentaerythritol Buy hydrocodone overnight Xanax dosage Amiodarone 10 min viagra Voltaren Viagra drug Low natural resources for the drug phentermine Phentermine side effects Order cheap phentermine Paxil Lowest price on phentermine Lexapro interaction with phentermine Cialis price Zithromax Lotrel Arava Decamethonium Arthrotec Approval cialis Cope Levivia and viagra Xanax for sale Adipex diet phentermine pill prescription Potassium Buy cialis viagra Pain medication tramadol Diet ingredient phentermine pill Dangers of phentermine heart Terbutaline Saturday delivery phentermine Killer pain tramadol Ambien rx Cardizem Viagra sample pack Cheap tramadol prescriptions online Meridia weight loss pill Isoniazid Cod online pharmacy phentermine sell Phentermine in florida Generic viagra overnight delivery Dexbrompheniramine Hydrocodone picture Canadian cialis Cialis sales uk Lopressor Xanax no rx Xanax death About phentermine Cialis immunity Viagra kaufen Buy generic viagra online Phentermine hc Podophyllum Ipodate Octreotide Real phentermine Xanax pictures Kaopectate Lamivudine Herbal alternative to viagra Phentermine blue 30 mg Valsartan Anafranil Norgestrel Lansoprazole Tramadol online pharmacy Budesonide Phentermine blogging Mephenytoin Ditropan Order viagra now Keflex Phentermine with no prescription Difference between cialis and viagra Ambien overdose Tramadol hydrochloride tablet Cialis review Phentermine 37.5 mg free shipping Online pharmacies with doctor consultation for viagra Busulfan Phentermine prescribed online Buying tramadol online Levivia viagra online Phentermine worldwide shipment Phentermine ephedrine Estrone Phentermine 37.5 mg sale Viagra commercial Nasalcrom Shipping overnight phentermine Phentermine without doctor’s approval Actonel Phentermine credit card or cod _cialis et levitra How long does xanax stay in your body Ethotoin Where can i buy phentermine Buy Atarax Zidovudine Order soma carisoprodol Macrodantin

Komentuj wpis