Problémy s JavaScript v praxi

Inkvizitor

Re:Problémy s JavaScript v praxi
« Odpověď #465 kdy: 09. 10. 2018, 20:58:47 »
A asi to ani nikdy nepochopíš, musel bys úplně změnit pohled na programování, zapomenout na své osvědčené postupy jak algoritmizuješ úlohy, které používáš automaticky a už o nich ani nepřemýšlíš.

V dynamickém jazyku nejsou proměnné důležité,  pracuješ v něm s hodnotami, nikoliv proměnnými. A možná to více oceníš, když si uvědomíš, že nejde jen o pojmenované proměnné, ale i ty anonymní, listy, slovníký, generátory, návratové hodnoty funkcí. To vše pracuje primárně s variabilními hodnotami. Je to něco jako nákupní taška, kam si dáš libovolné zboží jaké zrovna potřebuješ. Pro statického programátora hrůzná představa, ten za normální považuje, že má tašku na rohlíky, tašku na mlíka, tašku ha piva a přijde mu, že je velmi prasácké mít všechno v jedné tašce a nemá z toho dobrý pocit. Ale je to dáno jen tím, jak je vychovaný a jak je naučený myslet.

Sorry, ale tohle jsou hrozné kydy. Programuju v dynamickém jazyku snad déle než Ty, ale jakkoli je mi jasné, že v kontejneru můžu mít vedle sebe jabka s hruškama a pytli dalších jablek a hrušek a vedle toho ještě i rezavý hřebík a mrtvolu křečka, běžně se to nedělá a to z dobrého důvodu. Aby se v tom člověk vyznal a nedělalo mu to za zády něco, co neočekává. A zrovna tak identifikátor není kýbl na sr.čky, ale pomůcka k tomu, aby se člověk v kódu vyznal a proto by mělo obsah co nejlépe a nejjednoznačněji popsat a jelikož mám obsah identifikátorem popsaný, tak ctím, co říká a nedávám tam něco jiného.


Bacsa

Re:Problémy s JavaScript v praxi
« Odpověď #466 kdy: 09. 10. 2018, 21:02:55 »
typová inference vlastně nic podstatného neřeší
  ::)

eee

Re:Problémy s JavaScript v praxi
« Odpověď #467 kdy: 09. 10. 2018, 21:10:55 »
Jeden z mých oblíbených postupů na vytváření kolekcí hodnot s kratkou zivotnosti je tento:

import pickle
class MessageData: pass
...
md = MessageData()
md.type      = ... // number, string
md.sub_type  = ... // number, string
md.session   = session
md.data      = data // number, string, array, object, ...
message_data = pickle.dumps(md)
// dalsi polozky se pridavaji dle potreby
...

Vznikají tak velmi snadno a rychle funkcni prototypy aplikací v testovacim prostredi, ktere se ukazi koncovemu uzivateli a casto se hned na miste interaktivne doladi. Zkuste neco podobneho delat v C.

eee

Re:Problémy s JavaScript v praxi
« Odpověď #468 kdy: 09. 10. 2018, 21:20:38 »
Jak říkám, esoterika.
Lidská mysl si vyvinula řadu strategií, kterými se brání změně myšlení. Neočekávám v této diskusi, že by tu někdo k něčemu takovému dospěl :-).

Tak to chápeš špatně.

Za prvé, máš pravdu, lidská mysl se přirozeně brání změně. Na to jsou studie. Ale otázka je, zda ten problém mám já, neby ty.

Za druhé, jak jsem psal, tak mě živí programování v dynamických jazycích. A tudíž bych samozřejmě uvítal, možná i zaplatil, když by mi někdo ukázal, v čem dělám chybu v úvaze. Protože, co si budem nalhávat, proč bych měl programovat s utrpením, když bych mohl programovat s potěšením.
Ten problem maji obecne vsichni, takze i my oba. Ale co se tyce statickych/dynamickych jazyku, tak tam mas problem ty, ja mam rad a synergicky vyuzivam oboji. Ale mam treba problem s funkcionalnimi jazyky. Byt zabedneny, tak se proti nim vyhranuji a odsuzuji je, takhle si jen rikam, ze nejsou pro me, nejsem s nimi mentalne kompatibilni. Ty programujes s utrpenim? Ja jsem tim stale vice nadsenejsi. Jestli chces zmenu, zkus vic otevrit svou mysl, na misto odsuzovani.

Re:Problémy s JavaScript v praxi
« Odpověď #469 kdy: 09. 10. 2018, 21:30:43 »
Jako člověk, který se profesně živí dynamickými jazyky (Javascript, Python, PHP, Lua) bych měl zájem o vysvětlení, v čem jsou ty dynamické jazyky výhodnější. Víše uvedený popis je spíš takový esoterický kec, než vysvětlení.

Me prijde, ze v dynamickych jazycich je levnejsi polymorfismus.

OK. Můžeš to prosím rozvést?

Zkusim.
Mam funkci ktera umi pracovat s nejakym typem vstupu.
Chci ji rozsirit, aby umela zpracovat i nejaky dalsi typ vstupu.
U dynamicky typovaneho jazyka upravim telo funkce. (Idealne ani to ne, v clojure muzu pouzit multimethod a dispatch podle ceho se mi zamane na konkretni implementaci).
U staticky typovaneho musim upravit i signaturu, nebo vymyslet ze novy typ vstupu je subtyp nejakeho jiz podporovaneho.

Cim presneji specifikuju typ vstupu tim vic omezuju definicni obor a tim snizuju moznost polymorfismu.



andy

Re:Problémy s JavaScript v praxi
« Odpověď #470 kdy: 09. 10. 2018, 21:35:16 »
Ad dynamické vs. statické jazyky (s hodně dobrým typovým systémem typu Haskell)

Typování obecně zabrání některým validním programům běžet. Typický příklad:
Kód: [Vybrat]
if (true) then 1 else "no"Tohle prostě staticky typovaným jazykem neprojde, přestože to je validní program. Samozřejmě díky tomu je dynamický jazyk "flexibilnější"; a je to strašná prasárna. Takže asi není čím se chlubit...

eee, můžeš poskytnout nějaký kus kódu, který ti přijde jako ukázka toho, jak je dynamický jazyk flexibilnější? IMO zapomínáš, že v těch jazycích, o kterých se bavíme, je podpora pro algebraické datové typy (a kdyby to nestačilo, tak generalizované algebraické datové typy...), která IMO tu flexibilitu, kterou máš na mysli, naprosto uspokojivě řeší.

Citace
Mam funkci ktera umi pracovat s nejakym typem vstupu.
Chci ji rozsirit, aby umela zpracovat i nejaky dalsi typ vstupu.
U dynamicky typovaneho jazyka upravim telo funkce. (Idealne ani to ne, v clojure muzu pouzit multimethod a dispatch podle ceho se mi zamane na konkretni implementaci).
U staticky typovaneho musim upravit i signaturu, nebo vymyslet ze novy typ vstupu je subtyp nejakeho jiz podporovaneho.

Cim presneji specifikuju typ vstupu tim vic omezuju definicni obor a tim snizuju moznost polymorfismu.
Máš na mysli třeba toto?
Kód: [Vybrat]
encode :: ToJSON a => a -> ByteString
Aneb "vezmi hodnotu, která se umí zakódovat do JSONu a zakóduj ji"? A následně když to chci rozšířit třeba pro nějaký nový typ vstupu - "Jidlo", tak udělám:
Kód: [Vybrat]
data Jidlo = Mliko | Rohlik | Jablko
-- Genericka instance, zakoduje jako stringy:
instance ToJSON Jidlo
-- Nebo custom instance, zakoduje jak potrebuju
instance ToJSON Jidlo where
 toJSON Mliko = toJSON "mlicko"
 toJSON Rohlik = toJSON "rohlicek"
 toJSON Jablko = toJSON "jablicko"
Asi tak?

BoneFlute

  • *****
  • 2 046
    • Zobrazit profil
Re:Problémy s JavaScript v praxi
« Odpověď #471 kdy: 09. 10. 2018, 21:36:09 »
zkus vic otevrit svou mysl,

Není čemu.

eee

Re:Problémy s JavaScript v praxi
« Odpověď #472 kdy: 09. 10. 2018, 21:47:17 »
A asi to ani nikdy nepochopíš, musel bys úplně změnit pohled na programování, zapomenout na své osvědčené postupy jak algoritmizuješ úlohy, které používáš automaticky a už o nich ani nepřemýšlíš.

V dynamickém jazyku nejsou proměnné důležité,  pracuješ v něm s hodnotami, nikoliv proměnnými. A možná to více oceníš, když si uvědomíš, že nejde jen o pojmenované proměnné, ale i ty anonymní, listy, slovníký, generátory, návratové hodnoty funkcí. To vše pracuje primárně s variabilními hodnotami. Je to něco jako nákupní taška, kam si dáš libovolné zboží jaké zrovna potřebuješ. Pro statického programátora hrůzná představa, ten za normální považuje, že má tašku na rohlíky, tašku na mlíka, tašku ha piva a přijde mu, že je velmi prasácké mít všechno v jedné tašce a nemá z toho dobrý pocit. Ale je to dáno jen tím, jak je vychovaný a jak je naučený myslet.

Sorry, ale tohle jsou hrozné kydy. Programuju v dynamickém jazyku snad déle než Ty, ale jakkoli je mi jasné, že v kontejneru můžu mít vedle sebe jabka s hruškama a pytli dalších jablek a hrušek a vedle toho ještě i rezavý hřebík a mrtvolu křečka, běžně se to nedělá a to z dobrého důvodu. Aby se v tom člověk vyznal a nedělalo mu to za zády něco, co neočekává. A zrovna tak identifikátor není kýbl na sr.čky, ale pomůcka k tomu, aby se člověk v kódu vyznal a proto by mělo obsah co nejlépe a nejjednoznačněji popsat a jelikož mám obsah identifikátorem popsaný, tak ctím, co říká a nedávám tam něco jiného.
Nemas pravdu. Neni duvod, proc by ses v tom nemel vyznat. Typicky priklad je binding hodnot pro SQL, ktery predavam nebo ziskavam jako objekt, a je to prirozena kolekce nahodnych dat ruznych typu. Nebo se bezne zpracovavaji data z excelu, kdy zaznam (radek) je opet nahodnou smesi hodnot ruznych datovych typu (text, cislo, datum, mena, kde navic rozlisujes i vyznam textu a cisel a prirazujes jim vlastni datove typy). Vhodne zvoleny nazev identifikatoru je dulezity a je na tobe abys zvolil takovy, ktery bude mit odpovidajici abstrakci a nematl te. To se nijak nevylucuje s efektivnim vyuzivanim dynamickych datovych typu. Takze si mohu vytvorit datovy typ pro kontejner SQLData a v nem budu ocekavat libovolnou kolekci atributu jak co se tyce nazvu identifikatoru (odpovádaji nazvum sloupcu tabulky) tak jejich typovych hodnot. Obdobne mohu mit komplexni XLSRecord/XLSValue s metadaty kazde hodnoty nebo jednoduchy CSVRecord. V prirozenem svete bezne pracujes s kolekcemi hodnot ruznych typu a neni dvod, proc by ti to melo delat problem pri programovani, naopak to pomahá lepe vystihnout chaos realneho sveta.

andy

Re:Problémy s JavaScript v praxi
« Odpověď #473 kdy: 09. 10. 2018, 21:58:42 »
Nemas pravdu. Neni duvod, proc by ses v tom nemel vyznat. Typicky priklad je binding hodnot pro SQL, ktery predavam nebo ziskavam jako objekt, a je to prirozena kolekce nahodnych dat ruznych typu.
Tomu nerozumím. Jako třeba:
Kód: [Vybrat]
data Row = Row {
   ident :: Int
   , name :: Text
   , age :: int
   ..etc
}
V statických jazycích se tomu říká struct..? A pomáhá to zorganizovat chaos reálného světa a nezbláznit se v tom, co do té sql řádky dávám..?

eee

Re:Problémy s JavaScript v praxi
« Odpověď #474 kdy: 09. 10. 2018, 22:10:35 »

Typování obecně zabrání některým validním programům běžet. Typický příklad:
Kód: [Vybrat]
if (true) then 1 else "no"Tohle prostě staticky typovaným jazykem neprojde, přestože to je validní program. Samozřejmě díky tomu je dynamický jazyk "flexibilnější"; a je to strašná prasárna. Takže asi není čím se chlubit...

Není to prasárna, jen se na to podívej abstraktněji:

promenna = (podminka) ? datovy_typ1 : datovy_typ2

Na tom přece nic špatného není. Třeba když datovy_typ2 je None. Nebo ty datové typy jsou muz a zena, nebo html a pdf, a pak bys také mohl mít třeba toto:

levy = (typeof(pravy) == int) ? int(levy) : str(levy)

Já si bežně z funkcí které čtou data vracím hodnotu false, pokud funkce selže, None pokud data nejsou nebo datový objekt - tedy tři různé datové typy. Není to o nic horší, než návratový číselný kód z C funkce, která možná změní obsah proměnné předané funkci a pro získání chybového textu je nutné volat zvláštní funkci.

Re:Problémy s JavaScript v praxi
« Odpověď #475 kdy: 09. 10. 2018, 22:11:58 »
Máš na mysli třeba toto?
Kód: [Vybrat]
encode :: ToJSON a => a -> ByteString
Aneb "vezmi hodnotu, která se umí zakódovat do JSONu a zakóduj ji"? A následně když to chci rozšířit třeba pro nějaký nový typ vstupu - "Jidlo", tak udělám:
Kód: [Vybrat]
data Jidlo = Mliko | Rohlik | Jablko
-- Genericka instance, zakoduje jako stringy:
instance ToJSON Jidlo
-- Nebo custom instance, zakoduje jak potrebuju
instance ToJSON Jidlo where
 toJSON Mliko = toJSON "mlicko"
 toJSON Rohlik = toJSON "rohlicek"
 toJSON Jablko = toJSON "jablicko"
Asi tak?

To je vzhuru nohama. Ty menis typ, aby se dal poslat funkci. Ja jsem mluvil o pripadu kdy menim funkci aby umela zpracovat novy typ. Je to spis o pripadech kdy mam typ definovany externe a chci ho ve svem kodu umet pouzit.

Nedavno jsem resil nejake zpracovani exif dat u fotek. Kazdy vyrobce ma sve vlastni tagy. Narazil jsem na fotku ktera mela nejaka data v tagu, ktery jsem zatim neznal a tak jsem proste pridal defmethod s dispatch value :manufacturer "kodak" (nebo neco takoveho) a uz to frcelo.


andy

Re:Problémy s JavaScript v praxi
« Odpověď #476 kdy: 09. 10. 2018, 22:16:51 »
Není to prasárna, jen se na to podívej abstraktněji:

promenna = (podminka) ? datovy_typ1 : datovy_typ2

Na tom přece nic špatného není. Třeba když datovy_typ2 je None. Nebo ty datové typy jsou muz a zena, nebo html a pdf, a pak bys také mohl mít třeba toto:

levy = (typeof(pravy) == int) ? int(levy) : str(levy)

Já si bežně z funkcí které čtou data vracím hodnotu false, pokud funkce selže, None pokud data nejsou nebo datový objekt - tedy tři různé datové typy. Není to o nic horší, než návratový číselný kód z C funkce, která možná změní obsah proměnné předané funkci a pro získání chybového textu je nutné volat zvláštní funkci.
Víš proč se NullPointerException říká "million dolar mistake"..? Asi nevíš.... Ano, je to strašné. Je to úplně příšerné. Třeba z toho důvodu, že když vůbec chceš vědět, co se z té funkce vrací, tak se do ní musíš podívat. Ty type inference enginy (které tak děsně vychvaloval tvůj oblíbenec) ti na tom budou řvát, že to máš blbě. A teď je samozřejmě otázka, jak to dělat "dobře", když se bavíme o statických jazycích. Dělá se to pomocí algebraických datových typů - konkrétně součtového typu, který bohužel právě v C/C++/Java není. A vypadá to následovně:
Kód: [Vybrat]
data Result a = Data a | NoData | GotError text
mojefunkce :: Nejaky_vstupni_typ -> Result Navratovy typ
mojefunkce vstupni_data
  | jsou_chybna vstupni_data = GotError "Chybna vstupni data"
  | nedostaneme_vysledek vstupni_data = NoData
  | otherwise = Data (spocitej_vysledek vstupni_data)

Bacsa

Re:Problémy s JavaScript v praxi
« Odpověď #477 kdy: 09. 10. 2018, 22:21:59 »
Není to prasárna, jen se na to podívej abstraktněji:

promenna = (podminka) ? datovy_typ1 : datovy_typ2

Na tom přece nic špatného není. Třeba když datovy_typ2 je None. Nebo ty datové typy jsou muz a zena, nebo html a pdf, a pak bys také mohl mít třeba toto:

levy = (typeof(pravy) == int) ? int(levy) : str(levy)

Já si bežně z funkcí které čtou data vracím hodnotu false, pokud funkce selže, None pokud data nejsou nebo datový objekt - tedy tři různé datové typy. Není to o nic horší, než návratový číselný kód z C funkce, která možná změní obsah proměnné předané funkci a pro získání chybového textu je nutné volat zvláštní funkci.
Dělá se to pomocí algebraických datových typů - konkrétně součtového typu, který bohužel právě v C/C++/Java
V C++ je a je to super.

eee

Re:Problémy s JavaScript v praxi
« Odpověď #478 kdy: 09. 10. 2018, 22:22:55 »
Nemas pravdu. Neni duvod, proc by ses v tom nemel vyznat. Typicky priklad je binding hodnot pro SQL, ktery predavam nebo ziskavam jako objekt, a je to prirozena kolekce nahodnych dat ruznych typu.
Tomu nerozumím. Jako třeba:
Kód: [Vybrat]
data Row = Row {
   ident :: Int
   , name :: Text
   , age :: int
   ..etc
}
V statických jazycích se tomu říká struct..? A pomáhá to zorganizovat chaos reálného světa a nezbláznit se v tom, co do té sql řádky dávám..?
Ano, ve statických jazycích je to struct. Jeho nevýhoda je, že je statický, takže pro každý dotaz ho musíš mít nadefinovaný předem, mohou jich být stovky a neumožňuje ti zpracívat uživatelské dotazy vytvářené za běhu programu. Třeba u monitorovacího systému výkonových transformátorů, který měří několik set parametrů a uživatel chce zobrazit historii šesti z nich, které si zaklikl, třeba teplotu oleje z čidel pod víkem, nebo některé údaje z analyzátoru plynů. Ne že by to nešlo ve statickém jazyku řešit, ale je to holt komplikovanější a je s tím nutno řešit problémy, které v dynamickém jazyku nejsou.

andy

Re:Problémy s JavaScript v praxi
« Odpověď #479 kdy: 09. 10. 2018, 22:23:15 »
To je vzhuru nohama. Ty menis typ, aby se dal poslat funkci. Ja jsem mluvil o pripadu kdy menim funkci aby umela zpracovat novy typ. Je to spis o pripadech kdy mam typ definovany externe a chci ho ve svem kodu umet pouzit.

Nedavno jsem resil nejake zpracovani exif dat u fotek. Kazdy vyrobce ma sve vlastni tagy. Narazil jsem na fotku ktera mela nejaka data v tagu, ktery jsem zatim neznal a tak jsem proste pridal defmethod s dispatch value :manufacturer "kodak" (nebo neco takoveho) a uz to frcelo.
Teď úplně nerozumím...  to Jidlo může být definované externě, tu instanci (včetně případně i té class) si můžu definovat interně. Takže když mám tu funkci:
Kód: [Vybrat]
encode :: ToJson a => a -> ByteStringA Jidlo je definované externě, tak pro mě není problém si vyrobit tu instanci u sebe.

Konkrétně u toho exifu tomu úplně nerozumím, z knihovny pro přečtení Exifu by patrně vypadával nějaký typ ve stylu:
Kód: [Vybrat]
data ExifTag = TagString Text | TagInt Int | ... a ty bys zpracovával typ ExifTag. Překladač by po tobě chtěl, abys zpracoval všechny varianty (nebo tam dal nějaký "wildcard"), takže přidání další varianty by bylo jenom přidání další varianty místo toho wildcardu.