nutnost explicitně funkcím předhazovat data
To děláte i v jiných OO jazycích, ne? Když například napíši
obj.met(), tak metodě
met explicitně předávám objekt
obj.
2. takové rádobyzapouzdření obfuskací, předpokládám přepisovatelné, takže negarantovaný stav.
Zapouzdření funguje spolehlivě. Například implementace zásobníku v OCamlu:
module type STACK = sig
type 'a t
val empty : 'a t
val push : 'a -> 'a t -> 'a t
end
module Stack : STACK = struct
type 'a t = 'a list
let empty = []
let push x xs = x :: xs
end
Zásobník je implementován strukturou/modulem
Stack, jenž má signaturu
STACK. Signatura říká, jak se struktura tváří zvenčí. V našem případě je typ
t (jediný typ ve struktuře) abstraktní - nikdo zvenčí neuvidí, že je zásobník implementován jako spojový seznam, jediný, kdo to vidí, jsou funkce ze struktury
Stack - v našem případě funkce
empty a
push.
Na rozdíl od mainstreamových jazyků jsou signatury srovnávány strukturálně, nikoliv nominálně - to zvyšuje flexibilitu. Například stuktura
module AnotherStack = struct
type 'a t = 'a list
let empty = []
let push x xs = x :: xs
let pop (_ : 'a t) = failwith "TODO"
end
jde použít v místě, kde je očekávána struktura se signaturou
STACK - struktuře
AnotherStack nebylo nutné přiřadit signaturu
STACK (nevadí ani to, že
AnotherStack obsahuje funkci navíc). Jelikož jsme struktuře
AnotherStack explicitně nepřiřadili signaturu, kompilátor jí přiřadí signaturu automaticky, tato signatura odhalí vše - i zvenčí bude vidět, že je zásobník implementován jako spojový seznam.
Struktura
AnotherStack může být uvnitř jiné struktury například
M. Při přiřazování signatury struktuře
M můžeme přiřadit i signaturu struktuře
AnotherStack, anebo strukturu
AnotherStack můžeme úplně vynechat - pak tato struktura bude vidět pouze uvnitř
M, nikoliv zvenčí.
Pořád mi nikdo neukázal stejně jednoduchou alternativu k objektovému paradigmatu. To je to, co se tu snažím získat a osobně by mě to dost zajímalo.
Moduly v OCamlu můžete chápat jako objekty bez dědičnosti - můžete je předávat funkcím i vracet z funkcí. Mj. pokud potřebujete dědičnost, má OCaml i objektový systém s dědičností (zapouzdření se tam však vynucuje pomocí modulů). Nicméně na rozdíl od modulů/struktur nemohou objekty (z objektového systému) obsahovat typy. Dá se například říci, že Scala sjednotila systém modulů a objektů do jednoho - tam objekty mohou obsahovat i typy a funguje tam i dědičnost.