Zobrazit příspěvky

Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.


Příspěvky - zboj

Stran: 1 ... 90 91 [92] 93 94 ... 101
1366
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 14. 09. 2015, 12:02:46 »
Řekněme, že chci mít objekty čtverec, obdélník, kosočtverec a rovnoběžník. Je jasné, že s jednoduchou dědičností se daleko nedostanu. Proto obecný dotaz: existuje nějaké ... ?

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

Doufám, že jste tazatelovi pomohli ...
Vzhledem k obecnosti otázky celkem jo, až na to zaplevelení diskusí o FP ve hrách.

1367
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 14. 09. 2015, 11:54:45 »
Ty dvě počítané vlastnosti jsou tam zcela zbytečné. A co je zbytečné, musí pryč.
Ty počítané vlastnosti rozhodně nejsou zbytečné. Slouží k tomu aby šel čtverec použít všude tam, kde se dá použít rovnoběžník. Pokud mám třeba funkci na kreslení rovnoběžníka, tak pokud má čtverec tyhle dvě "zbytečné" vlastnosti tak ho tímhle způsobem můžu nakreslit taky.

Nebo chci přidat funkci pro obvod. Ve tvém případě musím tu funkci dodat do interface a doimplementovat ve všech odvozených třídách. Není jednodušší napsat jedinou funkci, která spočítá obvod rovnoběžníka a v případě čtverce využívá ty "zbytečné" počítané vlastnosti?

Jak uz od zacatku tady nekdo rikal, vsechno zavisi na zpusobu pouziti.
Tyhle zobecnovani, co tady delas zas vedou tomu, ze casto to co kompl zvladl pred 20 lety s tehdejsim hw, dela dneska na 20 let novejsim hw stejnou dobu. Kdyz budes mit miliardy ctvercu a budes je nekde muset skladovat a budes potrebovat pocitat jejich obsahy, tak si sakra rozmyslis, jestli tam budes nekde pocitat cos, drzet si zbytecne data, atp.

Odtud pak vznikaji napriklad tragicke aplikace v Jave - nepouzitelny lagovaci moloch, prestoze Java sama o sobe umi byt i relativne hodne rychla.

Vtip je právě v tom, že data se nikde zbytečně nedrží, už se to tady vysvětlovalo asi třikrát. Pokud je navíc struct pro čtverec neměnná, překladač z přístupu k side2 udělá přímý přístup k side1 a skew bude prostě konstanta. Díky této fázi optimalizací lze pak vyhodit i cos z funkce pro výpočet pro obsah (z metody area bude něco jako area<T> s různou implementací pro různé typy). Takže "miliardy čtverců" v něčem jako Array<Square> by rychleji implementovat ani nešla. Stačí si ten kód pustit s profilerem, pole miliardy čtverců zabere třetinu paměti oproti miliardě rovnoběžníků, pričemž výpočet obsahu je stejně rychlý (s -Ofast pochopitelně).

1368
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 14. 09. 2015, 11:47:01 »
Swift neznám, díky tomu snippetu by se ze mě ale konvertita nestal. Musím říci, že já osobně dostávám z myšlenky "nulovatelných typů" kopřivku, ale zajímavé by bylo porovnat "opravdovou" verzi třeba právě s implementací v Haskellu. Protože třeba v Pythonu si to dovedu představit díky ducktypingu za podstatně menších bolestí (jasně, ty třídy by bez dědičnosti nebyly ocejchovány ala Unifiable?, ale ta nulovatelnost podle mě stejně degraduje typový systém, takže to podle mě vyjde skoro nastejno).

V dynamickém jazyku to takto půjde vždy (Python, ObjC), zde je výhoda právě ve statickém typování.

1369
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 14. 09. 2015, 05:58:25 »
Včera jsem narazil na zatím nejhezčí příklad využití protokolů bez dědičnosti. Potřeboval jsem naimplementovat strukturu rysů s unifikací. Ve strukturách obvykle můžou být atomické hodnoty (zde pouze řetězec) a rekurzivně struktury rysů samy (někdy také množiny a případně další kolekce, ale to by už bylo triviální). Takto to jde nejjednodušeji:

Kód: [Vybrat]
protocol Unifiable : CustomStringConvertible {
    func unifiedWith(value:Unifiable) -> Unifiable?
}

class FeatureStructure : Unifiable {
    var features:[String:Unifiable] = [:]
    subscript(key:String) -> Unifiable? {
        get { return features[key] }
        set(value) { features[key] = value }
    }
    func unifiedWith(value:Unifiable) -> Unifiable? {
        if let value = value as? FeatureStructure {
            // some complicated stuff
        }
        return nil
    }
    var description:String {
        return "[" + ",".join(features.map { (key,value) in "\(key)=\(value)" }) + "]"
    }
}

extension String : Unifiable {
    func unifiedWith(value:Unifiable) -> Unifiable? {
        if let value = value as? String { return value == self ? self : nil }
        return nil
    }
    public var description:String { return self }
}

let fs1 = FeatureStructure()
fs1["a"] = "1"
let fs2 = FeatureStructure()
fs2["b"] = "2"
print("\(fs1) ⨆ \(fs2) = \(fs1.unifiedWith(fs2))")

Elegance sama :)

1370
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 13. 09. 2015, 22:31:26 »
Zajímalo by mě, na jaké nevýhody můžu u FP narazit. Zatím, co vím, tak že takovej Haskell je výkonově na úrovni Javy.  Což zase není tak hrozné, a možná by to chtělo nějaké lepší benchmarky. Napadá vás něco dalšího? Možná sem jen příliš velkej fanda, ale když bych se měl rozmýšlet, zda C++ nebo Haskell, tak neváhám ani okamžik (a to jsem si s C++ pár věcí napsal).

http://www.rarous.net/weblog/448-deset-duvodu-proc-nepouzivat-funkcionalni-jazyky.aspx :)

1371
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 16:52:43 »
Poněkud názornější (a užitečnější) příklad protocol-based programming: 

Kód: [Vybrat]
protocol Differentiable {
    var derivative:Differentiable { get }
}

extension Double : Differentiable {
    var derivative:Differentiable { return 0 }
}

struct Variable : Differentiable, CustomStringConvertible {
    let name:String
    init(name:String) { self.name = name; }
    var derivative:Differentiable { return 1 }
    var description:String { return name }
}

struct Sum : Differentiable, CustomStringConvertible {
    let lhs:Differentiable
    let rhs:Differentiable
    init(lhs:Differentiable, rhs:Differentiable) { self.lhs = lhs; self.rhs = rhs }
    var derivative:Differentiable { return lhs.derivative + rhs.derivative }
    var description:String { return "\(lhs) + \(rhs)" }
}

func +(lhs:Differentiable, rhs:Differentiable) -> Differentiable {
    return Sum(lhs: lhs, rhs: rhs)
}

struct Multiplication : Differentiable, CustomStringConvertible {
    let lhs:Differentiable
    let rhs:Differentiable
    init(lhs:Differentiable, rhs:Differentiable) { self.lhs = lhs; self.rhs = rhs }
    var derivative:Differentiable { return lhs.derivative * rhs + lhs * rhs.derivative }
    var description:String { return "\(lhs) * \(rhs)" }
}

func *(lhs:Differentiable, rhs:Differentiable) -> Differentiable {
    return Multiplication(lhs: lhs, rhs: rhs)
}

let f = 2 * Variable(name: "x")
print("(\(f))' = \(f.derivative)")

1372
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 16:30:57 »
Jak vidíš, zápis je ještě kratší, ještě jednodušší a pro mnohé i čitelnější.
Akorát se ztratilo veškeré sdílení kódu, což bylo to hlavní, co ten příklad ilustroval. Místo jednoho kusu kódu si ho musím u každé třídy implementovat znova a znova.

To bylo mým úmyslem. Demonstrovat, že sdílení kousíčku kódu komplikovanými nástroji je složitější a podstatně méně čitelné, než použití interface. Pokud budu někde chtít použít třídu Čtverec, budu se oprávněně ptát, k čemu má tři atributy, když mi stačí jeden. Pokud to bude složitější výpočet, než jen obsah, mohu ten vzoreček sdílet v nějaké statické třídě - podobně jako je sestavena celá třída Math.

Program musí být v prvé řadě snadno čitelný člověkem programátorem. Kompilátor je až daleko za ním. Pokud je metoda pro výpočet obsahu zapouzdřena uvnitř svého objektu, je to nejen přehledné, ale i rychlé.

1) Přečti si konvence pojmenování metod ve Swiftu, než začneš kritizovat.

Zrovna pojmenování metod tam chybí. Přitom běžně se i ve Swiftu dodržuje pravidlo, že název metody má začínat slovesem.

Citace
2) Je tam jeden atribut a dvě počítané vlastnosti, což je něco jako převlečená metoda. Zbytek ti vysvětlil JSH.

Ty dvě počítané vlastnosti jsou tam zcela zbytečné. A co je zbytečné, musí pryč.

1) Slovesem začíná, pokud nic nevrací.
2) Působíš dojmem začínajícího studenta, který ještě nechápe (nezná) souvislosti. JSH ti už vše kolem toho příkladu vysvětlil, stačí si číst jeho odpověď stále dokola ;)

1373
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 16:09:52 »
1) Co je na area nesmyslného? Možná se douč AJ.

Název area() se nehodí pro název metody, protože je to podstatné jméno. Je však možné ho použít pro vlastnost Area, která by se tu docela hodila. Možná se douč pravidla pojmenování tříd, metod a vlastností.

Citace
2) Omyl, u čtverce je jen jeden atribut, zbytek jsou computed properties. To nejsou atributy. Metoda pro výpočet obsahu se dá dopsat, v tomto případě tu generickou optimalizuje standardní knihovna (v obecném případě je jasné, že může dělat úplně něco jiného). Prostě toto řešení právě redukuje počet atributů, které nemá smysl mít v deklaraci (a tedy paměti).

Jsou tam tři privátní atributy: side1, side2 a skew. Snad ještě umím počítat. Všechny tři se nachází uvnitř objektu, ale to není podstatné, stejně jako nejsou podstatné optimalizace kompilátoru. Podstatné je, že čtverec má z definice jen jednu délku strany a žádné zkosení. Ve tvém řešení silně trpí sémantika jenom proto, že se pokoušíš sdílet nějakou metodu, která ani sdílena být nemá.

1) Přečti si konvence pojmenování metod ve Swiftu, než začneš kritizovat.
2) Je tam jeden atribut a dvě počítané vlastnosti, což je něco jako převlečená metoda. Zbytek ti vysvětlil JSH.

1374
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 15:35:06 »
Zdá se mi to, nebo ten příklad je ve skutečnosti zbytečně komplikovaný a má daleko k eleganci?

Kde se dá zjednodušit?

Tento jazyk neznám, ale vidím tam funkci s nesmyslným názvem area(), která je vložena do nějakého rodiče obou objektů. Něco podobného dělají v PHP traits. Ovšem už ze zápisu té funkce vidím, že u čtverce zbytečně počítá cos(skew) - je vždy roven jedné. Raději napíši do každé třídy jiný vzoreček pro výpočet obsahu, než abych do třídy Čtverec dával atribut skew, který tam sémanticky vůbec nepatří. Místo jednoho atributu tam máš tři atributy - z toho dva jsou zcela zbytečné. Čtverec má jen jeden atribut a tím je délka strany.

Kód: [Vybrat]
interface Areable  {
    Double area()
}

struct Parallelograma : Areable {
    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
    }

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

struct Square : Areable {
    var side: Double

    init(side s1: Double) {
        side = s1
    }

    func area() -> Double {
        return side * side
    }
}

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

Jak vidíš, zápis je ještě kratší, ještě jednodušší a pro mnohé i čitelnější.

1) Co je na area nesmyslného? Možná se douč AJ.
2) Omyl, u čtverce je jen jeden atribut, zbytek jsou computed properties. To nejsou atributy. Metoda pro výpočet obsahu se dá dopsat, v tomto případě tu generickou optimalizuje standardní knihovna (v obecném případě je jasné, že může dělat úplně něco jiného). Prostě toto řešení právě redukuje počet atributů, které nemá smysl mít v deklaraci (a tedy paměti).

1375
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 15:29:02 »
Tohle je IMO chyba. Schválně se při programování občas zastav a zamysli se kolik objektů upravuješ a kolik jich vytvoříš a pak jenom předáš. U mně ty immutable objekty jednoznačně vedou a to píšu hlavně v C++, které na to nějak extra zatížené není.

Immutable objekty řeší daleko víc věcí než jenom tohle. Zásadně mění třeba způsob jak synchronizovat vlákna.

Většinu objektů píšu hlavně proto že potřebuji mutable data a udržet data při změnách konzistentní, nepřekvapivě. Kdyby věděl, že čtvercoobdélníky budou immutable, je pravděpodobné že bych objekty vůbec nepoužil. Synchronizaci vláken mám vyřešenou k dokonalosti.

1) Nejde (kromě C++, to je na jinou debatu).
2) Právě neměnnost objektů je velká výhoda, i když v tomto případě jde spíše o to, jak se používají protokoly.

Protokoly nejdou. Napsat čtyři potomky, to vše bez setterů, jde skoro všude.
Výhoda neměnnosti objektů je vykoupena nevýhodou jejich neustálého kopírování a měnění pointerů na novou kopii a to přináší zase jiné problémy.
Pointerů? U struct?

1376
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 14:36:43 »
Aby tu nebylo jen pusté filosofování, zde je "protocol-oriented" kód

1) Takhle to jde v OOP také, samozřejmě.
2) Nejsou tam settery, ty právě způsobovaly ten hlavní problém. Konkrétně ve struct Square nejsou settery na side1 a side2. Immutable objekty neberu jako řešení.

1) Nejde (kromě C++, to je na jinou debatu).
2) Právě neměnnost objektů je velká výhoda, i když v tomto případě jde spíše o to, jak se používají protokoly.

1377
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 12:41:22 »
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]
 ... 
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é :)

Zdá se mi to, nebo ten příklad je ve skutečnosti zbytečně komplikovaný a má daleko k eleganci?

Kde se dá zjednodušit?

1378
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 12:24:13 »
Co se tyka OOP, dedicnosti a Go.. tady se dost zapomina, ze se dedi data, nikoli funkce (funkce neni treba dedit - bud jsou polymorfni nebo ne, a to je dane fakticky tim, jake jine funkce volaji (pripadne k jakym datum pristupuji ale to je jen specialni pripad volani)). Nejlepsi je IMHO se ke "klasickemu" OOP (C++, Java..) postavit tak, ze jde o tri ruzne abstrakce:

  • Zapouzdreni
  • Dedicnost
  • Polymorfismus

Vsechny tyhle vlastnosti Go ma, ale misto toho, aby je michalo dohromady jako "tridy", tak je ma zvlast:

  • Moduly
  • V definici struktury je mozne primo vlozit jinou strukturu, bez kvalifikace (jenom jednu - odpovida jednonasobne dedicnosti)
  • Interfacy (nebo tez protokoly - lze o objektu prohlasit, ze splnuje nejaky interface, napsat funkci, ktera predpoklada interface atd.)

IMHO je to tak lepsi. Mate tri ortogonalni koncepty a muzete si je smichat jak je libo.
To "vkládání" struktur není moc rozumné, někdy má podtřída (díky invariantům, viz výše) méně dat než rodič.

1379
Vývoj / Re:Omezená dědičnost (je něco lepšího než OOP?)
« kdy: 11. 09. 2015, 11:53:34 »
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é :)

1380
Studium a uplatnění / Re:Má cenu studovat IT navazující?
« kdy: 11. 09. 2015, 10:42:14 »
to radsi_anonymne:
A nemohlo to bejt tim, ze absolventum SS je19 a jsou to jeste de-facto deti kdezto absolventovi VS je minimalne o 5 let vice a s velkou pravdepodobnosti i o vic?
Moje zkusenost s absolventama VS je zase takova ze casto vedi vsechno nejlip a chteli by ridit svet a myslej si, ze na ne vsude cekaj za 50k, ackoliv jejich pridana hodnota je casto minimalni az nulova oproti SS.

Ja osobne potencial prinosu ve VS vidim, nicmene si nemyslim ze by se dal posuzovat plosne. Je to o individualitach.
Jeden z castych argumentu pro VS je ze te nauci dotahovat projekty. Mne prijde ze to studenty uci jen jak to co nejzaobaleneji ocurat aby to proslo u vyucujiciho a presne tak si vysvetluju ten tvuj: "tah na branku"
Navic casto lide studuji obor uplne mimo. Dopravky, PEF, ruzne soukrome ustavy a pak jdou delat do IT. Ok, proc ne, ale jakou je mozne ocekavat pridanou hodnotu od absolventa takoveho oboru?

Na druhou stranu znam nekolik lidi s UK co se venuji programovani a tam ta pridana hodnota urcite je to klobouk dolu.
"Tah na branku" je individuální záležitost. "Přidaná hodnota" také záleží (nepřímo) na povaze studenta/absolventa, někteří dělají minimum, jen aby prošli - prostě nejsnazší cesta k titulu.

Stran: 1 ... 90 91 [92] 93 94 ... 101