Dědičnost dnes

gll

Re:Dědičnost dnes
« Odpověď #360 kdy: 24. 01. 2017, 18:12:31 »

Dynamické a použitelné jsou i např. Ruby nebo Python.

Právě ani jeden není. Python je na malé skriptíky a Ruby také. Oba se dají dost dobře použít na webíky, ale to je tak všechno. Přesně ta jejich dynamičnost je vyřazuje z použití. Také metatřídy v Pythonu to všechno jen dodělají :D Jako nic proti nim, jen to je přesně ten příklad jazyků, které použít na větší věci nejde. Proto se tam ani nepoužívají. Kdyby ta dynamičnost byla tak úžasná, tak to nepoužívají hlavně admini, kteří vyvíjet neumí.

Můžete uvést nějaký konkrétní příklad, kdy vám metatřídy komplikovaly práci? Programátoři aplikací to nepoužívají a těch několik knihoven, co je používá to má odladěné.

Za prvé můžeš mít neschopné kolegy, kteří je nacpou všude. A za druhé jsou projekty, které je asi tak odladěné něměly. Třeba Django a jejich ORM je super využití. Jenže tam nikdo mít problém snad ani nemůže. Bohužel je lepší mít asi jazyk více osekaný a dělat to jinak. ORM v Javě také máš a tam žádné metatřídy nejsou. Takže se to jeví cool asi jako ta dynamičnost. Není to obecně dobrý nápad mít v jazyce.

A třeba OOP v Pythonu, které bylo ve 2 spíše jako vtip a ve trojce je pořád nic moc, ale lepší než nic. Takže pokud mi někdo řekne, že se  tenhle jazyk na něco velkého hodí, tak to dost vypovídá o jeho schopnostech.

Využití metatříd je hlavně v programátorských nástrojích a podobně. Stačí jejich použití v projektu zakázat. Stejného efektu jako metatřídou lze většinou dosáhnout i dekorátorem třídy mnohem explicitněji.

ani guru David Beazley si není jistý, kdy je vhodné použít metaclassu:

https://www.youtube.com/watch?v=sPiWg5jSoZI



gll

Re:Dědičnost dnes
« Odpověď #361 kdy: 24. 01. 2017, 18:44:35 »
A třeba OOP v Pythonu, které bylo ve 2 spíše jako vtip a ve trojce je pořád nic moc, ale lepší než nic. Takže pokud mi někdo řekne, že se  tenhle jazyk na něco velkého hodí, tak to dost vypovídá o jeho schopnostech.

V čem se zásadně liší OOP v pythonu 3 oproti 2?

phpmág

Re:Dědičnost dnes
« Odpověď #362 kdy: 24. 01. 2017, 19:10:41 »
A třeba OOP v Pythonu, které bylo ve 2 spíše jako vtip a ve trojce je pořád nic moc, ale lepší než nic. Takže pokud mi někdo řekne, že se  tenhle jazyk na něco velkého hodí, tak to dost vypovídá o jeho schopnostech.

V čem se zásadně liší OOP v pythonu 3 oproti 2?

Nevím, to mi říkali lidi, kteří měli rádi Python. Ve dvojce to byla jen taková parodie na OOP. Ve trojce by to mělo být lepší. Nebo pokud je to stejně špatné jako u dvojky, tak to asi není moc co řešit.

gll

Re:Dědičnost dnes
« Odpověď #363 kdy: 24. 01. 2017, 19:27:13 »
Nevím, to mi říkali lidi, kteří měli rádi Python. Ve dvojce to byla jen taková parodie na OOP. Ve trojce by to mělo být lepší. Nebo pokud je to stejně špatné jako u dvojky, tak to asi není moc co řešit.

Parodie podle člověka, který to nikdy nepoužil. Další programátor teoretik.

phpmág

Re:Dědičnost dnes
« Odpověď #364 kdy: 24. 01. 2017, 19:46:03 »
Kde to má rozhraní? Kde je nějaké zapouzdření, když je vše public? Kde je nějaká dědičnost, když všechno je dynamické a nikdo mi nebrání cokoli přepsat? Tomu fakt říkáš jazyk na vývoj?


Re:Dědičnost dnes
« Odpověď #365 kdy: 24. 01. 2017, 19:55:37 »
O FP se tu bavit nechci, neznám jej dost, ale znám OOP a z toho, co tuším o FP (které mi stejně jako OOP většina lidí nedokáže vysvětlit), tak jsou v přímém protikladu - OOP považuje chování a stavy za neoddělitelné a zapouzdřuje je, schopnost modelovat změnu stavů je přímo jeho cílem při zachování identity, FP na samostatná, otevřená data používá samostatné (rádoby) univerzální funkce (či jejich zřetězení), stavy nemodeluje a identitu zahazováním mezivýsledků popírá. Takže v podstatě Čumilovo tvrzení, že OOP a FP spolu nemají nic společného, je pravdivé.
Zbytek příspěvku, co je a není FP, považuju za deklarativní konstrukce či dojmy bez důkazů či příkladů.
Obecná tvrzení nejsou vetšinou pravdivá :)

Záleží na tom, jak by se FP a OOP vlastně měly kobinovat a především taky na definici, co je FP a co je OOP. Chceš-li konkrétní příklad, nastuduj si, jak (na nejvyšší úrovni) funguje Erlang: aplikace se skládá z procesů, procesy mezi sebou komunikují výhradně zasíláním asynchronních zpráv (až na drobné výjimky jako třeba sdílená databáze, ale to se používá málo), nemůžou mít žádný sdílený stav a vnitřní fungování procesů je naprogramováno funkcionálně (spíš pragmatická než čistá implementace FP - jsou např. možné vedlejší efekty). => procesy jsou aktory => procesy se velmi podobají objektům ve Smalltalku => je tam "OOP" (nikdo se tím moc nechlubí, aby se toho nechytali Javisti apod., ale je to tak) i FP.

gll

Re:Dědičnost dnes
« Odpověď #366 kdy: 24. 01. 2017, 20:07:35 »
Kde to má rozhraní? Kde je nějaké zapouzdření, když je vše public? Kde je nějaká dědičnost, když všechno je dynamické a nikdo mi nebrání cokoli přepsat? Tomu fakt říkáš jazyk na vývoj?

proč sis javamane změnil jméno? Používej si co chceš, ale nepiš o věcech, které neznáš.

Re:Dědičnost dnes
« Odpověď #367 kdy: 24. 01. 2017, 20:26:09 »
Zprávy mají s funkcemi společnou jedinou věc, a to, že synchronně vracejí odpověď. Tím jejich podobnost končí.
To je minimálně zavádějící tvrzení.

1. funkce jsou statické, zprávy jsou akce

Pokud se "funkcí" myslí to, co funkce znamená v (čistém) FP, tak funkce není nic jiného než zkratka pro nějaký dlouhý výraz - kdekoliv dám funkci, tam bych mohl dát ten dlouhý výraz (referenční transparentnost), nic víc. Celý program v čistém FP je vlastně striktně vzato sémanticky úplně statický - není to popis činnosti (co se má udělat kdy a jak), je to úplně statický popis relací mezi daty. Např. fce sqr(x) neříká "vem x a udělej s ním něco", říká, že čísla 3 a 9 jsou v relaci sqr. Protože samozřejmě chceme programovat nějakou činnost, má FP jazyk nějaký runtime, který tu statickou strukturu vezme a podle ní něco dělá. V samotném jazyce ale nic "dělat" nejde. Není jak.

2. zprávy nemusí být synchronní

...a dokonce je lepší, když defaultně nejsou, protože sesynchronizovat asynchronní události je v dobře navrženém jazyce triviální (kód v jazyce Elixir):
Kód: [Vybrat]
# synchronni fce - vrati :ok nebo :timeout
def ping_sync do
  # poslu zpravu agentovi
  send(agent,{self(),:ping})
  # cekam na odpoved nebo timeout
  receive do
    :pong -> :ok
  after 5000 -> :timeout
  end
end

3. odeslání zprávy nemusí nic "vracet" nebo může "vracet" víc hodnot postupně

Např. můžu actoru poslat zprávu
Kód: [Vybrat]
{self(),:subscribe_seconds}
a on mi od té doby bude každou sekundu posílat zprávy typu
Kód: [Vybrat]
{:seconds_now,1485285333}
Zprávy pochopitelně chodí úplně nezávisle na tom, co zrovna příjemce dělá (tj. musí tam být nějaký mailbox). A je čistě na příjemci, jestli je zahodí, nebo si hodnotu aktuálního času napíše na čelo lihovou fixkou :)

...prostě asynchronní zprávy kombinované se vzájemně neblokovanými aktory/agenty mají obrovské možnosti, které se dost těžko představují, dokud si v tom člověk fakt prakticky nezkusí něco napsat.

Jak se modelují změny stavů pomocí immutable, jsem se stále nedozvěděl, ale to neznamená, že to nejde, třeba jo.
Immutable je immutable, takže pokud si pod "změnou stavu" představuješ změnu in situ, tak nijak. Jinak to ale může vypadat třeba takhle (jeden příklad z jiného světa, když odpověď "monády" ti nestačila):

Kód: [Vybrat]
# zjednodušený ilustrační příklad, v reálu by to vypadalo trochu jinak
defmodule StateHolder do
  # tahle funkce spustí agenta držícího stav
  def start_link() do
    # spustí funkci loop s parametry [0] v novém vlákně
    spawn_link(fn -> loop(0) end)
  end

  def loop(state) do
    receive do
      {:add,k} ->
        new_state = state + k
        IO.puts "stav se meni z #{state} na #{new_state}"
        loop(new_state)
      {:get_state,pid} ->
        send(pid,{:state_is,state})
        loop(state)
    end
  end

end
« Poslední změna: 24. 01. 2017, 20:31:29 od Mirek Prýmek »

Re:Dědičnost dnes
« Odpověď #368 kdy: 24. 01. 2017, 20:37:09 »
K tomu StateHolder ještě praktická ukázka použití, pokud to někomu pomůže...

Kód: [Vybrat]
iex(2)> sh = StateHolder.start_link
#PID<0.107.0>

iex(3)> send(sh,{:get_state,self()})
{:get_state, #PID<0.81.0>}        <--------- funkce send/2 vrací to, co poslala, to nás nezajímá

iex(4)> flush           <----------- tímhle vyberu zprávy pro aktuální proces (tj. "tazatele", ne sh)
{:state_is, 0}
:ok

iex(5)> send(sh,{:add,10})
stav se meni z 0 na 10      <----------- tohle vypsal StateHolder
{:add, 10}

iex(6)> send(sh,{:add,10})
stav se meni z 10 na 20
{:add, 10}

iex(7)> send(sh,{:get_state,self()})
{:get_state, #PID<0.81.0>}

iex(8)> flush
{:state_is, 20}
:ok

phpmág

Re:Dědičnost dnes
« Odpověď #369 kdy: 24. 01. 2017, 20:47:28 »
Kde to má rozhraní? Kde je nějaké zapouzdření, když je vše public? Kde je nějaká dědičnost, když všechno je dynamické a nikdo mi nebrání cokoli přepsat? Tomu fakt říkáš jazyk na vývoj?

proč sis javamane změnil jméno? Používej si co chceš, ale nepiš o věcech, které neznáš.

Co z toho není pravda? Proč se asi moc nerozšířil na pořádný vývoj?

gll

Re:Dědičnost dnes
« Odpověď #370 kdy: 24. 01. 2017, 21:13:37 »
Kde to má rozhraní? Kde je nějaké zapouzdření, když je vše public? Kde je nějaká dědičnost, když všechno je dynamické a nikdo mi nebrání cokoli přepsat? Tomu fakt říkáš jazyk na vývoj?

proč sis javamane změnil jméno? Používej si co chceš, ale nepiš o věcech, které neznáš.

Co z toho není pravda? Proč se asi moc nerozšířil na pořádný vývoj?

vše je pravda. Nechci se hádat, který jazyk je lepší. Původně jsem reagoval na tvé tvrzení o metaclasách.

phpmág

Re:Dědičnost dnes
« Odpověď #371 kdy: 24. 01. 2017, 21:17:14 »
S tím souhlasím a i jsi to potvrdil. Takže metatřídy jsou OK, když se nepoužívají. Jen vše ostatní nám zůstalo, takže na vývoj bych to moc neviděl :(

gll

Re:Dědičnost dnes
« Odpověď #372 kdy: 24. 01. 2017, 21:45:22 »
S tím souhlasím a i jsi to potvrdil. Takže metatřídy jsou OK, když se nepoužívají. Jen vše ostatní nám zůstalo, takže na vývoj bych to moc neviděl :(

javamanova definice seriozního vývoje = vývoj v javě. Podle tvé definice se seriozní vývoj v ničem jiném dělat nedá.

lopata

Re:Dědičnost dnes
« Odpověď #373 kdy: 24. 01. 2017, 21:46:50 »
Kde to má rozhraní? Kde je nějaké zapouzdření, když je vše public? Kde je nějaká dědičnost, když všechno je dynamické a nikdo mi nebrání cokoli přepsat? Tomu fakt říkáš jazyk na vývoj?

javamane, přejmenuj se zpátky a přestaň prudit pod jiným alter egem, všichni tě poznají, protože jsi pořád stejně neschopná lopata. Ty nejenom že nerozumíš Pythonu, ty nerozumíš ani té Javě. Pro tvoji informaci, private v javě (stejně jako __ v pythonu), je jen kontrakt, který může kdokoliv porušit. Nedělám si iluze, že bys to pochopil, protože pár řádek kódu je mimo tvoje možnosti, ale s private v javě se to má takhle:
Kód: [Vybrat]
import java.lang.reflect.*;

class Foo
{
    private String foo;

    public Foo()
    {
        foo = "foo";
    }

    public void print()
    {
        System.out.println(foo);
    }
}

class Bar
{
    public static void main(String[] args)
    {
        Foo foo = new Foo();
        foo.print();
        try
        {
            Field f = foo.getClass().getDeclaredField("foo");
            f.setAccessible(true);
            f.set(foo, "bar");
        }
        catch (Throwable e)
        {
            System.err.println(e);
        }
        foo.print();
    }
}
Co to asi vypíše?
Kód: [Vybrat]
java Bar
foo
bar
Takže už někam zalez a přestaň nás otravovat vlastní neschopností. Děkujeme.

balki

Re:Dědičnost dnes
« Odpověď #374 kdy: 24. 01. 2017, 22:25:39 »
Kde to má rozhraní? Kde je nějaké zapouzdření, když je vše public? Kde je nějaká dědičnost, když všechno je dynamické a nikdo mi nebrání cokoli přepsat? Tomu fakt říkáš jazyk na vývoj?

javamane, přejmenuj se zpátky a přestaň prudit pod jiným alter egem, všichni tě poznají, protože jsi pořád stejně neschopná lopata. Ty nejenom že nerozumíš Pythonu, ty nerozumíš ani té Javě. Pro tvoji informaci, private v javě (stejně jako __ v pythonu), je jen kontrakt, který může kdokoliv porušit. Nedělám si iluze, že bys to pochopil, protože pár řádek kódu je mimo tvoje možnosti, ale s private v javě se to má takhle:
Kód: [Vybrat]
import java.lang.reflect.*;

class Foo
{
    private String foo;

    public Foo()
    {
        foo = "foo";
    }

    public void print()
    {
        System.out.println(foo);
    }
}

class Bar
{
    public static void main(String[] args)
    {
        Foo foo = new Foo();
        foo.print();
        try
        {
            Field f = foo.getClass().getDeclaredField("foo");
            f.setAccessible(true);
            f.set(foo, "bar");
        }
        catch (Throwable e)
        {
            System.err.println(e);
        }
        foo.print();
    }
}
Co to asi vypíše?
Kód: [Vybrat]
java Bar
foo
bar
Takže už někam zalez a přestaň nás otravovat vlastní neschopností. Děkujeme.

Toto je ukazkovy priklad nespravneho pouzitia reflexie v Jave.  Public fieldy a metody su preto public, lebo su sucastou garantovaneho rozhrania, ktore sa v buducnosti bude menit len minimalne. Kdezto private metody, tie sa neodporuca takto hackovat, lebo je velmi pravdepodobne, ze v triede v buducnosti nebudu.  Javova reflexia je velmi nepohodlna a ani sa moc nepouziva, rychlo by vas to prznenie kodu preslo. Ked chcete pouzivat taketo dirty hacky, odporucam uz radsej AspectJ. Naviac pouzivate C-ckove formatovanie na java kod, kazi mi to oci.