Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Marekuss 15. 11. 2021, 18:04:43

Název: Rust - std::ANY alebo lepší návrh?
Přispěvatel: Marekuss 15. 11. 2021, 18:04:43
Majme nasledujuci kod, kde mame strukturu X, Y, Z a majme "Database" ktora obsahuje funkciu "push" - vstup je "Any". Na zaklade typu vstupujuceho do "push" sa rozhodne ktory template sa zavola.
Dany zapis samozrejme funguje, len to nieje to prave orechove, skusenejsi kolegovia, mate nejaky navrh na zlepsenie?

Kód: [Vybrat]
// Various Structs
pub struct X {
    name: String
}

pub struct Y {
    text: String
}

pub struct Z {
    value: u64
}

/* Builder - traits */
trait DatabaseBuilder<T> {
    fn add(&self, data: &T);
}

impl DatabaseBuilder<X> for Database {
    fn push(&self, data: &X){
        /* ... */
        let y = data.name;
    }
}

impl DatabaseBuilder<Y> for Database {
    fn push(&self, data: &Y){
        /* ... */
        let y = data.text;
    }
}

impl DatabaseBuilder<Z> for Database {
    fn push(&self, data: &Z){
        /* ... */
        let y = data.value;
    }
}

/* Database */
pub struct Database {
    /* ... */
}

impl Database {
    pub fn new() -> Databse {
        /* ... */
    }

    pub fn push(&mut self, data: &dyn std::any::Any) {

        match data.downcast_ref::<X>() {
            Some(p) =>  DatabaseBuilder::<X>::push(self, p),
            None => {}
        }

        match data.downcast_ref::<Y>() {
            Some(p) =>  DatabaseBuilder::<Y>::push(self, p),
            None => {}
        }

        match data.downcast_ref::<Z>() {
            Some(p) =>  DatabaseBuilder::<Z>::push(self, p),
            None => {}
        }

    }

}
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 15. 11. 2021, 20:06:28
Proč nepoužiješ enum?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 15. 11. 2021, 20:52:10
mate nejaky navrh na zlepsenie?
Ta funkce push může být klidně generická. Nebo jde mít trait zastřešující X–Z. První řešení je více o (silných) typech, druhé o OO návrhu. Proti použití Any bych obecně nic neměl, ale typ se pak kontroluje za běhu, což nebývá úplně ideální. Navíc v Rustu má Any omezení ohledně lifetimů.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Marekuss 15. 11. 2021, 23:20:51
Mozete spravit kratky snippet, pripadne upravit kod ktory som postol? Nieje mi uplne jasne ako by som to v oboch pripadoch zrealizoval.. v Ruste som novacik tak sa rad naucim novym trikom.
Diky!
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 16. 11. 2021, 06:42:17
Mozete spravit kratky snippet, pripadne upravit kod ktory som postol?
Chtělo by to nejdříve úplný kód (bez /* ... */). U té generické metody by byla signatura
Kód: [Vybrat]
fn push<T:B>(&mut self, data:T) kde B je příslušný bound. Tohle ani není o Rustu, každý jazyk s typovými parametry má takovéto použití unifikace. V obecné rovině doporučuju co nejvíce modelovat typové podobnosti (a odlišnosti) přes traity, dynamický dispatch je na Rustu to zajímavé oproti C.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 16. 11. 2021, 10:16:30
Jak píše Idris, asi základní otázka v tvém případě je, jestli push opravdu musí umět zpracovávat Any (tj. za překladu neznáš typ pushovaných dat), nebo jestli ten typ za překladu znáš, a chceš jen, aby push bylo generické a umělo pracovat s různými typy dat.

Pokud typ za překladu znáš (a pokud je to jen trochu možné, snažil bych se to tím směrem tlačit), půjde se nějak odpíchnout od Idrisova nástřelu, když napíšeš víc, napíšeme víc i my.

Pokud ne, asi skutečně nezbude než dělat nějaký dynamic dispatch přes např. Any. I v takovém případě bych se ovšem spíš snažil případná neznámá data co nejdřív převést na nějaký konkrétní typ a udělat push generické s trait boundem a bez Any.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 16. 11. 2021, 10:28:04
Jak píše Idris, asi základní otázka v tvém případě je, jestli push opravdu musí umět zpracovávat Any (tj. za překladu neznáš typ pushovaných dat), nebo jestli ten typ za překladu znáš, a chceš jen, aby push bylo generické a umělo pracovat s různými typy dat.

Pokud typ za překladu znáš (a pokud je to jen trochu možné, snažil bych se to tím směrem tlačit), půjde se nějak odpíchnout od Idrisova nástřelu, když napíšeš víc, napíšeme víc i my.

Pokud ne, asi skutečně nezbude než dělat nějaký dynamic dispatch přes např. Any. I v takovém případě bych se ovšem spíš snažil případná neznámá data co nejdřív převést na nějaký konkrétní typ a udělat push generické s trait boundem a bez Any.

Z kódu v prvním příspěvku bych vyvozoval, že mu nejde o "libovolná data", akorát neví, jak tam procpat nějaký konečný počet různých datových typů. Jakkoli chápu, že při vytváření jednotlivé hodnoty je třeba explicitně uvést variantu a tudíž to je malinko ukecanější, pořád mi enum přijde jako menší zlo, než dynamický dispatch.

Možná by bylo ale fajn, kdyby OP uvedl, co přesně potřebuje udělat, než aby se snažil nějak přiohnout jedno místo v konkrétním návrhu.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 16. 11. 2021, 10:32:59
Pokud ne, asi skutečně nezbude než dělat nějaký dynamic dispatch přes např. Any. I v takovém případě bych se ovšem spíš snažil případná neznámá data co nejdřív převést na nějaký konkrétní typ a udělat push generické s trait boundem a bez Any.
Přesně. Když už je nutné sáhnout po Any, je dobré jeho užití izolovat a ve zbytku kódu pracovat hezky po rustovsku s typovým systémem (ten je v Rustu ostatně poměrně silný, nově včetně GADT). Traity poskytují transparentní dynamický dispatch, Any je explicitní dynamický dispatch dělaný na koleně (dost často působí jako hack nebo antipattern).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 16. 11. 2021, 10:37:32
Jakkoli chápu, že při vytváření jednotlivé hodnoty je třeba explicitně uvést variantu a tudíž to je malinko ukecanější, pořád mi enum přijde jako menší zlo, než dynamický dispatch.
Ani jedno není zlo. A enumy jsou taky dynamické (rezoluce za běhu, v Rustu to jsou ostatně součtové typy a interní implementace je stejným dynamickým mechanismem jako traity). Rozdíl je na úrovni syntaxe a potažmo čitelnosti, tam vedou "enumy". Jen to chce pro posouzení vědět přesněji, o co tazateli jde.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 16. 11. 2021, 11:58:34
...A enumy jsou taky dynamické (... interní implementace je stejným dynamickým mechanismem jako traity)...

Už jsme asi dosti offtopic, ale toto IMHO není pravda. Pro zajímavost: https://docs.rs/enum_dispatch/0.3.7/enum_dispatch/
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 16. 11. 2021, 12:38:31
Pro zajímavost: https://docs.rs/enum_dispatch/0.3.7/enum_dispatch/
Tohle je skutečně zajímavé, vypadá to jako nějaká sofistikovaná optimalizace.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 16. 11. 2021, 13:34:15
Pro zajímavost: https://docs.rs/enum_dispatch/0.3.7/enum_dispatch/
Tohle je skutečně zajímavé, vypadá to jako nějaká sofistikovaná optimalizace.
P.S. Teď jsem se dočetl, že překladač Rustu má dostat optimalizaci devirtualizací i pro traity, prý už se na tom pracuje. Pak už zůstane jako nevýhoda jen alokace na haldě, ale to s rozumným alokátorem není problém. Dík za odkaz, donutilo mě to najít si více o interní (zamýšlené) implementaci Rustu.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Marekuss 17. 11. 2021, 12:47:14

Ano, spravne. Jednotlive typy (XYZ) poznam uz v dobe prekladu, nevedel som spravne namodelovat Trait tak, aby som vedel "nacpat" XYZ do funkcie "push", a teda, vyuzil som mne zname std::Any.
Proč nepoužiješ enum?
Este niesom v Ruste spravne "zabehnuty" takze, neviem/netusim ako konkretne by som pouzil Enum ako nahradu za Struct ( tomto konkretnom priklade)

fn push<T:B>(&mut self, data:T)

Ano, k tomuto som sa rovnako dopracoval +- ked ste to postol.

Posielam prehladnejsi, upravenejsi kod, samozrejme v kode pouzivam Result<(), Error>, len pre prehladnost som to odstranil.
Uz sa mi to vcelku pozdava, az na nutnost DatabaseMembers, ale to si myslim, ze casom a skusenostami optimalizujem :)
Diky

Kód: [Vybrat]
use MYSQL::Connection;

pub enum DatabaseMembers {
    X,
    Y,
    Z
}

// Various Structs
pub struct X {
    pub name: String
}

pub struct Y {
    pub text: String
}

pub struct Z {
    pub value: u64
}

/* Builder - traits */
trait DatabaseBuilder {
    fn push(&self, c: &Option<Connection>);
    fn create_table(c: &Option<Connection>);
}

impl DatabaseBuilder for X {
    fn push(&self, c: &Option<Connection>){
        let query = query = "INSERT INTO x (name) VALUES (?1)"
        let query_params = params![&self.name];

        match c {
            Some(e) => e.execute(query, query_params)?,
            None => {},
        };
    }

    fn create_table(c: &Option<Connection>){
        let query =
            "CREATE TABLE IF NOT EXISTS X (
                id      INTEGER PRIMARY KEY,
                name    TEXT NOT NULL,
            );";
        match c {
            Some(e) => e.execute(query, [])?,
            None => {},
        }
    }

}

impl DatabaseBuilder for Y {
    fn push(&self, c: &Option<Connection>){
        let query = query = "INSERT INTO y (text) VALUES (?1)"
        let query_params = params![&self.value];

        match c {
            Some(e) => e.execute(query, query_params)?,
            None => {},
        };
    }

    fn create_table(c: &Option<Connection>){
        let query =
            "CREATE TABLE IF NOT EXISTS X (
                id      INTEGER PRIMARY KEY,
                text    TEXT NOT NULL,
            );";
        match c {
            Some(e) => e.execute(query, [])?,
            None => {},
        }
    }
}

impl DatabaseBuilder for Z {
    fn push(&self, c: &Option<Connection>){
        let query = query = "INSERT INTO z (name) VALUES (?1)"
        let query_params = params![&self.name];

        match c {
            Some(e) => e.execute(query, query_params)?,
            None => {},
        };
    }

    fn create_table(c: &Option<Connection>){
        let query =
            "CREATE TABLE IF NOT EXISTS X (
                id      INTEGER PRIMARY KEY,
                name    INTEGER,
            );";
        match c {
            Some(e) => e.execute(query, [])?,
            None => {},
        }
    }
}

impl DatabaseBuilder for Database {
    fn push(&self, c: &Option<Connection>){};
    fn create_table(c: &Option<Connection>){};
}

/* Database */
pub struct Database {
    c: Option<Connection>,
}

impl Database {
    pub fn new() -> Database {
        Database {
            c: None,
        }
    }

    pub fn open_temporary(&mut self){
        self.c = Some(Connection::open_in_memory());
    }

    pub fn push<T: DatabaseBuilder>(&mut self, data: &T) {
        data.push(&self.conn)
    }

    pub fn create_table(&mut self, m: DatabaseMembers) {
        match m {
            DatabaseMembers::X => X::create_table(&self.conn),
            DatabaseMembers::Y => Y::create_table(&self.conn),
            DatabaseMembers::Z => Z::create_table(&self.conn),
        }
    }
}

fn main() {

    let mut db: Database = Database::new();
    db.open_temporary();


    // X   
    db.create_table(DatabaseMembers::X);
    let x = X {name: String::from("Ahoj")};
    db.push(&x);

    // Y   
    db.create_table(DatabaseMembers::Y);
    let y = Y {text: String::from("Ahoj")};
    db.push(&y);

}


Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 17. 11. 2021, 14:14:39
fn push<T:B>(&mut self, data:T)
Ano, k tomuto som sa rovnako dopracoval +- ked ste to postol.
Jo, tohle je standard (nejen) v Rustu. Součtové typy (rustí enum) můžou být rychlejší (překladač Rustu traity evidentně nedevirtualizuje).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 17. 11. 2021, 16:05:24
fn push<T:B>(&mut self, data:T)
Ano, k tomuto som sa rovnako dopracoval +- ked ste to postol.
Jo, tohle je standard (nejen) v Rustu. Součtové typy (rustí enum) můžou být rychlejší (překladač Rustu traity evidentně nedevirtualizuje).

Když použiješ traitu jako typový parametr funkce (fn f<T>(t: T)...), překladač ji pro konkrétní typ "monomorfizuje", tj. přeloží specializovanou verzi přímo tomu typu na míru. To se výkonově těžko dá překonat.

Když použiješ traitu jako trait object (Box<dyn T>, nebo &dyn T, které naházíš třeba do Vec, abys mohl mít "heterogenní" kolekci), dostaneš fat pointer - vtable+data. Volání se děje dispatchem přes tu vtable. Devirtualizovat to asi vždy půjde jen omezeně, v principu může být těch implementací (tj. různých vtablů) spousta.

Když použiješ enum, je to obyčejný datový typ, tj. žádný fat pointer, na konkrétní variantě matchuješ, a když je těch variant málo, je vcelku zjevný, že to matchování se dá implementovat rychleji (jedním dvěma ify, což pak může spekulativní provádění instrukcí vykonat prakticky hned), než dereference přes vtable (i když samozřejmě když pak v kolekci bude třeba jeden typ trait objectu výrazně převažovat, tak to díky cache a branch predikci nejspíš bude taky docela odsejpat, ale i tak je to alespoň dvakrát tolik dat než jednoduchý enum).

V praxi se samozřejmě člověk mezi enumem a trait objectem rozhoduje nejvíc podle toho, jestli jde o uzavřený nebo otevřený typ.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 17. 11. 2021, 16:17:18
Devirtualizovat to asi vždy půjde jen omezeně
To dá rozum, když je to heuristická optimalizace. Typicky se používá v různých JIT překladačích a runtimech à la Smalltalk. Rust prostě tuhle optimalizaci (zatim?) nemá, pro C++ existuje údajně v experimentální formě. Každopádně až v Rustu bude, enumy už nebudou mít výhodu rychlosti.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 17. 11. 2021, 16:28:27

Debilní root fórum systém, psal jsem se s tím asi půl hodiny, mezitím mě to odhlásilo a příspěvek nenávratně zmizel. Tak ještě jednou v rychlosti:

push<T: DatabaseBuilder> - dobrý.

Chtělo by to trochu učesat:

Nelíbí se mi ty Optiony v push, create_table, a možná i v Database, myslím že by bylo lepší je zrušit. Navíc bych čekal, že budou brát &mut self.

Kdyby ses chtěl zbavit těch DatabaseMembers, který jsou opravdu podivný, mohla by se třeba udělat lazy inicializace tabulek přímo v Database, např. něco jako (nevím jestli půjde přeložit)

pub struct Database {
    initialized_tables: HashSet<TypeId>,
    c: Connection,
}

impl Database {
    fn init_table<T: DatabaseBuilder + 'static>(&mut self) {
        let type_id = TypeId::of::<T>();
        if !self.initialized_tables.contains(&type_id) {
            T::create_table(&self.c);
            self.initialized_tables.insert(type_id);
        }
    }

    pub fn push<T: DatabaseBuilder + 'static>(&mut self, data: &T) {
        self.init_table::<T>();
        data.push(&self.conn)
    }
}
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 17. 11. 2021, 16:33:27
Devirtualizovat to asi vždy půjde jen omezeně
To dá rozum, když je to heuristická optimalizace. ...Každopádně až v Rustu bude, enumy už nebudou mít výhodu rychlosti.

Spíš bych řekl, že "až v Rustu bude, enumy v některých případech už nebudou mít výhodu rychlosti, nebo bude rozdíl v rychlosti menší".
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 17. 11. 2021, 17:42:06

Debilní root fórum systém, psal jsem se s tím asi půl hodiny, mezitím mě to odhlásilo a příspěvek nenávratně zmizel. Tak ještě jednou v rychlosti:

push<T: DatabaseBuilder> - dobrý.

Chtělo by to trochu učesat:

Nelíbí se mi ty Optiony v push, create_table, a možná i v Database, myslím že by bylo lepší je zrušit. Navíc bych čekal, že budou brát &mut self.

Kdyby ses chtěl zbavit těch DatabaseMembers, který jsou opravdu podivný, mohla by se třeba udělat lazy inicializace tabulek přímo v Database, např. něco jako (nevím jestli půjde přeložit)

pub struct Database {
    initialized_tables: HashSet<TypeId>,
    c: Connection,
}

impl Database {
    fn init_table<T: DatabaseBuilder + 'static>(&mut self) {
        let type_id = TypeId::of::<T>();
        if !self.initialized_tables.contains(&type_id) {
            T::create_table(&self.c);
            self.initialized_tables.insert(type_id);
        }
    }

    pub fn push<T: DatabaseBuilder + 'static>(&mut self, data: &T) {
        self.init_table::<T>();
        data.push(&self.conn)
    }
}
Zrovna TypeId je stejně haram jako Any.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Marekuss 17. 11. 2021, 21:40:24
Dik za hint, mas pravdu, to s tym Option optimalizujem (:
K tomu navrhu cez Lazy Init, super napad, rovno to pouzijem, uvazoval som ale nic lepsie ma prakticky na momentalne sksuenosti nenapada.

Este raz dik za hint.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 17. 11. 2021, 22:04:59
K tomu navrhu cez Lazy Init, super napad, rovno to pouzijem, uvazoval som ale nic lepsie ma prakticky na momentalne sksuenosti nenapada.
Jde to elegantněji přes get_or_insert.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Marekuss 17. 11. 2021, 22:16:35
K tomu navrhu cez Lazy Init, super napad, rovno to pouzijem, uvazoval som ale nic lepsie ma prakticky na momentalne sksuenosti nenapada.
Jde to elegantněji přes get_or_insert.

Diky za hint, vyzera to ako tiez dobra cesta :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 18. 11. 2021, 09:14:09
Zrovna TypeId je stejně haram jako Any.

Jo, já osobně TypeId taky zatím nikdy nepoužil, ale pro tohle zadání mi to přišlo jako elegantní jednoduchý řešení .. alespoň jsem nepřišel na lepší, napadá tě něco?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 09:33:52
Zrovna TypeId je stejně haram jako Any.
Jo, já osobně TypeId taky zatím nikdy nepoužil, ale pro tohle zadání mi to přišlo jako elegantní jednoduchý řešení .. alespoň jsem nepřišel na lepší, napadá tě něco?
Ne, ale je to stejně nesystémové jako Any. Jasně se ukazuje, že Rust potřebuje aspoň nějaký malý stabilní runtime, pokud chce věrohodně rozšířit pole působnosti. I když s C++ si nemá co vyčítat. (Podle interních informací z Googlu je právě tohle důvodem, proč Rust více nepodporují na App Engine a jiných cloudových službách.)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 18. 11. 2021, 09:38:16
K tomu navrhu cez Lazy Init, super napad, rovno to pouzijem, uvazoval som ale nic lepsie ma prakticky na momentalne sksuenosti nenapada.
Jde to elegantněji přes get_or_insert.

HashSet::get_or_insert je nightly, a stejně nevím jak by se to na to dalo použít. Šlo by použít get_or_insert_with, a tu closure na počítání hodnoty k vložení do HashSety zneužít k inicializaci tabulky takhle: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=d221825d869185554b7077d109a55157 , ale jestli je to elegantnější, to je s otazníkem. Je fakt, že to možná bude o trochu rychlejší, odpadne duplicitní lookup, ale možná že by to optimalizátor v té první verzi eliminoval.

Kdybych nechtěl používat nightly a chtěl to takhle v jednom kroku, dala by se místo HashSet použít HashMap<TypeId, ()> a entry api HashMap-y, za cenu jistého zamlžení sémantiky (premature optimization is the root of all evil, že).

K tomu pro zajímavost - přesně takhle je v rustu implementovaná HashSet - když to zjednoduším, je to obal nad HashMapou s unit hodnotama, mírně zjednodušeno

pub struct HashSet<T> {
    map: HashMap<T, ()>,
}

impl<T> HashSet<T> {
    pub fn contains<Q>(&self, value: &Q) -> bool
    {
        self.map.contains_key(value)
    }

 // atp...
}

Přijde mi naprosto úžasný, že takhle definovaná HashSeta je optimálně rychlá, nemusí se znovu nic reimplementovat, unit hodnoty vnitřní hashmapy se vyoptimalizují pryč.



Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 18. 11. 2021, 09:40:49
Zrovna TypeId je stejně haram jako Any.
Jo, já osobně TypeId taky zatím nikdy nepoužil, ale pro tohle zadání mi to přišlo jako elegantní jednoduchý řešení .. alespoň jsem nepřišel na lepší, napadá tě něco?
Ne, ale je to stejně nesystémové jako Any. Jasně se ukazuje, že Rust potřebuje aspoň nějaký malý stabilní runtime, pokud chce věrohodně rozšířit pole působnosti. I když s C++ si nemá co vyčítat. (Podle interních informací z Googlu je právě tohle důvodem, proč Rust více nepodporují na App Engine a jiných cloudových službách.)

Můžeš rozvést, co myslíš v tomhle případě runtimem, a k čemu by měl být Rustu užitečný?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 10:32:47
odpadne duplicitní lookup
Ano, a na tohle by se mělo hledět vždy. (Zvlášť lidi od C++ tohle hned v kódu vidí a kritizují :) neb STL tohle řeší hezky.)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 10:34:37
K tomu pro zajímavost - přesně takhle je v rustu implementovaná HashSet - když to zjednoduším, je to obal nad HashMapou [...] Přijde mi naprosto úžasný, že takhle definovaná HashSeta je optimálně rychlá, nemusí se znovu nic reimplementovat, unit hodnoty vnitřní hashmapy se vyoptimalizují pryč.
Jo, to je známý pattern, Go to má stejně tak (ani nic nemusí optimalizovat, má struct{}).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 10:46:07
Můžeš rozvést, co myslíš v tomhle případě runtimem, a k čemu by měl být Rustu užitečný?
Myslím to, to myslí runtimem autoři Rustu (chlubíce se, že žádný nemá). Nechci zabředávat do diskusí (osobně mě absence runtimu, autory tolik vychvalovaná, netrápí, máme přece C++, Javu, Go, .NET Core :) etc., každý dle svého gusta), ale právě lidi od App Engine si stěžují na absenci alespoň elementární dynamické reflexe (statická se dá v Rustu nasimulovat a hodně modulů to dělá). Proto zatím App Engine nemá plnou podporu pro Rust, těžko se jim integruje s jejich Datastorem, Memcache apod. IMHO tohle už není pole působnosti Rustu, ale někteří rustí nadšenci by ho zřejmě chtěli vidět všude a Google neustále "otravují" :) Podle jednoho jejich vývojáře chtějí přidat C++, až bude mít odsouhlasené některé TS (přesunuté do C++23), to se pak rustíci pominou, že je C++ předběhlo :D

Dle mého subjektivního názoru je možná i lepší, že tam ten dynamický runtime není, začátečníci jsou tak nuceni psát pořádně objektově (resp. traitově, kdyby někdo trval na implikaci OO=>dědičnost). Problém ale je v případech, kdy by se hodil, a těžko může být jedna verze Rustu pro juniory a jiná pro ty, kteří ví, co dělají, a dynamičnost nezneužijí k přiohnutí jazyka či návrhu.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 18. 11. 2021, 11:42:32
odpadne duplicitní lookup
Ano, a na tohle by se mělo hledět vždy. (Zvlášť lidi od C++ tohle hned v kódu vidí a kritizují :) neb STL tohle řeší hezky.)

Koukám že HashSet::insert vrací, jestli už tam vkládaný prvek byl nebo ne, takže se to celý dá zjednodušit na optimální

    fn init_table<T: DatabaseBuilder + 'static>(&mut self) {
        let type_id = TypeId::of::<T>();
        if self.initialized_tables.insert(type_id) {
            T::create_table(&mut self.c);
        }
    }

Jak by se to dělalo se Set-ou v C++ STL?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 11:46:41
Jak by se to dělalo se Set-ou v C++ STL?
V tomto případě stejně, insert v std::set taky indikuje, jestli se prvek přidal.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 18. 11. 2021, 11:49:00
Můžeš rozvést, co myslíš v tomhle případě runtimem, a k čemu by měl být Rustu užitečný?
... ale právě lidi od App Engine si stěžují na absenci alespoň elementární dynamické reflexe ...

Pod dynamickou reflexi se toho může schovat hodně (v extrému třeba smalltalkovský #become: , #allInstances, #selectors, metatřídy, reifikovaný callstack), ale v Rustu si ani základnější věci příliš představit nedovedu, těžko třeba zjišťovat typ nějaké hodnoty když se optimalizátor rozhodl ji úplně vyhodit, a i kdyby ne tak k ní stejně nejsou metadata. No, uvidíme, co se vymyslí.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 11:58:50
Můžeš rozvést, co myslíš v tomhle případě runtimem, a k čemu by měl být Rustu užitečný?
... ale právě lidi od App Engine si stěžují na absenci alespoň elementární dynamické reflexe ...
Pod dynamickou reflexi se toho může schovat hodně (v extrému třeba smalltalkovský #become: , #allInstances, #selectors, metatřídy, reifikovaný callstack), ale v Rustu si ani základnější věci příliš představit nedovedu, těžko třeba zjišťovat typ nějaké hodnoty když se optimalizátor rozhodl ji úplně vyhodit, a i kdyby ne tak k ní stejně nejsou metadata. No, uvidíme, co se vymyslí.
No právě, jde o metadata. Třeba Go má velký runtime, ale hlavně kvůli GC. Ideální runtime má ObjC, ten je malý, flexibilní, elegantní, prostě skvěle navržený a implementovaný. Nebo microsoftí metadata u C++ se taky povedly, než to zrušili :) Ale Rust je v podstatě asembler s GADT, tak v nic moc nedoufám :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 13:59:45
třeba smalltalkovský #become: , #allInstances, #selectors, metatřídy, reifikovaný callstack
BTW takhle daleko asi nikdo jít nechce — to už může rovnou použít Smalltalk nebo ObjC :) — ale reifikované invokace jsou ještě před hranicí užitečnosti a neprůhledné magie :) Jinak u Rustu bych fakt moc neřádil, ostatně mantra jeho autorů je abstrakce bez ztráty efektivity (nebo tak nějak) a dává smysl mít bezpečné a efektivní C s mocnými makry ;)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 18. 11. 2021, 17:16:47

Ano, spravne. Jednotlive typy (XYZ) poznam uz v dobe prekladu, nevedel som spravne namodelovat Trait tak, aby som vedel "nacpat" XYZ do funkcie "push", a teda, vyuzil som mne zname std::Any.
Proč nepoužiješ enum?
Este niesom v Ruste spravne "zabehnuty" takze, neviem/netusim ako konkretne by som pouzil Enum ako nahradu za Struct ( tomto konkretnom priklade)

Očividně jsme se nepochopili, enum v Rustu je, jak správně poznamenal Idris, součtový typ, tedy něco jako variantní typ v jiných jazycích - můžeš na základě zvolené varianty (typicky pattern matching) vzít vnitřek (např. instanci struktury X, Y nebo Z) a pracovat s ním "hezky" namísto toho řešení, které jsi měl původně. Struktura a enum se v Rustu doplňují a to dost elegantně.

Tvoje nové řešení používá enum a la C, což není samozřejmě nic špatného, ale já jsem si představoval něco jiného - muselo by se to ale celé překopat. Jinak doporučuju se mrknout na Diesel a podobná řešení DB v Rustu - ať už pro náhradu nebo inspiraci.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 18. 11. 2021, 17:17:46
Prosím případně smazat (ignorovat), nevím, jak se tento příspěvek vytvořil.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 18. 11. 2021, 17:21:22
Tvoje nové řešení používá enum a la C
Podle mě je totiž matoucí nazvat součtové typy "enum", člověk si nese z C (a podobných jím ovlivněných) nějakou představu, která je velice daleko od součtových typů ve funkcionálním pojetí (a nepomáhá ani nazvat je "indirect enum" jako ve Swiftu, spíše naopak...).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Marekuss 18. 11. 2021, 17:34:26
Očividně jsme se nepochopili, enum v Rustu je, jak správně poznamenal Idris, součtový typ, tedy něco jako variantní typ v jiných jazycích - můžeš na základě zvolené varianty (typicky pattern matching) vzít vnitřek (např. instanci struktury X, Y nebo Z) a pracovat s ním "hezky" namísto toho řešení, které jsi měl původně. Struktura a enum se v Rustu doplňují a to dost elegantně.

Tvoje nové řešení používá enum a la C, což není samozřejmě nic špatného, ale já jsem si představoval něco jiného - muselo by se to ale celé překopat. Jinak doporučuju se mrknout na Diesel a podobná řešení DB v Rustu - ať už pro náhradu nebo inspiraci.
Nakolko v tomto pripade sa mi jedna o navrh, tak reimplementacia do Rustovskeho Enumu je taka studijna vyzva :). Pozrem co ponuka doc rustu na Enum, pattern matching a pod. Postnem to sem na reviziu a pre porovnanie.

Diky za hint

Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 19. 11. 2021, 10:25:36
Očividně jsme se nepochopili, enum v Rustu je, jak správně poznamenal Idris, součtový typ, tedy něco jako variantní typ v jiných jazycích - můžeš na základě zvolené varianty (typicky pattern matching) vzít vnitřek (např. instanci struktury X, Y nebo Z) a pracovat s ním "hezky" namísto toho řešení, které jsi měl původně. Struktura a enum se v Rustu doplňují a to dost elegantně.

Tvoje nové řešení používá enum a la C, což není samozřejmě nic špatného, ale já jsem si představoval něco jiného - muselo by se to ale celé překopat. Jinak doporučuju se mrknout na Diesel a podobná řešení DB v Rustu - ať už pro náhradu nebo inspiraci.
Nakolko v tomto pripade sa mi jedna o navrh, tak reimplementacia do Rustovskeho Enumu je taka studijna vyzva :). Pozrem co ponuka doc rustu na Enum, pattern matching a pod. Postnem to sem na reviziu a pre porovnanie.

Diky za hint
Rozhodně doporučuji naučit se pattern matching pořádně, Rust je tím prolezlý (vracení chyb, prázdných hodnot…). Chce to zvyknout si na syntax (match, if let…), jinak to žádná věda není a přispívá to k bezpečnosti kódu. Taky doporučuji nezvykat si na unwrap :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: ondra05 19. 11. 2021, 15:02:10
Očividně jsme se nepochopili, enum v Rustu je, jak správně poznamenal Idris, součtový typ, tedy něco jako variantní typ v jiných jazycích - můžeš na základě zvolené varianty (typicky pattern matching) vzít vnitřek (např. instanci struktury X, Y nebo Z) a pracovat s ním "hezky" namísto toho řešení, které jsi měl původně. Struktura a enum se v Rustu doplňují a to dost elegantně.

Tvoje nové řešení používá enum a la C, což není samozřejmě nic špatného, ale já jsem si představoval něco jiného - muselo by se to ale celé překopat. Jinak doporučuju se mrknout na Diesel a podobná řešení DB v Rustu - ať už pro náhradu nebo inspiraci.
Nakolko v tomto pripade sa mi jedna o navrh, tak reimplementacia do Rustovskeho Enumu je taka studijna vyzva :). Pozrem co ponuka doc rustu na Enum, pattern matching a pod. Postnem to sem na reviziu a pre porovnanie.

Diky za hint
Rozhodně doporučuji naučit se pattern matching pořádně, Rust je tím prolezlý (vracení chyb, prázdných hodnot…). Chce to zvyknout si na syntax (match, if let…), jinak to žádná věda není a přispívá to k bezpečnosti kódu. Taky doporučuji nezvykat si na unwrap :)

A raději si zvyknout na otazníky :)

Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 19. 11. 2021, 15:15:53
Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.
Kdo by to čekal, že do tak nízkoúrovňového jazyka proniknou natolik abstraktní funkcionální konstrukty :) Nakonec ta symbióza funguje celkem hladce.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 19. 11. 2021, 15:38:27
Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.

Těmi monádami myslíš prosím co?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 20. 11. 2021, 11:45:07
Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.
Kdo by to čekal, že do tak nízkoúrovňového jazyka proniknou natolik abstraktní funkcionální konstrukty :) Nakonec ta symbióza funguje celkem hladce.

Zcela off-topic, Idrisi, tohle by se ti mohlo líbit: https://maybevoid.com/blog/mononym-part-1/
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 20. 11. 2021, 12:36:08
Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.
Kdo by to čekal, že do tak nízkoúrovňového jazyka proniknou natolik abstraktní funkcionální konstrukty :) Nakonec ta symbióza funguje celkem hladce.
Zcela off-topic, Idrisi, tohle by se ti mohlo líbit: https://maybevoid.com/blog/mononym-part-1/
Jo, to jsem zaregistroval, akorát jsem se k tomu ještě podrobněji nedostal. Dík za odkaz a připomenutí.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: ondra05 20. 11. 2021, 14:15:39
Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.

Těmi monádami myslíš prosím co?

Result, Option, Future, Iterator...
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 20. 11. 2021, 14:24:28
Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.
Těmi monádami myslíš prosím co?
Result, Option, Future, Iterator...
Teď už to chce jen HKT a z Rustu bude Haskell. I k DT už mají našlápnuto :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 21. 11. 2021, 07:21:52
Popravdě, od té doby co dělám v Rustu mi přijde způsob řešení takových věcí bez součtových typů, pattern matchingu a monád hrozně kostrbatý.

Těmi monádami myslíš prosím co?

Result, Option, Future, Iterator...

OK, takže jde o to, že na existujících standardních typech s výhodou využíváš monadický přístup, jestli tomu rozumím dobře. Přemýšlel jsem, jestli má smysl jít někam dál a víc to "ohaskellovat"...
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: registrovany_ava 21. 11. 2021, 09:14:52
Těmi monádami myslíš prosím co?

Result, Option, Future, Iterator...

OK, takže jde o to, že na existujících standardních typech s výhodou využíváš monadický přístup, jestli tomu rozumím dobře. Přemýšlel jsem, jestli má smysl jít někam dál a víc to "ohaskellovat"...

Jj, monády bez HKT a nějaké formy do-notation jsou dost polovičatý. Pro rust existují věci jako https://crates.io/crates/do-notation , ale moc se to nepoužívá. S nejpoužívanějšími monádami (Result, Option, Future) se v rustu pracuje jinak(?, async/await), State není moc potřeba protože máme exclusive mutability, u řetězených and_then (monadické bind) u Iterátorů člověk často narazí na borrow checker nebo příliš krátce žijící data. Takže rustovský svět m-word moc nepoužívá, a pro komunitu je to asi i zdravější.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 21. 11. 2021, 09:37:44
Těmi monádami myslíš prosím co?
Result, Option, Future, Iterator...
OK, takže jde o to, že na existujících standardních typech s výhodou využíváš monadický přístup, jestli tomu rozumím dobře. Přemýšlel jsem, jestli má smysl jít někam dál a víc to "ohaskellovat"...
Jj, monády bez HKT a nějaké formy do-notation jsou dost polovičatý. Pro rust existují věci jako https://crates.io/crates/do-notation , ale moc se to nepoužívá. S nejpoužívanějšími monádami (Result, Option, Future) se v rustu pracuje jinak(?, async/await), State není moc potřeba protože máme exclusive mutability, u řetězených and_then (monadické bind) u Iterátorů člověk často narazí na borrow checker nebo příliš krátce žijící data. Takže rustovský svět m-word moc nepoužívá, a pro komunitu je to asi i zdravější.
V poslední době se zda, že Rust jde cestou GADT. Ty jsou IMHO vhodnější pro Rust.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Rike 26. 11. 2021, 19:22:20
Já jsem z Rustu bohužel docela zklamán. Jazyk nese určité zajímavé prvky, o tom žádná, ale ten ekosystém, to je hrůza. Většina "crates", co jsem chtěl zkoušet, byla ve verzi 0.x, přičemž část kvůli nedodržování zpětné kompatibility nešla kompilovat. Chce to asi ještě čas.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 26. 11. 2021, 20:24:14
Já jsem z Rustu bohužel docela zklamán. Jazyk nese určité zajímavé prvky, o tom žádná, ale ten ekosystém, to je hrůza. Většina "crates", co jsem chtěl zkoušet, byla ve verzi 0.x, přičemž část kvůli nedodržování zpětné kompatibility nešla kompilovat. Chce to asi ještě čas.
Rust se vyvíjí dost živelně, ale IMHO to zas taková hrůza není. S důležitými crates problémy nebývají.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: kate 26. 11. 2021, 21:26:07
Já jsem z Rustu bohužel docela zklamán. Jazyk nese určité zajímavé prvky, o tom žádná, ale ten ekosystém, to je hrůza. Většina "crates", co jsem chtěl zkoušet, byla ve verzi 0.x, přičemž část kvůli nedodržování zpětné kompatibility nešla kompilovat. Chce to asi ještě čas.

Které třeba? Používáme Rust jako hlavní jazyk pro backend a s nezkompilovatelnou knihovnou jsem se ještě nesetkala. Problémy mladého ekosystému to tedy má, občas musíme pro potřebnou funkcionalitu přispívat do upstreamu víc než by to bylo nutné v něčem mnohem starším jako Python.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 27. 11. 2021, 07:32:57
Já jsem z Rustu bohužel docela zklamán. Jazyk nese určité zajímavé prvky, o tom žádná, ale ten ekosystém, to je hrůza. Většina "crates", co jsem chtěl zkoušet, byla ve verzi 0.x, přičemž část kvůli nedodržování zpětné kompatibility nešla kompilovat. Chce to asi ještě čas.

Bylo by asi fajn, kdybys byl konkrétnější. Udělat a publikovat crate může kdekdo, je tedy docela přirozené, že budou v různém stavu. Bez urážky, chce to trochu selského rozumu, případně zkušenosti, aby člověk poznal stabilní a rozumně vyvíjené od nedopečených pokusů. Možná bys mohl zkusit https://lib.rs/ , tam by měly být ty ověřené.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Rike 27. 11. 2021, 12:26:24
Jo, jenže ono není k mému "tématu" moc na výběr. Potíž s kompilací jsem měl zde: https://crates.io/crates/intercom, a nenašel jsem vůbec pořádnou "crate" na SOAP WSDL server. Dočetl jsem se na jednom blogu z roku 2020, že podpora XML vůbec je v Rustu zatím slabá.

Čekal jsem prostě trošku víc. Už tu ten ekosystém nějaký pátek je a měl by být náhradou za C/C++, přičemž by měl ale nabízet částečně přístup známý z "velkých" jazyků. To se mi jako "reklama" líbí. Chce to asi ještě trochu toho času, než budou pokryta i takováto "témata".
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 27. 11. 2021, 12:51:06
Jo, jenže ono není k mému "tématu" moc na výběr. Potíž s kompilací jsem měl zde: https://crates.io/crates/intercom, a nenašel jsem vůbec pořádnou "crate" na SOAP WSDL server. Dočetl jsem se na jednom blogu z roku 2020, že podpora XML vůbec je v Rustu zatím slabá.

Čekal jsem prostě trošku víc. Už tu ten ekosystém nějaký pátek je a měl by být náhradou za C/C++, přičemž by měl ale nabízet částečně přístup známý z "velkých" jazyků. To se mi jako "reklama" líbí. Chce to asi ještě trochu toho času, než budou pokryta i takováto "témata".
Zrovna COM s Rustem moc nekamarádí. Tohle se většinou řeší tak, že se napíše wrapper v C++ a do něj se staticky přilinkuje rustí knihovna.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 27. 11. 2021, 19:22:56
Jo, jenže ono není k mému "tématu" moc na výběr. Potíž s kompilací jsem měl zde: https://crates.io/crates/intercom, a nenašel jsem vůbec pořádnou "crate" na SOAP WSDL server. Dočetl jsem se na jednom blogu z roku 2020, že podpora XML vůbec je v Rustu zatím slabá.

Čekal jsem prostě trošku víc. Už tu ten ekosystém nějaký pátek je a měl by být náhradou za C/C++, přičemž by měl ale nabízet částečně přístup známý z "velkých" jazyků. To se mi jako "reklama" líbí. Chce to asi ještě trochu toho času, než budou pokryta i takováto "témata".

Podle mě tohle není moc pravděpodobné, jelikož generaci vývojářů, která nejčastěji používá Rust, tohle nechává dost klidnou. Většina novějších API, se kterými jsem se setkal v posledních cca 7 letech, SOAP nepoužívá a naimplementovat to dobře je asi dost práce. COM jde mimo mě už úplně, ale jelikož se Rust v nějaké míře prosadil i v Microsoftu, kdoví.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 27. 11. 2021, 19:52:56
Jo, jenže ono není k mému "tématu" moc na výběr. Potíž s kompilací jsem měl zde: https://crates.io/crates/intercom, a nenašel jsem vůbec pořádnou "crate" na SOAP WSDL server. Dočetl jsem se na jednom blogu z roku 2020, že podpora XML vůbec je v Rustu zatím slabá.

Čekal jsem prostě trošku víc. Už tu ten ekosystém nějaký pátek je a měl by být náhradou za C/C++, přičemž by měl ale nabízet částečně přístup známý z "velkých" jazyků. To se mi jako "reklama" líbí. Chce to asi ještě trochu toho času, než budou pokryta i takováto "témata".
Podle mě tohle není moc pravděpodobné, jelikož generaci vývojářů, která nejčastěji používá Rust, tohle nechává dost klidnou. Většina novějších API, se kterými jsem se setkal v posledních cca 7 letech, SOAP nepoužívá a naimplementovat to dobře je asi dost práce. COM jde mimo mě už úplně, ale jelikož se Rust v nějaké míře prosadil i v Microsoftu, kdoví.
Jo, SOAP je peklo a patří na smetiště IT dějin. COM by ale problém být neměl, MS napsal celou rustí vrstvu nad svým API (i když zrovna COM je lepší řešit přes MSVC).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 28. 11. 2021, 02:43:56
SOAP je peklo a patří na smetiště IT dějin.

Proč?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 28. 11. 2021, 09:07:22
SOAP je peklo a patří na smetiště IT dějin.
Proč?
To je vážně míněná otázka? Odpovědí jsou všechny důvody, proč vzniklo například gRPC.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Rike 28. 11. 2021, 11:55:40
Jako dobrý, ale pořád mi přijde jednodušší sestavit SOAP klienta v těžce zastaralých systémech, než tam průkopnicky sestavovat gRPC klienta.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 28. 11. 2021, 12:05:09
Jako dobrý, ale pořád mi přijde jednodušší sestavit SOAP klienta v těžce zastaralých systémech, než tam průkopnicky sestavovat gRPC klienta.
Pak je ale vůbec nesmysl “průkopnicky” nasazovat Rust :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Rike 28. 11. 2021, 12:40:29
Pak je ale vůbec nesmysl “průkopnicky” nasazovat Rust :)
No jo, chtěl jsem se sobecky naučit něco nového a nakonec jsem spadl do vlastní díry  :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 28. 11. 2021, 14:15:14
Pak je ale vůbec nesmysl “průkopnicky” nasazovat Rust :)
No jo, chtěl jsem se sobecky naučit něco nového a nakonec jsem spadl do vlastní díry  :)

Sobče, vzdělávat ses chtěl!
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 28. 11. 2021, 14:15:33
Pak je ale vůbec nesmysl “průkopnicky” nasazovat Rust :)
No jo, chtěl jsem se sobecky naučit něco nového a nakonec jsem spadl do vlastní díry  :)
Tak zrovna Rust má smysl se učit, i když ho nakonec člověk nepoužije. Ale nedá se čekat podpora obskurních obstarožních technologií. Já zrovna kdysi Rust na Windows použil, ale rozhraní bylo v C++/CLI (byla to komponenta pro .NET, ne COM). Rust umí vytvářet statické knihovny a dobře si rozumí s MSVC. Ale napsat to celé v Rustu, to není úplně schůdné.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 28. 11. 2021, 14:16:59
Pak je ale vůbec nesmysl “průkopnicky” nasazovat Rust :)
No jo, chtěl jsem se sobecky naučit něco nového a nakonec jsem spadl do vlastní díry  :)
Sobče, vzdělávat ses chtěl!
Hehe, furt lepší než různí javamani, co místo sebevzdělávání nadávají všem vzdělaným a úspěšným :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 29. 11. 2021, 01:25:30
SOAP je peklo a patří na smetiště IT dějin.
Proč?
To je vážně míněná otázka? Odpovědí jsou všechny důvody, proč vzniklo například gRPC.

Jo, je to vážně míněná otázka.

Se SOAP jsem dělal (Java, C#, PHP). Netvrdím, že je to nějaká slává, prostě jsem to vzal v potaz a používal (když to klienti chtěli...).

RPC jsem používal dřív, různé implementace v Pythonu (patnáct let zpět). A mám za to, že je to krapet něco jiného než SOAP, ale nechám se poučit.

Aktuálně frčí REST, ale přijde mi to jako trochu jinak řešený stejný problém, akorát že tam zatím není standardizovaný nějaký popis rozhraní jako WSDL. Třeba časem.

gRPC neznám, díky za tip.

Ptal jsem se proto, že občas slyším někoho nadávat na SOAP, ale většinou to jsou jen tak obecné nářky. A mě známé nevýhody, že je to ukecané a že je to v XML mi přijde trochu málo na takové zhodnocení. Hoď sem něco z patra prosím.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 29. 11. 2021, 03:03:32
SOAP je peklo a patří na smetiště IT dějin.
Proč?
To je vážně míněná otázka? Odpovědí jsou všechny důvody, proč vzniklo například gRPC.
Aktuálně frčí REST, ale přijde mi to jako trochu jinak řešený stejný problém, akorát že tam zatím není standardizovaný nějaký popis rozhraní jako WSDL. Třeba časem.

gRPC neznám, díky za tip.
Je to celé o efektivitě, REST je poměrně pomalý a parsovat XML je taky zbytečně zdlouhavé. Proto vymysleli Protobuf, což je extrémně úsporný protokol, a gRPC nad ním jede přes HTTP/2, takže bez zbytečných latencí. Žádná věda v tom není, ostatně pokud člověk neřeší miliony RPC volání za hodinu, tak ho asi použití JSONu nebo XML pálit nebude. Jen prostě parsování sežere dost CPU cyklů a paměti.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 29. 11. 2021, 08:16:47
Aktuálně frčí REST, ale přijde mi to jako trochu jinak řešený stejný problém, akorát že tam zatím není standardizovaný nějaký popis rozhraní jako WSDL. Třeba časem.

OAS nestačí? https://en.wikipedia.org/wiki/OpenAPI_Specification
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 29. 11. 2021, 10:38:11
Aktuálně frčí REST, ale přijde mi to jako trochu jinak řešený stejný problém, akorát že tam zatím není standardizovaný nějaký popis rozhraní jako WSDL. Třeba časem.

OAS nestačí? https://en.wikipedia.org/wiki/OpenAPI_Specification
OpenAPI (aka Swagger) je jeden z mála standardů, co se v poslední povedl.

@BoneFlute Jestli to neznáš, doporučuju aspoň mrknout.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 29. 11. 2021, 23:45:19
SOAP je peklo a patří na smetiště IT dějin.
Proč?
To je vážně míněná otázka? Odpovědí jsou všechny důvody, proč vzniklo například gRPC.
Aktuálně frčí REST, ale přijde mi to jako trochu jinak řešený stejný problém, akorát že tam zatím není standardizovaný nějaký popis rozhraní jako WSDL. Třeba časem.

gRPC neznám, díky za tip.
Je to celé o efektivitě, REST je poměrně pomalý a parsovat XML je taky zbytečně zdlouhavé. Proto vymysleli Protobuf, což je extrémně úsporný protokol, a gRPC nad ním jede přes HTTP/2, takže bez zbytečných latencí. Žádná věda v tom není, ostatně pokud člověk neřeší miliony RPC volání za hodinu, tak ho asi použití JSONu nebo XML pálit nebude. Jen prostě parsování sežere dost CPU cyklů a paměti.

Takže to
Citace
je peklo a patří na smetiště IT dějin
je čistě proto, že SOAP je neefektivní? Nebo je mu vyčítáno i něco jiného?

Aktuálně frčí REST, ale přijde mi to jako trochu jinak řešený stejný problém, akorát že tam zatím není standardizovaný nějaký popis rozhraní jako WSDL. Třeba časem.

OAS nestačí? https://en.wikipedia.org/wiki/OpenAPI_Specification
OpenAPI (aka Swagger) je jeden z mála standardů, co se v poslední povedl.

Už jsem o něj zavadil, ale ještě jsem si na něj neudělal závěr. Takže díky za referenci.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 01:18:55
Aktuálně frčí REST, ale přijde mi to jako trochu jinak řešený stejný problém, akorát že tam zatím není standardizovaný nějaký popis rozhraní jako WSDL. Třeba časem.

co je OpenAPI?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 30. 11. 2021, 07:08:12
Takže to
Citace
je peklo a patří na smetiště IT dějin
je čistě proto, že SOAP je neefektivní? Nebo je mu vyčítáno i něco jiného?

Je to řešení ze světa Javy a velkých korporací. Design by committee, překomplikovaný, se spoustou rozšíření a ukrutně náročný, když to chceš znovu naimplementovat, ať už v jiném programovacím jazyce (jak jsme si tu koneckonců demonstrovali) nebo protože Ti stávající řešení třetích stran z nějakého důvodu nevyhovuje. Chceš poslat zprávu o tom, že Pepa Novák si kupuje ponožky za 10 dolarů a vychrstne to 5 KB XML s třemi namespacy a čtyřmi vrstvami obálek. Přitom Ty chceš jenom napsat jméno, příjmení, pár údajů o kartě a částku a nazpátek by Ti stačil číselný kód, který říká, jak to dopadlo a jeden řetězec s případným lidským popisem situace.

Krátce a výstižně, simplicity and utility trump large corporate backing: http://keithba.net/simplicity-and-utility-or-why-soap-lost
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 10:46:33
Takže to
Citace
je peklo a patří na smetiště IT dějin
je čistě proto, že SOAP je neefektivní? Nebo je mu vyčítáno i něco jiného?
překomplikovaný, se spoustou rozšíření a ukrutně náročný, když to chceš znovu naimplementovat
Přesně. Už jen samo použití XML nedává v dnešní době smysl a ty "obálky" kolem, to už je úplná magořina (z dnešního pohledu tvorby API a RPC).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 30. 11. 2021, 10:55:19
Aniž bych ostatní text ignoroval, tak:
Chceš poslat zprávu o tom, že Pepa Novák si kupuje ponožky za 10 dolarů
Mě na SOAP oslovilo právě a hlavně to WSDL. Nalinkuju jedno url, a hned mám kompletní knihovnu včetně dokumentace (fandím), typů, etc. A s žádným XML se vůbec nemusím dostat do styku (já vím, v reálu to tak nefungovalo) a nemusí mě zajímat.

To mě třeba na tom RESTu přišlo blbé. Že to sice je štíhlejší, a můžeš si to naimplementovat pár řádky kódu, ale problém je v tom, že vlastně musíš. Nejsou (nebyli) nástroje, které by udělali automaticky knihovnu a mohl jsi ty endpointy volat transparentně.

(Argument s OpenAPI prosím nechte. Pochopil jsem. Nastuduji si.)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 11:25:44
Aniž bych ostatní text ignoroval, tak:
Chceš poslat zprávu o tom, že Pepa Novák si kupuje ponožky za 10 dolarů
Mě na SOAP oslovilo právě a hlavně to WSDL. Nalinkuju jedno url, a hned mám kompletní knihovnu včetně dokumentace (fandím), typů, etc. A s žádným XML se vůbec nemusím dostat do styku (já vím, v reálu to tak nefungovalo) a nemusí mě zajímat.

To mě třeba na tom RESTu přišlo blbé. Že to sice je štíhlejší, a můžeš si to naimplementovat pár řádky kódu, ale problém je v tom, že vlastně musíš. Nejsou (nebyli) nástroje, které by udělali automaticky knihovnu a mohl jsi ty endpointy volat transparentně.

(Argument s OpenAPI prosím nechte. Pochopil jsem. Nastuduji si.)
Teď už se generuje okolo API všechno, SOAP, Protobuf, OpenAPI... (člověk tak získá nezávislost na konkrétním jazyce, to je plus).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: oss 30. 11. 2021, 13:33:23
Len by som chcel podotknut, ze OpenApi sa za desat rokov nedostalo tam, kde bol SOAP na zaciatku. Sice klient sa da generovat, ale ten tooling nie je az taky uzasny (napriklad format datumov je peklo), taktiez sa mi stava, ze klienti pre rozne jazyky sa vygeneruju zle, hoci je jasne dana specifikacia. Plus tomu chybaju niektore veci s autentifikacie, nie je mozne efktivne prenasat metadata a binarne data. Atd...

Dalej REST nie je RPC.

grpc zas chyba specifikacia akohekolvek zabezpecnia a validacie requestov, takze je to obcas dost velka partizancina.

Proste za mna SOAP prosto fungoval a fungoval dobre a vsade. A gzipnute XML je cca rovnako velke ako gzipnuty JSON.

A je vhodne pouzit gRPC na intergraciu dvoch roznych podnikov? lebo v praxy sa s nim stretvam len v komunikacii mikrosluzieb v jednej sieti.

Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 13:40:42
Aniž bych ostatní text ignoroval, tak:
Chceš poslat zprávu o tom, že Pepa Novák si kupuje ponožky za 10 dolarů
Mě na SOAP oslovilo právě a hlavně to WSDL. Nalinkuju jedno url, a hned mám kompletní knihovnu včetně dokumentace (fandím), typů, etc. A s žádným XML se vůbec nemusím dostat do styku (já vím, v reálu to tak nefungovalo) a nemusí mě zajímat.

To mě třeba na tom RESTu přišlo blbé. Že to sice je štíhlejší, a můžeš si to naimplementovat pár řádky kódu, ale problém je v tom, že vlastně musíš. Nejsou (nebyli) nástroje, které by udělali automaticky knihovnu a mohl jsi ty endpointy volat transparentně.

(Argument s OpenAPI prosím nechte. Pochopil jsem. Nastuduji si.)
Teď už se generuje okolo API všechno, SOAP, Protobuf, OpenAPI... (člověk tak získá nezávislost na konkrétním jazyce, to je plus).

generuje se jen kvuli staticke typove kontrole, ta aby fungovala, potrebujete mit specifikaci ve zdrojovem kodu daneho jazyka, ale neni problem precist napriklad protobuf specifikaci a vygenerovat dane tridy dynamicky

existuji reseni jak obejit nutnost generovani kodu pro ziskani staticke kontroly. MyPy ma pluginy, AFAIK F# ma type providers coz resi podobny problem
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 30. 11. 2021, 14:41:08
Teď už se generuje okolo API všechno, SOAP, Protobuf, OpenAPI... (člověk tak získá nezávislost na konkrétním jazyce, to je plus).

generuje se jen kvuli staticke typove kontrole, ta aby fungovala, potrebujete mit specifikaci ve zdrojovem kodu daneho jazyka, ale neni problem precist napriklad protobuf specifikaci a vygenerovat dane tridy dynamicky

existuji reseni jak obejit nutnost generovani kodu pro ziskani staticke kontroly. MyPy ma pluginy, AFAIK F# ma type providers coz resi podobny problem

Zkus pochopit, že existují statické programovací jazyky a tam to fakt je jinak a bude.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 15:03:00
Teď už se generuje okolo API všechno, SOAP, Protobuf, OpenAPI... (člověk tak získá nezávislost na konkrétním jazyce, to je plus).

generuje se jen kvuli staticke typove kontrole, ta aby fungovala, potrebujete mit specifikaci ve zdrojovem kodu daneho jazyka, ale neni problem precist napriklad protobuf specifikaci a vygenerovat dane tridy dynamicky

existuji reseni jak obejit nutnost generovani kodu pro ziskani staticke kontroly. MyPy ma pluginy, AFAIK F# ma type providers coz resi podobny problem

Zkus pochopit, že existují statické programovací jazyky a tam to fakt je jinak a bude.
Ono ani tak nejde o typový systém, jde to řešit buď reflexí nebo něčím jako rustí makra.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 15:06:09
Teď už se generuje okolo API všechno, SOAP, Protobuf, OpenAPI... (člověk tak získá nezávislost na konkrétním jazyce, to je plus).

generuje se jen kvuli staticke typove kontrole, ta aby fungovala, potrebujete mit specifikaci ve zdrojovem kodu daneho jazyka, ale neni problem precist napriklad protobuf specifikaci a vygenerovat dane tridy dynamicky

existuji reseni jak obejit nutnost generovani kodu pro ziskani staticke kontroly. MyPy ma pluginy, AFAIK F# ma type providers coz resi podobny problem

Zkus pochopit, že existují statické programovací jazyky a tam to fakt je jinak a bude.
Ono ani tak nejde o typový systém, jde to řešit buď reflexí nebo něčím jako rustí makra.

teoreicky muze typovy system brat informace z externiho zdroje.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 30. 11. 2021, 15:35:14
Ono ani tak nejde o typový systém, jde to řešit buď reflexí nebo něčím jako rustí makra.

Jde to asi různě, ale chceme to?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 15:36:04
Teď už se generuje okolo API všechno, SOAP, Protobuf, OpenAPI... (člověk tak získá nezávislost na konkrétním jazyce, to je plus).
generuje se jen kvuli staticke typove kontrole, ta aby fungovala, potrebujete mit specifikaci ve zdrojovem kodu daneho jazyka, ale neni problem precist napriklad protobuf specifikaci a vygenerovat dane tridy dynamicky

existuji reseni jak obejit nutnost generovani kodu pro ziskani staticke kontroly. MyPy ma pluginy, AFAIK F# ma type providers coz resi podobny problem
Zkus pochopit, že existují statické programovací jazyky a tam to fakt je jinak a bude.
Ono ani tak nejde o typový systém, jde to řešit buď reflexí nebo něčím jako rustí makra.
teoreicky muze typovy system brat informace z externiho zdroje.
To jo, taky se to často děje, ale jak to souvisí s OpenAPI?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 15:37:26
Ono ani tak nejde o typový systém, jde to řešit buď reflexí nebo něčím jako rustí makra.
Jde to asi různě, ale chceme to?
Reflexi asi nechceme (tedy jen init-time), ale generování kódu z ASTu zabudované přímo do syntaxe jazyka určitě všemi deseti.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 16:42:47
To jo, taky se to často děje, ale jak to souvisí s OpenAPI?

muzete mit satickou kontrolu podle API specifikace, bez nunosti prepisovat tu specifikaci do daneho jazyka. Staticky analyzer kodu muze brat informace napriklad z JSON schematu. nebo z protobuffer specifikaci. Nemusite generovat kod.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 17:17:06
To jo, taky se to často děje, ale jak to souvisí s OpenAPI?
muzete mit satickou kontrolu podle API specifikace, bez nunosti prepisovat tu specifikaci do daneho jazyka. Staticky analyzer kodu muze brat informace napriklad z JSON schematu. nebo z protobuffer specifikaci. Nemusite generovat kod.
A kde to takto funguje?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 30. 11. 2021, 18:07:23
To jo, taky se to často děje, ale jak to souvisí s OpenAPI?
muzete mit satickou kontrolu podle API specifikace, bez nunosti prepisovat tu specifikaci do daneho jazyka. Staticky analyzer kodu muze brat informace napriklad z JSON schematu. nebo z protobuffer specifikaci. Nemusite generovat kod.
A kde to takto funguje?

Pánové, jsem dost překvapený, co řešíte. Když se teda vrátím k Rustu, tak tam chci vidět něco jako normální strukturu, která je napíchnutá na serde_json nebo něco takového, pokud mi to vygeneruje něco automaticky, tak super, ale rozhodně nechci, aby se mi data někde nějak vzala - stejně někde na vstupu a výstupu budu potřebovat normální explicitně deklarovaný typ.

Úplně chápu, že v Pythonu můžu mít nějaké něco, které má někde __getattr__() nebo něco a magicky tahá z klobouku data, která má v dictu nebo kdoví kde, ale v Rustu to fakt nechci a doufám, že ani nebudu potřebovat.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 18:53:54
To jo, taky se to často děje, ale jak to souvisí s OpenAPI?
muzete mit satickou kontrolu podle API specifikace, bez nunosti prepisovat tu specifikaci do daneho jazyka. Staticky analyzer kodu muze brat informace napriklad z JSON schematu. nebo z protobuffer specifikaci. Nemusite generovat kod.
A kde to takto funguje?

treba https://github.com/erickpeirson/jsonschema-typed
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 19:00:03
Type Providers https://docs.microsoft.com/en-us/dotnet/fsharp/tutorials/type-providers/

https://github.com/fsprojects/OpenAPITypeProvider
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 19:02:06
....

vubec nevis o cem pisu.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 19:53:30
To jo, taky se to často děje, ale jak to souvisí s OpenAPI?
muzete mit satickou kontrolu podle API specifikace, bez nunosti prepisovat tu specifikaci do daneho jazyka. Staticky analyzer kodu muze brat informace napriklad z JSON schematu. nebo z protobuffer specifikaci. Nemusite generovat kod.
A kde to takto funguje?
Pánové, jsem dost překvapený, co řešíte. Když se teda vrátím k Rustu, tak tam chci vidět něco jako normální strukturu
Přesně tohle “řešíme”.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 30. 11. 2021, 20:16:41
Pánové, jsem dost překvapený, co řešíte. Když se teda vrátím k Rustu, tak tam chci vidět něco jako normální strukturu
Přesně tohle “řešíme”.

Přijde mi, že hledáte cestičky, jak normální kód negenerovat.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 30. 11. 2021, 20:18:18
....

vubec nevis o cem pisu.

Ale jo. Bohužel.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 20:33:26
Pánové, jsem dost překvapený, co řešíte. Když se teda vrátím k Rustu, tak tam chci vidět něco jako normální strukturu
Přesně tohle “řešíme”.

Přijde mi, že hledáte cestičky, jak normální kód negenerovat.

generovany kod je zlo.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 30. 11. 2021, 20:38:34
Přijde mi, že hledáte cestičky, jak normální kód negenerovat.

generovany kod je zlo.

K tomuto tématu jsem domluvil, nemám potřebu se dohadovat o tom, kdo má rád vdolky a kdo holky, protože nic lepšího z toho nekouká.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 30. 11. 2021, 22:20:06
Pánové, jsem dost překvapený, co řešíte. Když se teda vrátím k Rustu, tak tam chci vidět něco jako normální strukturu
Přesně tohle “řešíme”.
Přijde mi, že hledáte cestičky, jak normální kód negenerovat.
generovany kod je zlo.
Zlo je i alkohol a kolik lidí chlastá. Jak by se jinak řešil Protobuf nebo třeba typově bezpečné ORM v C++/Rustu/Go jinak než generováním? Dynamicky to jde ve Smalltalku nebo ObjC a jo, je to elegantní, ovšem bez extrémní dynamičnosti to nejde.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 30. 11. 2021, 23:10:03
Pánové, jsem dost překvapený, co řešíte. Když se teda vrátím k Rustu, tak tam chci vidět něco jako normální strukturu
Přesně tohle “řešíme”.
Přijde mi, že hledáte cestičky, jak normální kód negenerovat.
generovany kod je zlo.
Zlo je i alkohol a kolik lidí chlastá. Jak by se jinak řešil Protobuf nebo třeba typově bezpečné ORM v C++/Rustu/Go jinak než generováním? Dynamicky to jde ve Smalltalku nebo ObjC a jo, je to elegantní, ovšem bez extrémní dynamičnosti to nejde.
.
jde to pomoci Type Provideru, na ktere jsem daval odkaz. Neco podobneho jsou pluginy v MyPy.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: oss 01. 12. 2021, 08:54:07
Pánové, jsem dost překvapený, co řešíte. Když se teda vrátím k Rustu, tak tam chci vidět něco jako normální strukturu
Přesně tohle “řešíme”.
Přijde mi, že hledáte cestičky, jak normální kód negenerovat.
generovany kod je zlo.
Zlo je i alkohol a kolik lidí chlastá. Jak by se jinak řešil Protobuf nebo třeba typově bezpečné ORM v C++/Rustu/Go jinak než generováním? Dynamicky to jde ve Smalltalku nebo ObjC a jo, je to elegantní, ovšem bez extrémní dynamičnosti to nejde.
.
jde to pomoci Type Provideru, na ktere jsem daval odkaz. Neco podobneho jsou pluginy v MyPy.

Type Provider je len krajsie meno pre generator kodu, ktory je na urovni jazyka.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 01. 12. 2021, 15:16:53
generovany kod je zlo.

Silná slova. Pokud své tvrzení něčím nepodložíš, tak platí, že "generuj co můžeš".
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 01. 12. 2021, 15:29:05
generovany kod je zlo.

Silná slova. Pokud své tvrzení něčím nepodložíš, tak platí, že "generuj co můžeš".

neni to DRY.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 01. 12. 2021, 15:57:02
generovany kod je zlo.

Silná slova. Pokud své tvrzení něčím nepodložíš, tak platí, že "generuj co můžeš".

neni to DRY.

dokud ten generovany kod nekdo necommitne do repositare nebo nedej boze nezacne rucne editovat tak mi generovany kod nevadi... v opacnem pripade souhlasim, ze je to zlo
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 01. 12. 2021, 16:03:01
generovany kod je zlo.

Silná slova. Pokud své tvrzení něčím nepodložíš, tak platí, že "generuj co můžeš".

neni to DRY.

dokud ten generovany kod nekdo necommitne do repositare nebo nedej boze nezacne rucne editovat tak mi generovany kod nevadi... v opacnem pripade souhlasim, ze je to zlo
To commitování se děje dost často. Editace snad ne, aspoň já se s tím nesetkal.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Ink 01. 12. 2021, 17:15:36
dokud ten generovany kod nekdo necommitne do repositare nebo nedej boze nezacne rucne editovat tak mi generovany kod nevadi... v opacnem pripade souhlasim, ze je to zlo

A jaký to je problém, když to commitne? Když se to API mění jednou za uherský rok nebo vůbec, nevidím v tom žádný problém.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 01. 12. 2021, 19:48:29
generovany kod je zlo.
Silná slova. Pokud své tvrzení něčím nepodložíš, tak platí, že "generuj co můžeš".
Je třeba to brát pragmaticky. Když to jde jinak, je lepší negenerovat. Ovšem často není jiné cesty, třeba gRPC nebo různé ORM v C++/Go, pokud mají být použitelné, jinak nejdou.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 01. 12. 2021, 20:00:43
dokud ten generovany kod nekdo necommitne do repositare nebo nedej boze nezacne rucne editovat tak mi generovany kod nevadi... v opacnem pripade souhlasim, ze je to zlo

A jaký to je problém, když to commitne? Když se to API mění jednou za uherský rok nebo vůbec, nevidím v tom žádný problém.

To co se muze zmenit se zmeni... kdyz se to deje zridka tak to znamena ze na to nejsem zvyklej a o to vic me to muze zmast.
Za to co je v repositari citim odpovednost. Nechci citit zodpovednost za neco co vygeneroval stroj.
Kdyz delam code review tak se musim podivat jestli zmena ve schematu odpovida zmene v generovanem souboru...
Kdyz na tom dela vic lidi najednou tak se pak treba musi resit ze nekdo commitne zmenu schematu, ale uz ne zmeny v generovanem kodu... Nic se nerozbije, ale je to matouci...
Kdyz budes mit v aplikaci nejaky submodul ktery se meni zridka nebo vubec a nejaky jiny na nem zavisi... tak budes commitovat i binarku?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 01. 12. 2021, 22:13:36
dokud ten generovany kod nekdo necommitne do repositare nebo nedej boze nezacne rucne editovat tak mi generovany kod nevadi... v opacnem pripade souhlasim, ze je to zlo

A jaký to je problém, když to commitne? Když se to API mění jednou za uherský rok nebo vůbec, nevidím v tom žádný problém.

To co se muze zmenit se zmeni... kdyz se to deje zridka tak to znamena ze na to nejsem zvyklej a o to vic me to muze zmast.
Za to co je v repositari citim odpovednost. Nechci citit zodpovednost za neco co vygeneroval stroj.
Kdyz delam code review tak se musim podivat jestli zmena ve schematu odpovida zmene v generovanem souboru...
Kdyz na tom dela vic lidi najednou tak se pak treba musi resit ze nekdo commitne zmenu schematu, ale uz ne zmeny v generovanem kodu... Nic se nerozbije, ale je to matouci...
Kdyz budes mit v aplikaci nejaky submodul ktery se meni zridka nebo vubec a nejaky jiny na nem zavisi... tak budes commitovat i binarku?

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

Má to tyto důsledky:
V prvním případě se jede na tvrdo optimalizace, stroj může cokoliv.
V druhém případě je očekáváno, že to co se vygeneruje musí být co nejvíce čitelné; nejlépe optimalizované pro diff. (A následně se to třeba celé ještě projede první variantou.)

TypoProvidery a podobně jsou jen první varianta. Jen už zakomponovaná do překladače. Jak už tu někdo zmínil. Ve skutečnosti je to ale spousta dalších případů: gcc, javac, scalac, ... etc, kde by tě ani nepadlo uvažovat, že je to jen prachsprostej generátor kódu. A ne, není to něco jiného :)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 06:27:05

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

Má to tyto důsledky:
V prvním případě se jede na tvrdo optimalizace, stroj může cokoliv.
V druhém případě je očekáváno, že to co se vygeneruje musí být co nejvíce čitelné; nejlépe optimalizované pro diff. (A následně se to třeba celé ještě projede první variantou.)

TypoProvidery a podobně jsou jen první varianta. Jen už zakomponovaná do překladače. Jak už tu někdo zmínil. Ve skutečnosti je to ale spousta dalších případů: gcc, javac, scalac, ... etc, kde by tě ani nepadlo uvažovat, že je to jen prachsprostej generátor kódu. A ne, není to něco jiného :)

Mel bys nejakej netrivialni priklad 2?
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 02. 12. 2021, 10:01:45

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

Má to tyto důsledky:
V prvním případě se jede na tvrdo optimalizace, stroj může cokoliv.
V druhém případě je očekáváno, že to co se vygeneruje musí být co nejvíce čitelné; nejlépe optimalizované pro diff. (A následně se to třeba celé ještě projede první variantou.)

TypoProvidery a podobně jsou jen první varianta. Jen už zakomponovaná do překladače. Jak už tu někdo zmínil. Ve skutečnosti je to ale spousta dalších případů: gcc, javac, scalac, ... etc, kde by tě ani nepadlo uvažovat, že je to jen prachsprostej generátor kódu. A ne, není to něco jiného :)

Mel bys nejakej netrivialni priklad 2?

ORM modely pro existujici databazi, DB migrace (vetsinou nemusite cist, ale obcas chcete modifikovat).
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 11:11:58

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

...

Mel bys nejakej netrivialni priklad 2?

ORM modely pro existujici databazi, DB migrace (vetsinou nemusite cist, ale obcas chcete modifikovat).

Generovane ORM modely je treba schvalovat clovekem?
(Vim ze se to deje... I na mem soucasnem projektu to tak je... dokonce mi tam do entit cpou business logiku.... ale nelibi se mi to a bojuju proti tomu... protoze si myslim, ze je to nepekne a neni to potreba.)
Tem DB migracim asi nerozumim...
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 02. 12. 2021, 12:02:53
Generovane ORM modely je treba schvalovat clovekem?

myslim situaci, kdy je vygenerujete jednou z legacy databaze a potom uz je edituje clovek. vetsinou nejak funguji out of box, ale DB metadata vetsinou neobsahuji vsechny potrebne informace, musi doplnit clovek.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 12:15:46
Generovane ORM modely je treba schvalovat clovekem?

myslim situaci, kdy je vygenerujete jednou z legacy databaze a potom uz je edituje clovek. vetsinou nejak funguji out of box, ale DB metadata vetsinou neobsahuji vsechny potrebne informace, musi doplnit clovek.

Mozna... to jsem, ale jeste nezazil, ze bych mel legacy DB a chtel nad ni stavet novy projekt pro ktery bych si z ni generoval model...
Asi bych se i v takovem pripade snazil o nejaky jiny pristup...
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 02. 12. 2021, 13:24:51
Mozna... to jsem, ale jeste nezazil, ze bych mel legacy DB a chtel nad ni stavet novy projekt pro ktery bych si z ni generoval model...

podle me docela casta situace.

Asi bych se i v takovem pripade snazil o nejaky jiny pristup...

jaky?

pokud chcete ORM, alternativni pristup je pouzit reflexi z metadat, a dopsat jen to co chcete navic. (co nejde odvodit). Coz se hodi u nejakych malych jednoucelovych veci.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 02. 12. 2021, 13:43:43
jinak podle me vetsina ORM reflexi bez explicitniho vygenerovani kodu ani neumoznuje. Ja to pouzivam v SQLAlchemy, ale treba v djangu nebo rails active record to AFAIK nejde.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 02. 12. 2021, 14:57:54

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

Má to tyto důsledky:
V prvním případě se jede na tvrdo optimalizace, stroj může cokoliv.
V druhém případě je očekáváno, že to co se vygeneruje musí být co nejvíce čitelné; nejlépe optimalizované pro diff. (A následně se to třeba celé ještě projede první variantou.)

TypoProvidery a podobně jsou jen první varianta. Jen už zakomponovaná do překladače. Jak už tu někdo zmínil. Ve skutečnosti je to ale spousta dalších případů: gcc, javac, scalac, ... etc, kde by tě ani nepadlo uvažovat, že je to jen prachsprostej generátor kódu. A ne, není to něco jiného :)

Mel bys nejakej netrivialni priklad 2?

Inspiroval bych se co ostatní uváděli: mám verzovanou databázi. Změním tabulku, přejmenuju pár sloupců. schema-manage mi zařve, že je tam neverzovaná změna. Řeknu mu teda, aby vygeneroval sql-commit z té změny. Jenže jsem ty sloupce přejmenoval tak šikovně, že jsem ten nástroj zmátl, a on místo aby udělal příkaz pro přejmenování, tak udělá drop table + create table. Takže to předělám jak to má být, a commitnu.

Nebo z PHP světa, composer: nastavím si balíček, že má být ve verzi vendor/balicek:1.*, a on mi vygeneruje graf závislostí, kde bude jinejvendor/jinejbalicek:1.8.6, ale já vím, že zrovna tento má chybu, a potřebuju nižší/vyšší. Tak to poedituju/přinutím mu dát konkrétní verzi, a zase dám composerem zkontrolovat závislosti a vygenerovat graf.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 16:23:05
Mozna... to jsem, ale jeste nezazil, ze bych mel legacy DB a chtel nad ni stavet novy projekt pro ktery bych si z ni generoval model...

podle me docela casta situace.

Asi bych se i v takovem pripade snazil o nejaky jiny pristup...

jaky?

pokud chcete ORM, alternativni pristup je pouzit reflexi z metadat, a dopsat jen to co chcete navic. (co nejde odvodit). Coz se hodi u nejakych malych jednoucelovych veci.

Asi bych sel nejakou cestou podobnou jako treba u jaxb.
Zvlastni soubor s pravidly pro kustomizaci, ktery se pri generovani zpracuje vedle schematu a vygenerovany entity budou rovnou tak jak je chci....

Zalezelo by na konkretni situaci. Bez konkretniho prikladu co by tam bylo potreba menit nedokazu rict.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 02. 12. 2021, 16:40:20
Zalezelo by na konkretni situaci. Bez konkretniho prikladu co by tam bylo potreba menit nedokazu rict.

typicky vztahy, ktere nejdou vycist z cizich klicu.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 16:43:59
Inspiroval bych se co ostatní uváděli: mám verzovanou databázi. Změním tabulku, přejmenuju pár sloupců. schema-manage mi zařve, že je tam neverzovaná změna. Řeknu mu teda, aby vygeneroval sql-commit z té změny. Jenže jsem ty sloupce přejmenoval tak šikovně, že jsem ten nástroj zmátl, a on místo aby udělal příkaz pro přejmenování, tak udělá drop table + create table. Takže to předělám jak to má být, a commitnu.

S verzovanim DB schemat mam trochu problem... (kdyz neco verzuju tak predpokladam ze se snadno budu moct vratit k predchozi verzi ale to u DB a netrivialnich zmen "snadno" nejde) ale to je asi jedno.
V tomhle pripade je to stejne jedno.... co znamena ze "prejmenuju par sloupecku"
Pripojim se k DB a spustim nejaky "alter table" ne?

Takze jestli te spravne chapu tak si pustis nejakej kod nad DB, ten si neulozis protoze mas prece schema manage.
Ten ti ho vygeneruje spatne, takze to tam prepises aby to bylo tak jak uz si to jednou delal... a pak to commitnes.
Je to tak?
V tom pripade mi prijde jednodussi rovnou commitovat ty zmeny tak jak sem je psal predtim rucne a vynechat generator.

Nebo z PHP světa, composer: nastavím si balíček, že má být ve verzi vendor/balicek:1.*, a on mi vygeneruje graf závislostí, kde bude jinejvendor/jinejbalicek:1.8.6, ale já vím, že zrovna tento má chybu, a potřebuju nižší/vyšší. Tak to poedituju/přinutím mu dát konkrétní verzi, a zase dám composerem zkontrolovat závislosti a vygenerovat graf.

V php sem uz dloooouho nic nedelal takze si nejsem jistej v kramflecich, ten graf zavislosti je potreba commitovat?
Ale obcene bych nepovazoval konfiguraci dependency managementu za "kod".
Takze tam jsem OK s tim ze se kousek nejak generuje a kousek pise rucne.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 16:52:00
Zalezelo by na konkretni situaci. Bez konkretniho prikladu co by tam bylo potreba menit nedokazu rict.

typicky vztahy, ktere nejdou vycist z cizich klicu.

Jakoze mam sice sloupec s nejakejma IDckama z jiny tabule ale nemam nad tim definovany cizi klic?
No pak je otazka jestli chci, aby bylo to ORM chytrejsi nez sama databaze...
Nemit tam ten cizi klic muze mit nejakej duvod. A ja si pak spis myslim, ze je lepsi to ctit i v modelu.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: A.P.Hacker 02. 12. 2021, 17:05:53
Zalezelo by na konkretni situaci. Bez konkretniho prikladu co by tam bylo potreba menit nedokazu rict.

typicky vztahy, ktere nejdou vycist z cizich klicu.

Jakoze mam sice sloupec s nejakejma IDckama z jiny tabule ale nemam nad tim definovany cizi klic?
No pak je otazka jestli chci, aby bylo to ORM chytrejsi nez sama databaze...
Nemit tam ten cizi klic muze mit nejakej duvod. A ja si pak spis myslim, ze je lepsi to ctit i v modelu.

to je prave ten pripad, kdy chcete vygenerovany kod editovat rucne. Vygenerovane casti ale mohou byt i oddelene.

Zalezi, jestli v budoucnu hodlate generovat zmeny v DB podle aplikace, nebo naopak chcete synchronizovat podle DB, potom je editace vygenerovaneho kodu hloupost.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 02. 12. 2021, 17:32:33
Inspiroval bych se co ostatní uváděli: mám verzovanou databázi. Změním tabulku, přejmenuju pár sloupců. schema-manage mi zařve, že je tam neverzovaná změna. Řeknu mu teda, aby vygeneroval sql-commit z té změny. Jenže jsem ty sloupce přejmenoval tak šikovně, že jsem ten nástroj zmátl, a on místo aby udělal příkaz pro přejmenování, tak udělá drop table + create table. Takže to předělám jak to má být, a commitnu.

S verzovanim DB schemat mam trochu problem... (kdyz neco verzuju tak predpokladam ze se snadno budu moct vratit k predchozi verzi ale to u DB a netrivialnich zmen "snadno" nejde) ale to je asi jedno.
V tomhle pripade je to stejne jedno.... co znamena ze "prejmenuju par sloupecku"
Pripojim se k DB a spustim nejaky "alter table" ne?

Takze jestli te spravne chapu tak si pustis nejakej kod nad DB, ten si neulozis protoze mas prece schema manage.
Ten ti ho vygeneruje spatne, takze to tam prepises aby to bylo tak jak uz si to jednou delal... a pak to commitnes.
Je to tak?
V tom pripade mi prijde jednodussi rovnou commitovat ty zmeny tak jak sem je psal predtim rucne a vynechat generator.
Ono je to tak jak říkáš. A je to pravda, že by to bylo jednodužší, kdyby to lidi dělali. Ale oni to nedělají. Takže než poslouchat nadávky, to tam je ten generátor, a vysvětlit jim, že si to jen musí ještě zkontrolovat je reálnější.

Nebo z PHP světa, composer: nastavím si balíček, že má být ve verzi vendor/balicek:1.*, a on mi vygeneruje graf závislostí, kde bude jinejvendor/jinejbalicek:1.8.6, ale já vím, že zrovna tento má chybu, a potřebuju nižší/vyšší. Tak to poedituju/přinutím mu dát konkrétní verzi, a zase dám composerem zkontrolovat závislosti a vygenerovat graf.

V php sem uz dloooouho nic nedelal takze si nejsem jistej v kramflecich, ten graf zavislosti je potreba commitovat?
Ale obcene bych nepovazoval konfiguraci dependency managementu za "kod".
Takze tam jsem OK s tim ze se kousek nejak generuje a kousek pise rucne.
Ten graf závislostí je třeba commitovat (není to specifikum php, je to principielní problém), protože ty máš v jednom souboru uvedený cca verze a balíčky, které chceš, zatímco v tom druhém souboru jsou už přesné verze všech balíčků. Aby se pokaždé vygeneroval stejný graf a stáhly se vždycky ty samé balíčky - důsledky si asi domyslíš.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 02. 12. 2021, 17:43:03

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

Má to tyto důsledky:
V prvním případě se jede na tvrdo optimalizace, stroj může cokoliv.
V druhém případě je očekáváno, že to co se vygeneruje musí být co nejvíce čitelné; nejlépe optimalizované pro diff. (A následně se to třeba celé ještě projede první variantou.)

TypoProvidery a podobně jsou jen první varianta. Jen už zakomponovaná do překladače. Jak už tu někdo zmínil. Ve skutečnosti je to ale spousta dalších případů: gcc, javac, scalac, ... etc, kde by tě ani nepadlo uvažovat, že je to jen prachsprostej generátor kódu. A ne, není to něco jiného :)

Mel bys nejakej netrivialni priklad 2?

Příklad 3: VisualStudio má návrháře UI. Můžeš si tam naklikat, natahat, naarangovat elementy. Ty se potom zapíšou do souboru. Buď do C#, nebo do XAML. V případě XAML se tento ještě zpracovává do výsledného něčeho. C# je part třída, kde máš jednu část, kterou má na starost návrhář, a druhou část, kterou používáš ty jako vývojář pro vlastní opičárny. Když hrábneš do té návrhářské třídy, tak pokud to nepřeženeš, tak se to zpětně promítne do toho návrháře. Osvědčilo se mi do té návrhářské třídy koukat. Lépe si všimnu, že jsem udělal nějakou nepravost. Nebo naopak, při přejmenování nějakého elementu, se přejmenuje i tady a návrhář to v pohodě zkousne.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 17:50:20

Nebo z PHP světa, composer: nastavím si balíček, že má být ve verzi vendor/balicek:1.*, a on mi vygeneruje graf závislostí, kde bude jinejvendor/jinejbalicek:1.8.6, ale já vím, že zrovna tento má chybu, a potřebuju nižší/vyšší. Tak to poedituju/přinutím mu dát konkrétní verzi, a zase dám composerem zkontrolovat závislosti a vygenerovat graf.

V php sem uz dloooouho nic nedelal takze si nejsem jistej v kramflecich, ten graf zavislosti je potreba commitovat?
Ale obcene bych nepovazoval konfiguraci dependency managementu za "kod".
Takze tam jsem OK s tim ze se kousek nejak generuje a kousek pise rucne.
Ten graf závislostí je třeba commitovat (není to specifikum php, je to principielní problém), protože ty máš v jednom souboru uvedený cca verze a balíčky, které chceš, zatímco v tom druhém souboru jsou už přesné verze všech balíčků. Aby se pokaždé vygeneroval stejný graf a stáhly se vždycky ty samé balíčky - důsledky si asi domyslíš.

No nejakou dobu uz sem to nemusel resit ale pokud si pamatuju dobre tak maven a leiningen oba funguji tak ze kdyz uvedu explixitni zavislost primo na nejake verzi tak se ta verze pouzije i pro tranzitivni zavislosti.
(Myslim, ze aspon driv maven fungoval tak ze ta explicitni verze musela byt uvedena "nahore", coz je trochu napalici, ale nevim jestli to tak porad je).

Graf si sice muzu vygenerovat ale nikam ho nekomitnu, protoze to stejne pri buildu nikdo nepouzije.


Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 02. 12. 2021, 18:02:07
Graf si sice muzu vygenerovat ale nikam ho nekomitnu, protoze to stejne pri buildu nikdo nepouzije.
Graf ne, ale informace o těch konkrétních závislostech ano. Chceš tři balíčky s nějakou cca verzí - dostaneš jich stovku s konkrétní verzí. Zkontroluješ, zda všechno funguje a tím, že to commitneš (tu stovku balíčků se specifickými závislostmy) tak uděláš schválení, že takto je to správně.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 18:05:39

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

Má to tyto důsledky:
V prvním případě se jede na tvrdo optimalizace, stroj může cokoliv.
V druhém případě je očekáváno, že to co se vygeneruje musí být co nejvíce čitelné; nejlépe optimalizované pro diff. (A následně se to třeba celé ještě projede první variantou.)

TypoProvidery a podobně jsou jen první varianta. Jen už zakomponovaná do překladače. Jak už tu někdo zmínil. Ve skutečnosti je to ale spousta dalších případů: gcc, javac, scalac, ... etc, kde by tě ani nepadlo uvažovat, že je to jen prachsprostej generátor kódu. A ne, není to něco jiného :)

Mel bys nejakej netrivialni priklad 2?

Příklad 3: VisualStudio má návrháře UI. Můžeš si tam naklikat, natahat, naarangovat elementy. Ty se potom zapíšou do souboru. Buď do C#, nebo do XAML. V případě XAML se tento ještě zpracovává do výsledného něčeho. C# je part třída, kde máš jednu část, kterou má na starost návrhář, a druhou část, kterou používáš ty jako vývojář pro vlastní opičárny. Když hrábneš do té návrhářské třídy, tak pokud to nepřeženeš, tak se to zpětně promítne do toho návrháře. Osvědčilo se mi do té návrhářské třídy koukat. Lépe si všimnu, že jsem udělal nějakou nepravost. Nebo naopak, při přejmenování nějakého elementu, se přejmenuje i tady a návrhář to v pohodě zkousne.

Hmmm s tim sem nikdy nedelal.
Pamatuju si nejaky takovy udelatko pro Qt a jestli se nepletu tak tam se to do jednoho souboru nemotalo.
Tam byl snad v tom navrhari nejaky dialog pro event binding nebo co... to se mi zda lepsi.
Navic vystup z toho snad bylo nejaky xml a ne primo trida v cilovem jazyce.
Ale kdo vi... uz je to davno

Navic tady jsme trochu dal od generovani neceho ze schematu.
Tady "programator" "programuje". Sice tahanim nejakejch policek po formulari, ale to je jedno... to ze existuje kod a jeho visualni reprezentace je v poradku. Je to jedinny "zdroj pravdy" tak je v poradku ze to commitnu.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 18:13:19
Graf si sice muzu vygenerovat ale nikam ho nekomitnu, protoze to stejne pri buildu nikdo nepouzije.
Graf ne, ale informace o těch konkrétních závislostech ano. Chceš tři balíčky s nějakou cca verzí - dostaneš jich stovku s konkrétní verzí. Zkontroluješ, zda všechno funguje a tím, že to commitneš (tu stovku balíčků se specifickými závislostmy) tak uděláš schválení, že takto je to správně.

to fakt v mavenu ani v leiningenu nedelam... A nebo te porad spatne chapu.

Zavisim na balicku A:1.2.3 co zavisi na X, Y, Z.
Y zavisi na P ve verzi 3.14 a ten ma bug.
Moje zavislosti budou:

Maven sam spravne dotahne i X, Y, a Z a P tam budu mit ve verzi 3.1415

ale kdyz se podivam do repositare nikde nenajdu ani zminku o X, Y a Z
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 02. 12. 2021, 18:25:35

Přesně takto se to používá:
1/ Generovaný kód, jehož znění nevyžaduje schválení člověkem = generuje se na CI serveru (nebo kdekoliv jinde) + necommituje se.
2/ Generovaný kód, který mi vygeneruje stroj, ale musí projít schválením člověkem = generuje se u vývojáře, a pak se commituje.

Má to tyto důsledky:
V prvním případě se jede na tvrdo optimalizace, stroj může cokoliv.
V druhém případě je očekáváno, že to co se vygeneruje musí být co nejvíce čitelné; nejlépe optimalizované pro diff. (A následně se to třeba celé ještě projede první variantou.)

TypoProvidery a podobně jsou jen první varianta. Jen už zakomponovaná do překladače. Jak už tu někdo zmínil. Ve skutečnosti je to ale spousta dalších případů: gcc, javac, scalac, ... etc, kde by tě ani nepadlo uvažovat, že je to jen prachsprostej generátor kódu. A ne, není to něco jiného :)

Mel bys nejakej netrivialni priklad 2?

Příklad 3: VisualStudio má návrháře UI. Můžeš si tam naklikat, natahat, naarangovat elementy. Ty se potom zapíšou do souboru. Buď do C#, nebo do XAML. V případě XAML se tento ještě zpracovává do výsledného něčeho. C# je part třída, kde máš jednu část, kterou má na starost návrhář, a druhou část, kterou používáš ty jako vývojář pro vlastní opičárny. Když hrábneš do té návrhářské třídy, tak pokud to nepřeženeš, tak se to zpětně promítne do toho návrháře. Osvědčilo se mi do té návrhářské třídy koukat. Lépe si všimnu, že jsem udělal nějakou nepravost. Nebo naopak, při přejmenování nějakého elementu, se přejmenuje i tady a návrhář to v pohodě zkousne.

Hmmm s tim sem nikdy nedelal.
Pamatuju si nejaky takovy udelatko pro Qt a jestli se nepletu tak tam se to do jednoho souboru nemotalo.
Tam byl snad v tom navrhari nejaky dialog pro event binding nebo co... to se mi zda lepsi.
Navic vystup z toho snad bylo nejaky xml a ne primo trida v cilovem jazyce.
Ale kdo vi... uz je to davno

Navic tady jsme trochu dal od generovani neceho ze schematu.
Tady "programator" "programuje". Sice tahanim nejakejch policek po formulari, ale to je jedno... to ze existuje kod a jeho visualni reprezentace je v poradku. Je to jedinny "zdroj pravdy" tak je v poradku ze to commitnu.
Já jsem se nebavil o generování ze schematu. Já jsem obhajoval "generovat kód vždy a všude" v opozici ke "generování kódu je zlo" :-)

Graf si sice muzu vygenerovat ale nikam ho nekomitnu, protoze to stejne pri buildu nikdo nepouzije.
Graf ne, ale informace o těch konkrétních závislostech ano. Chceš tři balíčky s nějakou cca verzí - dostaneš jich stovku s konkrétní verzí. Zkontroluješ, zda všechno funguje a tím, že to commitneš (tu stovku balíčků se specifickými závislostmy) tak uděláš schválení, že takto je to správně.

to fakt v mavenu ani v leiningenu nedelam... A nebo te porad spatne chapu.

Zavisim na balicku A:1.2.3 co zavisi na X, Y, Z.
Y zavisi na P ve verzi 3.14 a ten ma bug.
Moje zavislosti budou:
  • P:3.1415 kde uz vim ze je bug opraven a
  • A

Maven sam spravne dotahne i X, Y, a Z a P tam budu mit ve verzi 3.1415

ale kdyz se podivam do repositare nikde nenajdu ani zminku o X, Y a Z


OK, Maven to dělá jinak, v pořádku.

Možná jde o to, že u Composeru (a nejen u něj), balíček nezávisí na konkrétní verzi. Takže když by byla vydána nová verze nějakého balíčku, tak by se mohlo stát, že se tam stáhne ona. A to pochopitelně nechci.
Jak to dělá Maven netuším, ale předpokládám, že je tam nějaká chytristika, aby po konfiguraci bylo zaručeno, že se vždy vytvoří stejný graf.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: listoper 02. 12. 2021, 19:06:58

Já jsem se nebavil o generování ze schematu. Já jsem obhajoval "generovat kód vždy a všude" v opozici ke "generování kódu je zlo" :-)

Jasne. Tady sme myslim na hrane, ale uznam ti ze se jedna o generovani. A uznam, ze tenhle generovany kod je potreba commitnout.
Ale ta rucni editace k tomu se mi uz fakt nelibi...


OK, Maven to dělá jinak, v pořádku.

Možná jde o to, že u Composeru (a nejen u něj), balíček nezávisí na konkrétní verzi. Takže když by byla vydána nová verze nějakého balíčku, tak by se mohlo stát, že se tam stáhne ona. A to pochopitelně nechci.
Jak to dělá Maven netuším, ale předpokládám, že je tam nějaká chytristika, aby po konfiguraci bylo zaručeno, že se vždy vytvoří stejný graf.

Uz mozna rozumim...
U mavenu mam snapshot a release artefakty. Release uz se nemuze zmenit takze i jeho tranzitivni zavislosti budou stejne.
Snapshot se meni jak sam tak jeho zavislosti... tam by to davalo smysl.
A to je mozna duvod proc na to nenarazim.
Snapshotum se obloukem vyhybam...


V leiningenu myslim muzu pouzivat version ranges... ale je u toho nejaky warning, ze se to nema delat....
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: BoneFlute 02. 12. 2021, 19:11:01
Snapshotum se obloukem vyhybam...

V leiningenu myslim muzu pouzivat version ranges... ale je u toho nejaky warning, ze se to nema delat....
Uváděl jsem příklad na generování kódu. Zda je to dobrý nápad řešit verzování a závislosti knihoven takhle nebo jinak, to je už trochu jinej příběh. :-)
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 02. 12. 2021, 22:56:08
pokud chcete ORM, alternativni pristup je pouzit reflexi z metadat
To závisí na možnost jazyka. Pokud to jde jen initonly reflexí, tak proč ne? Třeba Go takto řeší spoustu věcí (kromě ORM třeba REST API). Kód není úplně hezký (hlavně ten pro runtime proper), ale je rychlý a bezpečný.
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Marekuss 11. 01. 2022, 22:08:44
Ahojte Kolegovia, ozivujem temu, nakolko pribudli skusenosti ohladom Rustu, tak davam na zretel lepsi navrh :)
za pozornost stoji "create_table" v "impl Database" (1)
pripadne "pub fn push<T: CreateTable + ToDatabase>(&mut self, data: &T) " v (2)

Samozrejme je mozne nahradit Vec -> HashSet - to je kazdeho volba :)
Kód: [Vybrat]
/* temp */
/* use MYSQL::Connection; */
pub struct Connection {}
impl Connection {
    pub fn execute(/* ... */){/* ... */}
}

pub enum DatabaseMembers {
    X,
    Y,
    Z
}

// Various Structs
pub struct X {
    pub name: String
}

pub struct Y {
    pub text: String
}

pub struct Z {
    pub value: u64
}

/* Traits */

pub trait CreateTable {
    fn create_table(c: &Connection) -> Result<(), Error>;
    fn table_type() -> DatabaseMembers;
}

pub trait FromDatabase : Sized {
    fn get(c: &Connection) -> Result<Self, Error>;
}

pub trait ToDatabase {
    fn push(c: &Connection, data: &Self) -> Result<(), Error>;
}

/* Trait implementation */

/* Impl for X */
impl CreateTable for X {
    fn table_type() -> DatabaseMembers{
        DatabaseMembers::X;
    }

    fn create_table(c: &Connection) -> Result<(), Error>{
        let query =
        "CREATE TABLE IF NOT EXISTS X (
            id      INTEGER PRIMARY KEY,
            text    TEXT NOT NULL,
        );";

        Ok(())
    }
}

impl ToDatabase for X {
    fn push(c: &Connection, data: &Self) -> Result<(), PError> {
        let query =
        "INSERT INTO ...
        (name, ...)
        VALUES
        (?1, ...)
        ";
    }
}

impl FromDatabase for X {
    fn get(c: &Connection, id: usize) -> Result<Self, Error>{
        let query =
        "SELECT *
        FROM ...
        WHERE ... id=?1
        ";
        /* ... */
        Ok(X{ /*... */})
    }
}
/* Impl for Y */
impl CreateTable for Y {
    fn table_type() -> DatabaseMembers{
        DatabaseMembers::Y;
    }

    fn create_table(c: &Connection) -> Result<(), Error>{
        let query =
        "CREATE TABLE IF NOT EXISTS Y (
            id      INTEGER PRIMARY KEY,
            text    TEXT NOT NULL,
        );";

        Ok(())
    }
}

impl ToDatabase for Y {
    fn push(c: &Connection, data: &Self) -> Result<(), PError> {
        let query =
        "INSERT INTO ...
        (name, ...)
        VALUES
        (?1, ...)
        ";
    }
}

impl FromDatabase for Y {
    fn get(c: &Connection, id: usize) -> Result<Self, Error>{
        let query =
        "SELECT *
        FROM ...
        WHERE ... id=?1
        ";
        /* ... */
        Ok(Y{ /*... */})
    }
}

/* Impl for Z */
/* ... */

pub struct Database {
    c: Connection,
    initialized_tables: Vec<DatabaseTables>,
}

impl Database {
    pub fn open_temporary() -> Database {
        let mut db = Database {
            c: Connection::open_in_memory(),
        }
        /* ... */
        Ok(db)
    }

    /* (1) - Explicitne vytvorim tabulku ...*/
    pub fn create_table<T: CreateTable>(&mut self) -> Result<(), PError> {
        if !self.initialized_tables.contains(&T::table_type()) {
            let dbtable = T::create_table(&self.conn)?;
            self.initialized_tables.push(dbtable);
        }   

        Ok(())
    }

    pub fn push<T: CreateTable + ToDatabase>(&mut self, data: &T) {
        /* (2) - alebo implicitne vytvorim tabulku */
        if !self.initialized_tables.contains(&T::table_type()) {
            T::create_table(&self.conn)?;
            self.initialized_tables.push(&T::table_type());
        }
        ToDatabase::push(&self.conn, data)
    }

    pub fn get<T: FromDatabase>(&self, id: usize) -> Result<T, PError>{
        FromDatabase::get(&self.conn, uid)
    }

}

fn main() {

    let mut db: Database = Database::open_temporary();

    /* (1) - explicitne vytvorim tabulku pre X */
    db.create_table::<X>();
    let x = X {name: String::from("Ahoj")};
    db.push(&x);

    // (2) - implicitne vytvorim tabulku pre Y */
    let y = Y {text: String::from("Ahoj")};
    db.push(&y);
}

Pekny vecer
Název: Re:Rust - std::ANY alebo lepší návrh?
Přispěvatel: Idris 15. 01. 2022, 10:50:10
Ahojte Kolegovia, ozivujem temu, nakolko pribudli skusenosti ohladom Rustu, tak davam na zretel lepsi navrh :)
za pozornost stoji "create_table" v "impl Database" (1)
pripadne "pub fn push<T: CreateTable + ToDatabase>(&mut self, data: &T) " v (2)

Samozrejme je mozne nahradit Vec -> HashSet - to je kazdeho volba :)
Kód: [Vybrat]
/* temp */
/* use MYSQL::Connection; */
pub struct Connection {}
impl Connection {
    pub fn execute(/* ... */){/* ... */}
}

pub enum DatabaseMembers {
    X,
    Y,
    Z
}

// Various Structs
pub struct X {
    pub name: String
}

pub struct Y {
    pub text: String
}

pub struct Z {
    pub value: u64
}

/* Traits */

pub trait CreateTable {
    fn create_table(c: &Connection) -> Result<(), Error>;
    fn table_type() -> DatabaseMembers;
}

pub trait FromDatabase : Sized {
    fn get(c: &Connection) -> Result<Self, Error>;
}

pub trait ToDatabase {
    fn push(c: &Connection, data: &Self) -> Result<(), Error>;
}

/* Trait implementation */

/* Impl for X */
impl CreateTable for X {
    fn table_type() -> DatabaseMembers{
        DatabaseMembers::X;
    }

    fn create_table(c: &Connection) -> Result<(), Error>{
        let query =
        "CREATE TABLE IF NOT EXISTS X (
            id      INTEGER PRIMARY KEY,
            text    TEXT NOT NULL,
        );";

        Ok(())
    }
}

impl ToDatabase for X {
    fn push(c: &Connection, data: &Self) -> Result<(), PError> {
        let query =
        "INSERT INTO ...
        (name, ...)
        VALUES
        (?1, ...)
        ";
    }
}

impl FromDatabase for X {
    fn get(c: &Connection, id: usize) -> Result<Self, Error>{
        let query =
        "SELECT *
        FROM ...
        WHERE ... id=?1
        ";
        /* ... */
        Ok(X{ /*... */})
    }
}
/* Impl for Y */
impl CreateTable for Y {
    fn table_type() -> DatabaseMembers{
        DatabaseMembers::Y;
    }

    fn create_table(c: &Connection) -> Result<(), Error>{
        let query =
        "CREATE TABLE IF NOT EXISTS Y (
            id      INTEGER PRIMARY KEY,
            text    TEXT NOT NULL,
        );";

        Ok(())
    }
}

impl ToDatabase for Y {
    fn push(c: &Connection, data: &Self) -> Result<(), PError> {
        let query =
        "INSERT INTO ...
        (name, ...)
        VALUES
        (?1, ...)
        ";
    }
}

impl FromDatabase for Y {
    fn get(c: &Connection, id: usize) -> Result<Self, Error>{
        let query =
        "SELECT *
        FROM ...
        WHERE ... id=?1
        ";
        /* ... */
        Ok(Y{ /*... */})
    }
}

/* Impl for Z */
/* ... */

pub struct Database {
    c: Connection,
    initialized_tables: Vec<DatabaseTables>,
}

impl Database {
    pub fn open_temporary() -> Database {
        let mut db = Database {
            c: Connection::open_in_memory(),
        }
        /* ... */
        Ok(db)
    }

    /* (1) - Explicitne vytvorim tabulku ...*/
    pub fn create_table<T: CreateTable>(&mut self) -> Result<(), PError> {
        if !self.initialized_tables.contains(&T::table_type()) {
            let dbtable = T::create_table(&self.conn)?;
            self.initialized_tables.push(dbtable);
        }   

        Ok(())
    }

    pub fn push<T: CreateTable + ToDatabase>(&mut self, data: &T) {
        /* (2) - alebo implicitne vytvorim tabulku */
        if !self.initialized_tables.contains(&T::table_type()) {
            T::create_table(&self.conn)?;
            self.initialized_tables.push(&T::table_type());
        }
        ToDatabase::push(&self.conn, data)
    }

    pub fn get<T: FromDatabase>(&self, id: usize) -> Result<T, PError>{
        FromDatabase::get(&self.conn, uid)
    }

}

fn main() {

    let mut db: Database = Database::open_temporary();

    /* (1) - explicitne vytvorim tabulku pre X */
    db.create_table::<X>();
    let x = X {name: String::from("Ahoj")};
    db.push(&x);

    // (2) - implicitne vytvorim tabulku pre Y */
    let y = Y {text: String::from("Ahoj")};
    db.push(&y);
}

Pekny vecer
U těch selectů by bylo hezké mít je typově bezpečné (native queries), Rust je jedním z mála jazyků, kde to jde přirozeně.