Je Rust jazyk budoucnosti?

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #270 kdy: 05. 12. 2022, 17:10:47 »
Aby tohle fungovalo, musí být ta hodnota boxovaná (na-alokovaná na heapu a schovaná za, efektivně, pointer) a operace na ní se provádí přes dynamic dispatch (bude tam nějaký ekvivalent v-table), jinak by nebylo možné provést type erasure.
Teda, já jsem to vždycky chápal tak, že type erasure je způsob, jak typy odrbat. Kde by tam jako měla být schovaná vtable? A proč? Ve skutečnosti tam tu vtable potřebuješ v případě, kdy nechceš dělat type erasure...

Já té formulaci asi nerozumím.
Tak tak. Ta formulace je blábol, nedává to vůbec smysl.


Re:Je Rust jazyk budoucnosti?
« Odpověď #271 kdy: 05. 12. 2022, 17:18:24 »
Aby tohle fungovalo, musí být ta hodnota boxovaná (na-alokovaná na heapu a schovaná za, efektivně, pointer) a operace na ní se provádí přes dynamic dispatch (bude tam nějaký ekvivalent v-table), jinak by nebylo možné provést type erasure.
Teda, já jsem to vždycky chápal tak, že type erasure je způsob, jak typy odrbat. Kde by tam jako měla být schovaná vtable? A proč? Ve skutečnosti tam tu vtable potřebuješ v případě, kdy nechceš dělat type erasure...

Já té formulaci asi nerozumím.
Tak tak. Ta formulace je blábol, nedává to vůbec smysl.
A byl by nějaký argument? Na co by mi proboha prosím byl vtable, pokud nedělám type erasure? Přesně z toho důvodu, že jazyky jako C++ nebo Rust nedělají type erasure generik (místo toho monomofrigzují) nepotřebují vtables, narozdíl třeba od Javy.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #272 kdy: 05. 12. 2022, 17:20:47 »
Jinak podíval jsem se na C výstup Idris kompilátoru a je to prostě VM (verze idris je u mě 1.3.4). Toto je funkce alokující hodnotu, okopírováno z Idris runtime:

Kód: [Vybrat]
static inline Con * allocConF(VM * vm, uint32_t tag, uint16_t arity, int outer) { ... }
Hádejte, co je `tag` :D
Není to to, co si myslíš. A Idris 1 dávno není podporován, smysl dává jen použití jen Idrisu 2 (relevantní backend je "refc").

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #273 kdy: 05. 12. 2022, 17:26:08 »
Na co by mi proboha prosím byl vtable, pokud nedělám type erasure? Přesně z toho důvodu, že jazyky jako C++ nebo Rust nedělají type erasure generik (místo toho monomofrigzují) nepotřebují vtables, narozdíl třeba od Javy.
Jazyky jako Idris a Lean (a pár dalších) dělají type erasure a vtables v generovaném kódu taky nepoužívají.

Re:Je Rust jazyk budoucnosti?
« Odpověď #274 kdy: 05. 12. 2022, 17:30:55 »
Na co by mi proboha prosím byl vtable, pokud nedělám type erasure? Přesně z toho důvodu, že jazyky jako C++ nebo Rust nedělají type erasure generik (místo toho monomofrigzují) nepotřebují vtables, narozdíl třeba od Javy.
Jazyky jako Idris a Lean (a pár dalších) dělají type erasure a vtables v generovaném kódu taky nepoužívají.

No ano, protože ty hodnoty tagují, jak jsem viděl (v kódu všude velké switche na tagy).

Idris2 se mi instaluje, jak si z něj vygeneruju C kód pomocí 'refc' backendu?


Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #275 kdy: 05. 12. 2022, 17:31:22 »
Typ chovající se jako funkce. Tomu rozumím. Jak se to liší a v čem je to podobné proti průmyslovým generikám:
Kód: [Vybrat]
type IsEven<T> where T is Nat
?
P.S. Tady bych ještě dodal, že Nat je induktivní typ, což třeba C++ vůbec nemá, takže rozdíl pod pokličkou je. Ale pro programátora se to tváří jako stejná věc.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Je Rust jazyk budoucnosti?
« Odpověď #276 kdy: 05. 12. 2022, 17:34:15 »
Není podstatné, že Lua je dynamický jazyk. Chtěl jsem tím uvést, že když jsem se kouknul do toho zdrojáku, tak tam žádné typové informace, které tvrdíš, že tam musí zůstat aby něco, nebyly.
Jak jsi poznal, že tam nebyly typové informace? V jazyce jako Lua má každá hodnota runtime typovou informaci, tak fungují dynamicky typované jazyky, tzn. ty typy tam nemohly nebýt :)
Na vstupu bylo x = Red. V lue bylo x = 1. To považuji, že tam ten Red není.


Aby tohle fungovalo, musí být ta hodnota boxovaná (na-alokovaná na heapu a schovaná za, efektivně, pointer) a operace na ní se provádí přes dynamic dispatch (bude tam nějaký ekvivalent v-table), jinak by nebylo možné provést type erasure.
Teda, já jsem to vždycky chápal tak, že type erasure je způsob, jak typy odrbat. Kde by tam jako měla být schovaná vtable? A proč? Ve skutečnosti tam tu vtable potřebuješ v případě, kdy nechceš dělat type erasure...

Dobře, tak mějme ten příklad s maticí. Dejme tomu, že od nějaké velikosti Thr (jako threshold) používá implementace matice nějakou vymakanou reprezentaci v paměti kvůli ušetření místa pro velké matice. Ok? Teď dejme tomu, že máme operaci `col` na matici, která vrátí daný sloupec jako vektor. Tahle operace bude muset fungovat různě v závislosti na Thr, z úsporné reprezentace se čte sloupec jinak než z jednoduché.

Tak, a teď, ty napíšeš program, který načte matici ze souboru a bude chtít číst sloupce. Pokud by ta typová informace - v tomto případě velikost matice - byla komplet odstraněna, metoda `col` by neměla jak poznat, jak je konkrétní matice v paměti reprezentována, a tedy jak extrahovat sloupec. Proto bude muset ta matice si s sebou tu informaci vzít a držet si ji během runtime, buďto to může být nějaký tag, podle kterého udělá ta metoda `col` vidličku, anebo si s sebout vezme vtable, která bude u různých konkrétních hodnoty ukazovat na různé implementace `col`. Řešení s vtable je obecnější - těch typových parametrů může být více, chování se může v závislosti na nich více lišit.

V jazyce jako Rust nebo C++ tohle není potřeba, protože kompilátor zná dopředu všechny instanciace a provede monomofrizaci, ie. v podstatě z toho udělá různé typy s různými metodami, ale cena za to je, že není možné vytvořit tu hodnotu at runtime.
Načtu matici ze souboru.
Zjistím velikost matice, podle toho vyberu buď reprezentaci (nikoliv typ) A, nebo reprezentaci B.
Pokud je to A pošlu to "uličkou" A. Pokud je to B pošlu to uličkou B.

V tomto případě tam nikde není třeba uchovávat informaci o typu, ani v tagu, ani nikde.

Ale budiž, blbej případ.

Problém není v tom, že by informace nemohla být v runtimu, že by tam nemohl být nějaký tag, nebo co já vím. Ty tvrdíž, že tam být musí, zatímco v Rustu být nemusí. Ale vůbec mi nedochází, kde to musení vidíš.

Představ si lepší překlad:

Kód: [Vybrat]
type Matice a = GenericMatice a | OptimalizedMatice a
let xs : [Matice] = parseFromFile(f)

out = map format xs
where
   format x = case (type x):
      GenericMatice m -> formatGenericMatice m
      OptimalizedMatice m -> formatOptimalizedMatice m

Toto je první příklad, kde by mě napadlo, že by se hodilo type erasured nemít. A určitě se shodnem, že to některé jazyky takto můžou, přidat tam ty tagy, použít. Jiné jazyky něco takové zakážou. A některé jazyky (nebo ty samé, ale prostě si usmysleli) to zoptimalizují tak, že tam budou dvě "uličky" (v tomto případě si to nedokážu úplně představit, ale to není argument - stejně tak nedokážu najít "důkaz", proč by to nemělo jít). Pak tam v rámci optimalizace nebude vůbec žádná informace o typu.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #277 kdy: 05. 12. 2022, 17:35:15 »
Jazyky jako Idris a Lean (a pár dalších) dělají type erasure a vtables v generovaném kódu taky nepoužívají.
No ano, protože ty hodnoty tagují, jak jsem viděl (v kódu všude velké switche na tagy).

Idris2 se mi instaluje, jak si z něj vygeneruju C kód pomocí 'refc' backendu?
Tagují se součtové typy, to s typovými parametry vůbec nesouvisí.

Dal bych --codegen refc.

Re:Je Rust jazyk budoucnosti?
« Odpověď #278 kdy: 05. 12. 2022, 17:37:21 »
Načtu matici ze souboru.
Zjistím velikost matice, podle toho vyberu buď reprezentaci (nikoliv typ) A, nebo reprezentaci B.
Pokud je to A pošlu to "uličkou" A. Pokud je to B pošlu to uličkou B.
Konkretizuj to prosím. Představ si, že seš metoda `col`. Na základě čeho uděláš to rozhodnutí, kterou uličkou poslat maticová data?

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Je Rust jazyk budoucnosti?
« Odpověď #279 kdy: 05. 12. 2022, 17:41:08 »
Aby tohle fungovalo, musí být ta hodnota boxovaná (na-alokovaná na heapu a schovaná za, efektivně, pointer) a operace na ní se provádí přes dynamic dispatch (bude tam nějaký ekvivalent v-table), jinak by nebylo možné provést type erasure.
Teda, já jsem to vždycky chápal tak, že type erasure je způsob, jak typy odrbat. Kde by tam jako měla být schovaná vtable? A proč? Ve skutečnosti tam tu vtable potřebuješ v případě, kdy nechceš dělat type erasure...

Já té formulaci asi nerozumím.
Tak tak. Ta formulace je blábol, nedává to vůbec smysl.
A byl by nějaký argument? Na co by mi proboha prosím byl vtable, pokud nedělám type erasure? Přesně z toho důvodu, že jazyky jako C++ nebo Rust nedělají type erasure generik (místo toho monomofrigzují) nepotřebují vtables, narozdíl třeba od Javy.
To ale není argument.
Na co by mi v run-time byly typy, když je nepoužívám - proč mít vtable, když jsem typy odrbal = type erasure.
Pokud typy (v run-time) používám, tak neprovedu type erasure, a pak tam ty typy někde musím mít. Třeba jako vtable 1), abych se mohl dotázat, jaký typ má tato hodnota když tu informaci o typu potřebuji.
Situaci, kdy může být uchování typu hodnoty až do runtime zajímavé jsem uváděl v předchozím příspěvku.

Mě přijde, že to chápeš přesně opačně než jak to je :-)


1) Samozřejmě název vtable je zavádějící, protože to se používá v jiném kontextu u C++, ale ty sis začal.

Re:Je Rust jazyk budoucnosti?
« Odpověď #280 kdy: 05. 12. 2022, 17:42:15 »
Tagují se součtové typy, to s typovými parametry vůbec nesouvisí.
Ano, přesně tak, v případě nepoužití vtable je ten typ efektivně konvertován na součtový, tj. v tom příkladu s maticí s prahem velikosti pro jinou reprezentaci to efektivně bude součtový typ obsahující dvě varianty - malá a velká matice.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #281 kdy: 05. 12. 2022, 17:43:18 »
Není podstatné, že Lua je dynamický jazyk. Chtěl jsem tím uvést, že když jsem se kouknul do toho zdrojáku, tak tam žádné typové informace, které tvrdíš, že tam musí zůstat aby něco, nebyly.
Jak jsi poznal, že tam nebyly typové informace? V jazyce jako Lua má každá hodnota runtime typovou informaci, tak fungují dynamicky typované jazyky, tzn. ty typy tam nemohly nebýt :)
Na vstupu bylo x = Red. V lue bylo x = 1. To považuji, že tam ten Red není.


Aby tohle fungovalo, musí být ta hodnota boxovaná (na-alokovaná na heapu a schovaná za, efektivně, pointer) a operace na ní se provádí přes dynamic dispatch (bude tam nějaký ekvivalent v-table), jinak by nebylo možné provést type erasure.
Teda, já jsem to vždycky chápal tak, že type erasure je způsob, jak typy odrbat. Kde by tam jako měla být schovaná vtable? A proč? Ve skutečnosti tam tu vtable potřebuješ v případě, kdy nechceš dělat type erasure...

Dobře, tak mějme ten příklad s maticí. Dejme tomu, že od nějaké velikosti Thr (jako threshold) používá implementace matice nějakou vymakanou reprezentaci v paměti kvůli ušetření místa pro velké matice. Ok? Teď dejme tomu, že máme operaci `col` na matici, která vrátí daný sloupec jako vektor. Tahle operace bude muset fungovat různě v závislosti na Thr, z úsporné reprezentace se čte sloupec jinak než z jednoduché.

Tak, a teď, ty napíšeš program, který načte matici ze souboru a bude chtít číst sloupce. Pokud by ta typová informace - v tomto případě velikost matice - byla komplet odstraněna, metoda `col` by neměla jak poznat, jak je konkrétní matice v paměti reprezentována, a tedy jak extrahovat sloupec. Proto bude muset ta matice si s sebou tu informaci vzít a držet si ji během runtime, buďto to může být nějaký tag, podle kterého udělá ta metoda `col` vidličku, anebo si s sebout vezme vtable, která bude u různých konkrétních hodnoty ukazovat na různé implementace `col`. Řešení s vtable je obecnější - těch typových parametrů může být více, chování se může v závislosti na nich více lišit.

V jazyce jako Rust nebo C++ tohle není potřeba, protože kompilátor zná dopředu všechny instanciace a provede monomofrizaci, ie. v podstatě z toho udělá různé typy s různými metodami, ale cena za to je, že není možné vytvořit tu hodnotu at runtime.
Načtu matici ze souboru.
Zjistím velikost matice, podle toho vyberu buď reprezentaci (nikoliv typ) A, nebo reprezentaci B.
Pokud je to A pošlu to "uličkou" A. Pokud je to B pošlu to uličkou B.

V tomto případě tam nikde není třeba uchovávat informaci o typu, ani v tagu, ani nikde.

Ale budiž, blbej případ.

Problém není v tom, že by informace nemohla být v runtimu, že by tam nemohl být nějaký tag, nebo co já vím. Ty tvrdíž, že tam být musí, zatímco v Rustu být nemusí. Ale vůbec mi nedochází, kde to musení vidíš.

Představ si lepší překlad:

Kód: [Vybrat]
type Matice a = GenericMatice a | OptimalizedMatice a
let xs : [Matice] = parseFromFile(f)

out = map format xs
where
   format x = case (type x):
      GenericMatice m -> formatGenericMatice m
      OptimalizedMatice m -> formatOptimalizedMatice m

Toto je první příklad, kde by mě napadlo, že by se hodilo type erasured nemít. A určitě se shodnem, že to některé jazyky takto můžou, přidat tam ty tagy, použít. Jiné jazyky něco takové zakážou. A některé jazyky (nebo ty samé, ale prostě si usmysleli) to zoptimalizují tak, že tam budou dvě "uličky" (v tomto případě si to nedokážu úplně představit, ale to není argument - stejně tak nedokážu najít "důkaz", proč by to nemělo jít). Pak tam v rámci optimalizace nebude vůbec žádná informace o typu.
Informace o typu tam nebude nikdy. Idris a spol. mají kvantitativní typový systém a tzv. implicitní argumenty. To jsme ale hodně odbočili. Jinak pro ten příklad s maticí by se asi použil typ LTE, není nutné psát součtový typ, to je boilerplate. Ale jak říkám, to jsme odbočili k úplně jinému tématu.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #282 kdy: 05. 12. 2022, 17:44:45 »
Načtu matici ze souboru.
Zjistím velikost matice, podle toho vyberu buď reprezentaci (nikoliv typ) A, nebo reprezentaci B.
Pokud je to A pošlu to "uličkou" A. Pokud je to B pošlu to uličkou B.
Konkretizuj to prosím. Představ si, že seš metoda `col`. Na základě čeho uděláš to rozhodnutí, kterou uličkou poslat maticová data?
Nechcete si to psát přímo v kódu? Třeba tady: https://learn-idris.net/play

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Je Rust jazyk budoucnosti?
« Odpověď #283 kdy: 05. 12. 2022, 17:46:48 »
Načtu matici ze souboru.
Zjistím velikost matice, podle toho vyberu buď reprezentaci (nikoliv typ) A, nebo reprezentaci B.
Pokud je to A pošlu to "uličkou" A. Pokud je to B pošlu to uličkou B.
Konkretizuj to prosím. Představ si, že seš metoda `col`. Na základě čeho uděláš to rozhodnutí, kterou uličkou poslat maticová data?
Nejseš žádná metoda. Nic takové není.

Ve funkci načítání matice ze souboru je podmínka, která zjistí velikost dat. Pokud je to větší jak požadovaná podmínka (IF, SWITCH), tak provede větev, kde funkci col_optimalized předá získané data (surový pole bytů), pokud je menší, předá data funkci col_unoptimalized. Nikde žádné typy, nikde žádné tagy, nikde žádné vtable.

Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Je Rust jazyk budoucnosti?
« Odpověď #284 kdy: 05. 12. 2022, 17:47:00 »
Tagují se součtové typy, to s typovými parametry vůbec nesouvisí.
Ano, přesně tak, v případě nepoužití vtable je ten typ efektivně konvertován na součtový, tj. v tom příkladu s maticí s prahem velikosti pro jinou reprezentaci to efektivně bude součtový typ obsahující dvě varianty - malá a velká matice.
Ne, nebude (pokud se pořád bavíme o Idrisu/Leanu).