Smalltalk


Tato skolicka navazuje na skolicku o zakladech lispu

Obsah:


Uvod

No a dalsi lispove orientovanej jazyk je tu. Smalltalk je jazyk o kterym se docela hodne mluvi asi proto ze autori ho predelali pro mswokna a podobny prisernosti a delaji tam slavu. Ja osobne ho uz napovazuju za tak dobry jazyk. Ma hodne dobrych napadu ale ma jeden problem: Podarilo se jim tam zamotat syntaxi a nektery definice ze 100% smalltalk uz nejde ani interpretrovat. Presto je v nem moc dobrych napadu a hodne jazyku z neho vychazi (treba objektive c coz je vlastne smalltalk upraveny tak, aby se dal kompilovat a z trosku srovnanou syntaxi.

Vlastni navrh jazyka je celkem zajimavy. V lispovi jsme tak nejak svevolne dlouhym vyvojem dosli k tomu ze 70% jeho knihoven je objektovych. Jeho typy maji stromovou strukturu a celkove to hodne pripomina plne objektovy jazyk. (alespon nektere moderni implementace) Proto se autori rozhodli udelat jazyk co by narozdil od lispu byl objektovy uz od zacatku proste mel to ve vlastni implementaci jazyka. To by melo zjednodusit kompilaci protoze by tam nemusely takove 50 let stare archaismy jako v lispovi. Vsechny jeho konstrukce by byly objektove ne jako v lispu jenom cast kde se to hodi tudiz by byly jednodusi na zvladnuti jednotnejsi a rezsiritelnejsi. Jak se jim to povedlo posudte samy:

Hello word

zacnu prikladem hello word:

                'Hello, world' printNl !

Tady vidite ze format vyhodnocovatelne formy se zmenil. Hlavni uprava spociva v tom ze jako prvni se pise objekt se kterym neco delate - v tomto pripade 'Hello, world' ktery reader precte do stringoveho objektu. Jake druhe je zprava co mu chcete poslat tedy printNl coz je ocividne zprava co ho ma vypsat. ! oznacuje konec formy a znamena neco jako run v basicovi neboli ted to odstartuj. Takze v tomto pripade ctecka narazi na prvni cast a vytvori objekt hello word tedy instanci tridy text ktere posle zpravu.

Takze jak vidite lispovske objekty byly nahrazeny plnokrevnymi objekty co jsou schopne prijimat zpravy a byl zmenen format formy a pridan znak ! na odpaleni- muzete si napsat vic forem a treba pet naraz odpalit. Na to v lispovi potrebujete blok. Taky zavorek ubylo.

Matematika

Samozdrejme ze printNl funguje i na ciselny objekt:

                12345 printNl !

A integer se nam vytiskne(plus hodne statistik kolem-to se da vypnout pomoci prepinace -q) Jak vidite nic se nezmenilo oproti lispovskemu print jenom poradi se prohazelo. No a matematika stejne jako v lispu neni nic special. Proste napisete:

(1 + 2) printNl !

a vipise se 3. Jak to funguje? () jsou neco jako [] v tcl nebo () v lispovi proste umoznuji vnorovani forem a rikaji ze se to ma vyhodnotit napred. Nejprve se tedy vyhodnocuje forma 1 + 1. To je poslani zpravy + objektu 1. a navic predani parametru 1. Ta samozdrejme objekty secte a vysledkem je objekt 3 ktery vrati. Navratova hodnota tedy 3 se dosadi za () a vyvola se: 3 printNl !. Jeste je dulezita tahle konstrukce+

(1 + 3 + 4 - 5) printNl !

Tady interpretr veme 1 jako vychozi objekt a zjisti ze je treba poslat zpravu + zjisti ze zprava + ma 1 parametr posle ji tedy objekkt 3 vysledek bude objekt 4 a bude pokracovat na(4 + 3 -5) tedy mu posle zpravu + z jednim parametrem 3 atd.. To ma vyhodu ze se da pekne retezit zpravy. Prepis do lispu je:

(+(+(+ 1 3) 4) 5)

Coz ten smalltalkovej vypada lip protoze se to pise tak jak vyhodnocuje. Na druhou stranu tenhle postup komplikuje volitebny pocet parametru protoze nikdy neni jasne kde konci volani prvni zpravy a zacina druhe. Mimochodem je to dalsi celkem zbytecna jazykova konstrukce spolu z () a ! Nahodou matematika vypada lidsky. Je tu ale problem z upredostnovanim protoze zpravy se posilaji od leva do prava vyraz:
(1 + 3 / 2) printNl !
se vyhodnoti do 2 misto 1 a 3/2. Nastesti zavorky funguji vlastne stejne jako matematicke zavorky a:
(1 + ( 3 / 2 )) printNl !
uz bude fungovat.

Pouzivani trid

Tedy jak vytvaret instance objektu. Takhle si vytvorime symbol pro objekt:
               Smalltalk at: #x put: 0 !
Casem popisu proc tak divne. Je to treba abychom mohli priradit jmeno. Mimochodem protoze se parametry nevyhodnocuji jsou promene dalsi zbytecnou jazykovou konstrukci. To se nam to komplikuje.

pole

Na tom ukazu jak vypada bezny smalltalkovy objekt. Napred ho vytvorime tim ze posleme instanci zpravu:
x := Array new: 20 !
:= je prirazeni takze x ted ukazuje na pole. A zase konstrukce hmm....
Array new: 20 !
Posleme zpravu instanci ze se ma vytvorit a parametr 20 coz je ucividne velikost. Jeste poznamka ze meneni elementu tedy ceckarsky = neni := to je opravdu jenom spojeni x z objektem. Prvni zprava co ple prijima je at: tedy lisparske elt:
(x at: 1) printNl !
vypise prvni prvek. Tedy nil. Prirazovani se dela pomoci zpravy put:
x at: 1 put: 99 !
Tohle objektu x tedy poli posle zpravu at z parametrem 1. Ta vytvori novy objekt asociaci. Ktery se uklada do spravneho mista v poli. Zprava put: se yz posila novemu objektu tedy ne uz poli a ten ulozi hodnotu 99. (zpravy co chteji parametry se vetsinou jmenuji z dvojteckou) A muzete si to vypsat jestli chcete a opravdu tam bude 99. Samozdrejme ze si muzete s retezenim zprav a objektu blbnout jak dlouho chcete:
               ((x at: 1) + 1) printNl !
Je tu hodne dalsich typu co popisovat nebudu. treba set neboli mnozina apod. Dulezity je:

Slovnik

To je asociovana pamet. Stejne jako pole v tcl nebo asociovane listy, hasovaci tabulky nebo enviromenty v lispovi nebo xetory v cmlispu. Jsou to pole ktere muzete indexovat libovolnym objektem obsahuji tedy asociace z klice se zobrazi do hodnoty. Priklady prace:
               x := Dictionary new.
               x at: 'One' put: 1 !
               x at: 'Two' put: 2 !
               x at: 1 put: 'One' !
               x at: 2 put: 'Two' !
To tam nahaze 4 asociace. Jak vidite at je tu rozsireno a bere vsechny objekty. Silne pripomina gethash. A uz se muzem na asociace odkazovat:
(x at: 1) printNl !
=> 'One'
(x at: 'Two') printNl !
=> 2
a vypsat vsechno :
x printNl !
=> Dictionary (1,'One' 2,'Two' 'One',1 'Two',2 )

Smaltalkovej slovnik

Je tu specialni instance tohoto objektu pod jmenem Smalltalk. To je jeho enviroment. Jsou v nem tedy ulozene promene a jejich asociace do hodnot. jestli si pamatujete na vytvareni x:
               Smalltalk at: #x put: 0 !
Je vlastne pridani polozky x do slovniku a nastaveni na 0. To je opravdu elegantni reseni. Asi se divite proc ten #. je to stejny rozdil jako v lispu mezi "x" a 'x. Jedno je string druhe je symbol. Takze si muzete vytisknout vsechny promene pomoci:
Smalltalk printNl !
Tady ty promene rusit apod. Proste je to moc pekne a moc se mi to libi. Je to jedno misto kde trumfli lisp.

Pridavani trid

To je asi nejdulezitejsi vec v OO. Dulezite je take urcit kam do uz existujici hiearchie objekt umistit. Jak se takove misto hleda asi nemusim vysvetlovat. Ale pro orientaci list existujici struktury:
               Object
                   Autoload
                   Behavior
                       ClassDescription
                           Class
                           Metaclass
                   BlockContext
                   Boolean
                       False
                       True
                   CFunctionDescriptor
                   CObject
                   Collection
                       Bag
                       MappedCollection
                       SequenceableCollection
                           ArrayedCollection
                               Array
                               ByteArray
                               CompiledMethod
                               String
                                   Symbol
                           Interval
                           LinkedList
                               Semaphore
                           OrderedCollection
                               SortedCollection
                       Set
                           Dictionary
                               IdentityDictionary
                               SystemDictionary
                   Delay
                   FileSegment
                   Link
                       Process
                       SymLink
                   Magnitude
                       Character
                       Date
                       LookupKey
                           Association
                       Number
                           Float
                           Integer
                       Time
                   Memory
                       ByteMemory
                       WordMemory
                   Message
                   MethodContext
                   MethodInfo
                   ProcessorScheduler
                   SharedQueue
                   Stream
                       PositionableStream
                           ReadStream
                           WriteStream
                               ReadWriteStream
                                   FileStream
                       Random
                       TokenStream
                   UndefinedObject
Je to celkem zajimavy si ji projit. Clovek obcas zjisti zajimavy veci. Je to opravdu pekna struktura. Treba ze slovnik je pod mnozinou protoze slovnik je vlastne mnozina rozsirena o asociace. Nebo ze i trida je normalni objekt takze kdyz jsme posilaly zpravu tride Array posilali jsme zpravu normalnimu objektu typu class. To je prece krasne. Jesne jedna poznamka. Ukladani smalltalkove session je:
               Smalltalk snapshot: 'myimage.img' !
A nacteni:
               $ mst -I myimage.img

Vytvareni tridy

No jak asi se muze vytvorit nova trida? Reseni je jednoduche protoze kazda trida je objekt proste poslem rodicovskemu objektu zpravu ze chceme novy:
               Object subclass: #Account
                    instanceVariableNames: 'balance'
                    classVariableNames: ''
                    poolDictionaries: ''
                    category: nil !
Trochu to pripomina lispovsky zpusob zakladani.. Je to trochu dlouhy. Nejlepsi je nastavit si editor aby se to vyprasko po jedny klavese. Posilame zpravu tride Objekt coz je nejnizsi tride ve strome. Rikame ji ze se bude jmenovat Account a ze bude mit jednu privatni promenou jmenem "balance". Dokumentovani tridy Kazda trida ma misto na dokumentaci(stejne jako vetsinou v lispovi) jednoduse ji poslem zpravu:
               Account comment: 'I represent a place to deposit and withdraw 
money' !
A kdyz ji chceme precist:
               (Account comment) printNl !
nebo
               (Integer comment) printNl !

Definovani metody pro tridu

Opet se to dela pomoci posilani zpravy. Tentokrat ale dost divne a ja tomu moc nerozumim:
               !Account class methodsFor: 'instance creation'!

               new
                    | r |

                    r := super new.
                    r init.
                    ^r
               !!
To se nam ta gramatika mota...jeje No ten prvni vykricnik to nic..ten jenom odpali vsechno predtim. Account class posle zpravu Accountu a rika ze chce mluvit primo ze tridou. Vrati se tedy opravdova trida typu trida a ty se posle zprava methodsFor: z parametrem 'instance creation' a odpali se to pomoci !. Zatim to jde. 'instance creation' je komentar. Ale metoda methodsfor: udla zvlastni vec:prepne interpretr do jineho rezimu!!!To je ale prasarna co?-my chceme defmethod! Dalsi zbytecna jazykova konstrukce je hned dalsi radka tedy new. Jasne vytvari novou metodu. Ale proc to neni delane rozumne? a dalsi je zase nestandard! | r | vytvori lokalni promenout. Zacina prituhavat...my chceme let! Pomoci dalsi zbytecne konstrukce ji priradime vysledek formy supper new co posle new svemu rodicovy tedy tride Objekt co vytvori novy objekt. A hruza dlasi je tecka! dalsi nestandard. To je oddelovac. Neco jako v cecku strednik ale je to pojaty spis pascalisticky! Proste ne ukoncovac ale oddelovac takze jako : v Basicu! A aby toho nebylo malo hned dalsi je ^r coz je return a hned dalsi jazykova konstrukce(zacina se mi delat spatne) a aby nas dorazili jeste tam dali !! co prepne interpretr zpatky a zaroven ukonci definici metody-jenom ukonceni se dela pomoci !

Uff...to byl ale zahul..to jsem se zapotil...Az sem smalltalk vypadal dobre ale tohle.. to je proste paskvil. Zlatej lisp. No ale dalo by se to prezit a tak dal. Ted kdyz zadame:

Account new !
Tedy vyvolame construktora objektu. Smalltalk najde nasi metodu a pouzije ji. | r | vytvori lokalni promenou zavola construktor objektu a priradi ho r. Potom zavola metodu init uz od vytvorene instance. To je proto ze new metoda nemuze pristupovat do vytvoreneho objektu takze musi zavolat construktor oz od objektu tedy init co provede inicializaci.

Definovani metody pro instance

Jak sme zjistili new je metoda tridy tedy toho co vytvari objekt. Ale init je metoda uz instance. Proto ji musime napsat jinak:
               !Account methodsFor: 'instance initialization'!
               init
                    balance := 0
               !!
Vidite ze zmizelo volani class. Proto se metoda vytvari rovnou pro Account a ne pro objekt co ho ridi tedy !account class. Tahle metoda uz muze pristupovat na interni promene-je v objektu a je to normalni construktor. Tohle rozdeleni prace mezi dva konstruktory se mi zda elegantni. Takze init se da posilat uz vytvorenym objektum a new se posila tride abychom je vytvorily. Jak jednoduche. Metoda nic nevraci a to neznamena ze vraci neco jako void nebo 0 ale vraci hodnotu sveho objektu. Aby se metody daly pekne retezit Account new init init init init ! Posle mockrat init a porad tomu samymu objektu.

Prace z kontem

Vytvorime si instanci:
               Smalltalk at: #a put: (Account new) !
a mame ji v a :) Kdyz ho chceme vytisknout napiseme:
               a printNl !
Ale on nas vypece a napise:
               an Account
A nevime nic :) Proste jsme neudelali rozumnou metodu na tisk. PrintNl vola Print co uz nedela newline a ten vola PrintOn z parametrem stdout tedy trochu jako muj navrh jestli si ho pamatujete. Staci napsat PrintOn a mame vyhrano:
               !Account methodsFor: 'printing'!
               printOn: stream
                    super printOn: stream.
                    ' with balance: ' printOn: stream.
                    balance printOn: stream
               !!
a otestovat:
               a printNl !
a tiskne:
               an Account with balance: 0
rozbor.. super printOn vypise uz zname an Account. Dalsi radka vypise normalni text..to uz tu bylo mockrat A dalsi balanci zase nic novyho.

Prace z penezmi

No a ted trochu prace z accountem abychom nebyly porad svorc: !Account methodsFor: 'moving money'! spend: amount balance := balance - amount ! deposit: amount balance := balance + amount !! No a uz si to muzete zkusit: a deposit: 125! a deposit: 20! a printNl! a spend: 10! a printNl!

Podtridy

V manualu jeste delaji podtridu savings co pridava jeste jednu promenou:
               Account subclass: #Savings
                    instanceVariableNames: 'interest'
                    classVariableNames: ''
                    poolDictionaries: ''
                    category: nil !
Vytvoreni podtridy...uz jsem vysvetlil
               !Savings methodsFor: 'initialization'!
               init
                    interest := 0.
                    ^ super init
               !!
inicializace... a prace z daty:
               !Savings methodsFor: 'interest'!
               interest: amount
                    interest := interest + amount.
                    self deposit: amount
               !
               clearInterest
                    | oldinterest |

                    oldinterest := interest.
                    interest := 0.
                    ^oldinterest
               !!
Furt nic novyho snad mimo self coz je obdoba this takze vola svoji vlastni metodu. Tohle jsem projel rychle..doufam ze tomu rozumite..je to dulezity pro:

Checking class

Ta musi navic citac cheky-aby kazdy mel svoje cislo a pamatovat kolik jich je:
               Account subclass: #Checking
                    instanceVariableNames: 'checknum checksleft'
                    classVariableNames: ''
                    poolDictionaries: ''
                    category: nil !
               !Checking methodsFor: 'Initialization'!
               init
                    checksleft := 0.
                    ^super init
               !!

Psani checku

               !Checking methodsFor: 'spending'!
               newChecks: number count: checkcount
                    checknum := number.
                    checksleft := checkcount
               !

               writeCheck: amount
                    | num |

                    num := checknum.
                    checknum := checknum + 1.
                    checksleft := checksleft - 1.
                    self spend: amount.
                    ^ num
               !!
Tady si muzeme pomoci number nastavit cislo a tady vydite jak se daji zpravi celkem pekne retezit. Zprava se pousti:
Check newChecks: 10 count: 100
Vypada to jako volani dvou zprav ale neni...celkem pekne ale mota to syntaxi Writecheck je clekem primitivni funkce co zveci cislo,ubere pocet checku a odebere castu z konta. A jedeme:
               Smalltalk at: #c put: (Checking new) !
               c printNl !
               c deposit: 250 !
               c printNl !
               c newChecks: 100 count: 50 !
               c printNl !
               (c writeCheck: 32) printNl !
               c printNl !

Code blocks

No jak vidite bankovni system to asi nebude protoze muzete pocek seku precerpat a beztrestne ject do minusu. Na to jsou treba podminky. Ty se delaji po stylu lispu posilanim zprav a predavanim zpustitelneho kodu:
               !Checking methodsFor: 'spending'!
               writeCheck: amount
                    | num |

                    (checksleft < 1)
                         ifTrue: [ ^self error: 'Out of checks' ].
                    num := checknum.
                    checknum := checknum + 1.
                    checksleft := checksleft - 1.
                    self spend: amount
                    ^ num
               !!
To je metoda z detekci podteceni. A toto je podminka:
                    (checksleft < 1)
                         ifTrue: [ ^self error: 'Out of checks' ].
Jako prvni se vyhodnocuje (checksleft < 1) vysledkem je boolean tedy objekt true nebo false. Oba boolieny podporuji metodu ifTrue. U false nedela nic. U true spusti svuj prvni parametr-tim je: [ ^self error: 'Out of checks' ] To je normalni objekt jako vsechny jine ale obsahuje kod a ma metodu ktera ho provadi. Tedy ifTrue u true pouze veme svuj prvni parametr-ccode block a rekne mu aby se provedl. Naprosto typivky lispovsky pristup. Pouze je tu treba dalsi zbytecna jazykova konstrukce - [] protoze nema na kod tak pekny typ jako je lispovsky list. Funkci tehle podminek si muzete pekne otestovat:
               true ifTrue: [ 'Hello, world!' printNl ] !
               false ifTrue: [ 'Hello, world!' printNl ] !
               true ifFalse: [ 'Hello, world!' printNl ] !
               false ifFalse: [ 'Hello, world!' printNl ] !
Proti lispu nic noveho..proste unless no. Zajimave je zpracovani zpravy error co posle metoda svemu objektu. Tato zprava jako default odesle stejny error volajicimu apod. Toto spracovani chyb je celkem pekne.

Interace a spol

Jeste by bylo dobre rozsirit check tridu o historii kdy a jake byly cyjmuty checky. aby se nedalo padelat. To ale chce pridat promenou:
               Account subclass: #Checking
                    instanceVariableNames: 'checknum checksleft history'
                    classVariableNames: ''
                    poolDictionaries: ''
                    category: nil !
Tady ale vznikne kolize ze starymi instancemi co promenou nemaji. Gnu smaltalk je necha jak jsou a nove metody na ne uz nebudou fungovat. Jine smalltalky treba zakazou pridat. Musime take rozsirit init:
               !Checking methodsFor: 'initialization'!
               init
                    checksleft := 0.
                    history := Dictionary new.
                    ^ super init
               !!
Jak vidite budeme checky ukladat do slovniku. A rozsirime writeCheck:
               !Checking methodsFor: 'spending'!
               writeCheck: amount
                    | num |

                    "Sanity check that we have checks left in our checkbook"
                    (checksleft < 1)
                         ifTrue: [ ^self error: 'Out of checks' ].

                    "Make sure we've never used this check number before"
                    num := checknum.
                    (history includesKey: num)
                         ifTrue: [ ^self error: 'Duplicate check number' ].

                    "Record the check number and amount"
                    history at: num put: amount.

                    "Update our next checknumber, checks left, and balance"
                    checknum := checknum + 1.
                    checksleft := checksleft - 1.
                    self spend: amount.
                    ^ num
               !!
No jsou tu navic jeste komentare co jsou v lispovi v "" Jinak je tu pridavani checku:
                    history at: num put: amount.
a testovani jestli nahodou jsme takovy check uz nemeli:
                    (history includesKey: num)
                         ifTrue: [ ^self error: 'Duplicate check number' ].
Oba vyrazy jsou snad jasne. Ted ji jeste printit:
               !Checking methodsFor: 'printing'!
               printOn: stream
                    super printOn: stream.
                    ', checks left: ' printOn: stream.
                    checksleft printOn: stream.
                    ', checks written: ' printOn: stream.
                    (history size) printOn: stream.
               !
               check: num
                    | c |
                    c := history at: num ifAbsent: [ ^self error: 
'No such check #' ].
                    ^c
               !!
PrintOn je snad jasne. Proste secte vsechny zaznamy v historii a vypise kolik checku bylo vypsano. Taky je tu funkce check co bere cislo checku a vrati kolik. Taky ma osetreni. Snad je vse jasne. A ted je treba udelat kyzenou smycku na tisteni vsech checku: !Checking methodsFor: 'printing'! printChecks history associationsDo: [:assoc| (assoc key) print. ' - ' print. (assoc value) printNl. ] !! Je videt ze je tu volani metody associationsDo. Jeji princip je asi jasny proste zavola neco pro vsechny asociace. Zajimavejsi je code blok ktery zacina [:assoc| atd... To je blok z jednim parametrem. Takze nahrazuje castecne lisparsky lambda listy-proste vyzaduje parametr assoc kam metoda associationsDo ulozi hodnotu prvku typu asociace tedy ma dva hodnoty-key a value a pomoci (assoc key) print. se vypisuje.

Smycky

Vetsina objektu ma nejake to svoje do:
               1 to: 20 do: [:x| x printNl ] !
To je asi jasne..vytvori se nejaky objekt interval pomoci poslani to: do 1 a parametru 20 tedy interval 1 az dvacet a ten uz ma svoji metodu do a bloku predava jeden parametr blok si ho bere jako x a tiskne ho. Objekt interval muze byt i interval objedno:
               1 to: 20 by: 2 do: [:x| x printNl ] !
apod. samozdrejme ze takovy interval si muzeme ulozit:
              Smalltalk at: #i put: (Interval from: 5 to: 10) !
               i printNl !
               i do: [:x| x printNl] !
A delat dalsi praci. Toto reseni se mi zda hodne elegantni. Ale lisp ho muze mit taky-neni duvod proc ne. Typ interbal by se dal resit pomoci CLOSU jako bezny objekt a genericka funkce do by taky fungovala

Volani code bloku

Napiseme jednoduchou metodu co vola blok pro kazdy chek nad nejakou hodnotu:
               !Checking methodsFor: 'scanning'!
               checksOver: amount do: aBlock
                    history associationsDo: [:assoc|
                         ((assoc value) > amount)
                              ifTrue: [aBlock value: (assoc key)]
                    ]
               !!
metoda value tedy posila bloku hodnotu. Predavani parametru je ve smalltalku slabe kvuli omezenim z volitebnym poctem parametru protoze na predani dvou parametru musime mit zcela jinou metodu:
value: 1.hodnota value: 2.hodnota
a je jasne ze jich nemame nekonecno tak muzeme predat maximalne tri hodnoty. No reknete o co je lispovy reseni prez lambda listy pruznejsi. No doufam ze jinak je metoda jasna. muzete testovat:
               Smalltalk at: #mycheck put: (Checking new) !
               mycheck deposit: 250 !
               mycheck newChecks: 100 count: 40 !
               mycheck writeCheck: 10 !
               mycheck writeCheck: 52 !
               mycheck writeCheck: 15 !
               mycheck checksOver: 1 do: [:x| printNl] !
               mycheck checksOver: 17 do: [:x| printNl] !
               mycheck checksOver: 200 do: [:x| printNl] !
Je samozdrejme hodne cest jak napsat tuhle funkci:
               !Checking methodsFor: 'scanning'!
               checksOver: amount do: aBlock
                    | chosen |
                    chosen := history select: [:amt| amt > amount].
                    chosen associationsDo: aBlock
               !!
select je obdoba lispackyho member. Tenhle kod ale preda aBloku celou asociaci.

Zaver

Tim sem posal asi dost ze smalltalku aby to stacilo na bezne programovani. Rad bych ted smalltalk porovnal z lispem:
Myslim si ze cela smalltalska knihovna by sla prepsat do CLOSU-objektu v lispovi. Navic genericke funkce lispu jsou obecnejsi nez smalltalske metody. Genericka funkce muze urcit ze jeji ctvrty parametr musi byt string nezto smalltalska metoda urcuje vlastne jen prvni. Dal je tu problem z predavanim parametru-ve smalltalku nemuze mit metoda volitebny pocet parametru a dokonce musi mit mezi parametrama slova stylu do: apod. To sice zvysuje ukecanost a tim i citelnost jazyka ale na lisp to proste nema.. Navic smalltalk ma hrozne zmotanou syntaxi: () [] ! || !! value:value:value a narazi na moc dalsich omezeni naprosto zbytecnych. Proste zase ten svinskej lisp je lepsi :( Kdyby se smalltalska knihovna upravila pro lisp byla by to bomba. Lispovsky knihovny vetsinou vychazi z common lispu tedy knihovny z roku 1984 a ta nemohla byt a ani neni objektova a tak rozsiritelna jako smalltalska. A presto by to slo. Kdybych ja delal knihovnu k lispu implementoval bych zaklad objektu jako genericke funkce,defclass,defmetod a defgeneric primo jako primitivni funkce a celou knihovnu bych na tom vystavel podobne jako ve smalltalku. Smalltalk vlastne neresi zadny problem lispu(alespon ne tu z listingu) a prinasi hodne omezeni a hodne veci ma zbytecne danych do interpretru jeho interpretrace je slozita a celkove je v nem vetsi zmatek. Dokonce se prez veskerou snahu nevyvaroval funkci-code bloky jsou dost blbe udelane funkce. Smalltalk ma bohuzel jasnejsi vyhlidky nez lisp a hodne se rozsiruje. Vlastne urcuje dnesni smer v OO.


Tento soubor je soucasti rozsahle sbirky skolicek na http://www.ucw.cz/~hubicka/skolicky

Take si muzete prohlidnout jeji puvodni textovou podobu

Nebo mi mailnout na hubicka@ucw.cz

Copyright (C) Jan Hubicka 1995