Omezená dědičnost (je něco lepšího než OOP?)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #405 kdy: 16. 09. 2015, 13:37:06 »
Aby tu nebylo jen pusté filosofování, zde je "protocol-oriented" kód (ať to není příliš dlouhé, tak jen pro nejobecnější a nejspeciálnější případ):

Kód: [Vybrat]
protocol QuadrilateralWithParallelOppositeSides {
    var side1:Double { get }
    var side2:Double { get }
    var skew:Double { get }
}

extension QuadrilateralWithParallelOppositeSides {
    func area() -> Double {
        return side1 * side2 * cos(skew)
    }
}

struct Parallelogram : QuadrilateralWithParallelOppositeSides {
    var side1:Double
    var side2:Double
    var skew:Double
    init(side1 s1:Double, side2 s2:Double, skew s:Double) {
        side1 = s1
        side2 = s2
        skew = s
    }
}

struct Square : QuadrilateralWithParallelOppositeSides {
    var side1:Double
    var side2:Double { return side1 }
    var skew:Double { return 0 }
    init(side s1:Double) {
        side1 = s1
    }
}

let figure1 = Parallelogram(side1: 2, side2: 3, skew: M_PI_4)
let figure2 = Square(side: 3)
var list:Array<QuadrilateralWithParallelOppositeSides> = [ figure1, figure2 ]
print(list.map { $0.area() })

Jak je hezky vidět, metoda pro výpočet obsahu se definuje jen jednou. O různé invarianty se postarají "computed properties". Jednoduché, elegantní a rozšiřitelné :)

Doplnění k tomuto evidentně nejlepšímu řešení: Ve Swiftu je pro čtverec ona generická metoda stejně rychlá jako side1*side1 (agresivní optimalizace). V C++ clang generickou metodu také optimalizuje, ale zrychlení není o řád. Microsoftí C++ neoptimalizuje nic. C# zrychlí defaultní metodu asi o polovinu a Java (osmička) 4-5x. Sečteno a podtrženo: Swift jasně vede (v implementaci), ale kromě Microsoftího C++ si mainstream s optimalizací generické metody pro výpočet obsahu rovnoběžníku hravě poradí.


JS

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #406 kdy: 16. 09. 2015, 13:41:19 »
Mě jako haskellistu by moc zajímali podrobnosti. Nemáš nějaký pěkný pokec o tom? Nebo to tu alespoň trochu rozveď.

Taky by me to zajimalo.. zkousel jsem to vygooglit ale nic jsem nenasel.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #407 kdy: 16. 09. 2015, 13:58:10 »
Mě jako haskellistu by moc zajímali podrobnosti. Nemáš nějaký pěkný pokec o tom? Nebo to tu alespoň trochu rozveď.

Taky by me to zajimalo.. zkousel jsem to vygooglit ale nic jsem nenasel.

Já Haskell moc neznám. Zde je explicitně zmíněn:

https://en.m.wikipedia.org/wiki/Protocol_(object-oriented_programming)
https://mobile.twitter.com/bos31337/status/473545340864700416
https://bigonotetaking.wordpress.com/2015/07/17/swift-protocols-a-strategy/

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #408 kdy: 16. 09. 2015, 14:02:18 »
Protokol je původní název pro tento koncept. Dědičnost protokolů tam je. Virtuální metody ("defaultní") tam jsou taky. Někdo má problémy s porozuměním jednoduchému textu...

Z PDF se zdá jako že by protokoly snad měly být lepší náhrada za běžné OOP a to není pravda.
Vím že ve Swiftu jsou i class a ty fungují "postaru". Stejně tak "postaru" ve Swiftu dělají přepsání virtuální metody v potomku.

Specializace protokolu je většinou lepší než odvození z nadtřídy. Viz příklad někde výše, kde čtverec dědí z rovnoběžníku. V "běžném" OOP nejde v žádném jazyce mít společnou metodu pro výpočet obsahu a přitom méně atributů u čtverce. Principiálně tomu sice nic nebrání, ale v C++, C#, ObjC ani Javě to prostě nejde.

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #409 kdy: 16. 09. 2015, 14:02:41 »
Z PDF se zdá jako že by protokoly snad měly být lepší náhrada za běžné OOP a to není pravda.
Je to pravda. Častý problém programátorů-praktiků je, že jako "lepší" si představují to, co má víc čudlíků, hejblátek, generuje to víc kódu apod. Viz např. "můj jazyk je lepší, protože se v něm dá dělat i x" (hurá, "multiparadigmatický jazyk"). Ve skutečnosti je to ale spíš opačně - čím je věc omezenější, tím tam platí silnější předpoklady a tím se mj. dá i líp optimalizovat. A často je taky v důsledku obecnější, protože stačí splnit pevné předpoklady a platí spousta důsledků.

Protokoly jsou k tomu, aby se ke všem věcem, které splňují nějaké předpoklady, dalo chovat stejným způsobem. Podobně jako v OOP když mají společného předka. Akorát u protokolů nemusíš třešit tragikomické důsledky hierarchizace dědičnosti. Prostě to kváká jako kachna, tak je to kachna. Co víc chtít?!


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #410 kdy: 16. 09. 2015, 14:08:57 »
Z PDF se zdá jako že by protokoly snad měly být lepší náhrada za běžné OOP a to není pravda.
Je to pravda. Častý problém programátorů-praktiků je, že jako "lepší" si představují to, co má víc čudlíků, hejblátek, generuje to víc kódu apod. Viz např. "můj jazyk je lepší, protože se v něm dá dělat i x" (hurá, "multiparadigmatický jazyk"). Ve skutečnosti je to ale spíš opačně - čím je věc omezenější, tím tam platí silnější předpoklady a tím se mj. dá i líp optimalizovat. A často je taky v důsledku obecnější, protože stačí splnit pevné předpoklady a platí spousta důsledků.

Protokoly jsou k tomu, aby se ke všem věcem, které splňují nějaké předpoklady, dalo chovat stejným způsobem. Podobně jako v OOP když mají společného předka. Akorát u protokolů nemusíš třešit tragikomické důsledky hierarchizace dědičnosti. Prostě to kváká jako kachna, tak je to kachna. Co víc chtít?!

Aneb Einsteinovo "Everything Should Be Made as Simple as Possible, But Not Simpler".

P.S. s/praktik/lepič

JSH

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #411 kdy: 16. 09. 2015, 14:18:18 »
P.S. s/praktik/lepič
Nemusí to být lepič. Stačí aby se s něčím setkal poprvé. Ona ta elegance na první pohled vidět není. Je třeba začít o problému uvažovat trochu jinak.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #412 kdy: 16. 09. 2015, 14:24:17 »
P.S. s/praktik/lepič
Nemusí to být lepič. Stačí aby se s něčím setkal poprvé. Ona ta elegance na první pohled vidět není. Je třeba začít o problému uvažovat trochu jinak.

Jo, to je pravda. Mně jen vadí, když někdo kritizuje něco, než se s tím seznámí.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #413 kdy: 16. 09. 2015, 14:59:04 »
https://developer.apple.com/videos/wwdc/2015/?id=408

Když uz jsme u toho, nevíte někdo, proč v C# udělali tak debilně extension methods v cizích statických třídách? Java to má aspoň pohromadě.

Radek Miček

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #414 kdy: 16. 09. 2015, 16:08:27 »
https://developer.apple.com/videos/wwdc/2015/?id=408

Když uz jsme u toho, nevíte někdo, proč v C# udělali tak debilně extension methods v cizích statických třídách?

A v čem je to debilní, resp. jak by to mělo být?

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #415 kdy: 16. 09. 2015, 16:20:34 »
https://developer.apple.com/videos/wwdc/2015/?id=408

Když uz jsme u toho, nevíte někdo, proč v C# udělali tak debilně extension methods v cizích statických třídách?

A v čem je to debilní, resp. jak by to mělo být?

Má to být přímo v tom rozhraní, jako v Javě.

Natix

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #416 kdy: 16. 09. 2015, 16:38:46 »
Tady ale směšuješ dvě různé věci. Defaultní metody v Javě slouží jednak k omezené vícenásobné dědičnosti a jednak k tomu, aby bylo možné bezpečně rozšiřovat interfacy, které jsou součástí veřejných API. Druhý bod byl Oraclem prezentován jako jejich hlavní selling point, tzn. že defaultní metody jim umožnili rozšířit do té doby zamrzlé API kolekcí. Sranda je to, že nakonec k tomu prakticky vůbec nedošlo a veškeré funkcionální operace se místo kolekcí dostaly do nového typu - streamů.

Extension metody v C# naproti tomu slouží k rozšiřování tříd, nad kterými nemám kontrolu (jsou součástí SDK, knihoven atd.) a to v Javě dodnes není možné. Proto např. Guava definuje spoustu statických tříd pojmenovaných plurálem třídy, nad kterou operují (Strings, Ints, Iterables, Lists atd.). Takže pak můžu dělat toto: Lists.filter(list, predicate), ale už ne tohle: list.filter(predicate).

Radek Miček

Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #417 kdy: 16. 09. 2015, 16:39:09 »
https://developer.apple.com/videos/wwdc/2015/?id=408

Když uz jsme u toho, nevíte někdo, proč v C# udělali tak debilně extension methods v cizích statických třídách?

A v čem je to debilní, resp. jak by to mělo být?

Má to být přímo v tom rozhraní, jako v Javě.

Java nemá extension metody vůbec, ta má jen defaultní metody, ne? Navíc u defaultních metod musíte mít možnost rozhraní měnit (tj. přístup k jeho kódu).

Extension metody v C# jsou jen syntaktický cukr - kdyby mělo jít rozšířit existující rozhraní (bez možnosti ho přímo měnit - např. rozhraní z jiné assembly) nebo implementovat rozhraní pro existující třídu (bez možnosti ji přímo měnit), vyžadovalo by to změny v CLR (případně obejít CLR).

Výhodou stávajícího řešení je, že můžete mít více implementací jedné extension metody a není třeba měnit CLR.

BTW může třída ve Swiftu mít více implementací jednoho protokolu?

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #418 kdy: 16. 09. 2015, 17:15:30 »
Prostě to kváká jako kachna, tak je to kachna. Co víc chtít?!

Todle mi třeba vadí:
Kód: [Vybrat]
interface Foo
{
    string quak();
}

interface Doo
{
    string quak();
}

class DuckFoo implements Foo { .. }
class DuckDoo implements Doo { .. }

print(? duck) {
   std.out.print(duck.quak())
}

print(new DuckFoo)
print(new DuckDoo)


zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Omezená dědičnost (je něco lepšího než OOP?)
« Odpověď #419 kdy: 16. 09. 2015, 17:24:44 »
Tady ale směšuješ dvě různé věci. Defaultní metody v Javě slouží jednak k omezené vícenásobné dědičnosti a jednak k tomu, aby bylo možné bezpečně rozšiřovat interfacy, které jsou součástí veřejných API. Druhý bod byl Oraclem prezentován jako jejich hlavní selling point, tzn. že defaultní metody jim umožnili rozšířit do té doby zamrzlé API kolekcí. Sranda je to, že nakonec k tomu prakticky vůbec nedošlo a veškeré funkcionální operace se místo kolekcí dostaly do nového typu - streamů.

Extension metody v C# naproti tomu slouží k rozšiřování tříd, nad kterými nemám kontrolu (jsou součástí SDK, knihoven atd.) a to v Javě dodnes není možné. Proto např. Guava definuje spoustu statických tříd pojmenovaných plurálem třídy, nad kterou operují (Strings, Ints, Iterables, Lists atd.). Takže pak můžu dělat toto: Lists.filter(list, predicate), ale už ne tohle: list.filter(predicate).

Jenže v C# to jde i pro rozhraní.