abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 03:33 | IT novinky

    Dle plánu certifikační autorita Let's Encrypt nově vydává také certifikáty s šestidenní platností (160 hodin) s možností vystavit je na IP adresu.

    Ladislav Hagara | Komentářů: 0
    včera 14:44 | Nová verze

    V programovacím jazyce Go naprogramovaná webová aplikace pro spolupráci na zdrojových kódech pomocí gitu Forgejo byla vydána ve verzi 14.0 (Mastodon). Forgejo je fork Gitei.

    Ladislav Hagara | Komentářů: 2
    včera 13:11 | Zajímavý projekt

    Just the Browser je projekt, 'který vám pomůže v internetovém prohlížeči deaktivovat funkce umělé inteligence, telemetrii, sponzorovaný obsah, integraci produktů a další nepříjemnosti' (repozitář na GitHubu). Využívá k tomu skrytá nastavení ve webových prohlížečích, určená původně pro firmy a organizace ('enterprise policies'). Pod linuxem je skriptem pro automatickou úpravu nastavení prozatím podporován pouze prohlížeč Firefox.

    NUKE GAZA! 🎆 | Komentářů: 2
    16.1. 16:44 | Nová verze

    Svobodný multiplatformní herní engine Bevy napsaný v Rustu byl vydán ve verzi 0.18. Díky 174 přispěvatelům.

    Ladislav Hagara | Komentářů: 2
    16.1. 15:11 | IT novinky

    Miliardy korun na digitalizaci služeb státu nestačily. Stát do ní v letech 2020 až 2024 vložil víc než 50 miliard korun, ale původní cíl se nepodařilo splnit. Od loňského února měly být služby státu plně digitalizované a občané měli mít právo komunikovat se státem digitálně. Do tohoto data se povedlo plně digitalizovat 18 procent agendových služeb státu. Dnes to uvedl Nejvyšší kontrolní úřad (NKÚ) v souhrnné zprávě o stavu digitalizace v Česku. Zpráva vychází z výsledků víc než 50 kontrol, které NKÚ v posledních pěti letech v tomto oboru uskutečnil.

    Ladislav Hagara | Komentářů: 15
    16.1. 13:55 | IT novinky

    Nadace Wikimedia, která je provozovatelem internetové encyklopedie Wikipedia, oznámila u příležitosti 25. výročí vzniku encyklopedie nové licenční dohody s firmami vyvíjejícími umělou inteligenci (AI). Mezi partnery encyklopedie tak nově patří Microsoft, Amazon a Meta Platforms, ale také start-up Perplexity a francouzská společnost Mistral AI. Wikimedia má podobnou dohodu od roku 2022 také se společností Google ze skupiny

    … více »
    Ladislav Hagara | Komentářů: 0
    16.1. 02:22 | Nová verze

    D7VK byl vydán ve verzi 1.2. Jedná se o fork DXVK implementující překlad volání Direct3D 5, 6 a 7 na Vulkan. DXVK zvládá Direct3D 8, 9, 10 a 11.

    Ladislav Hagara | Komentářů: 0
    16.1. 02:00 | Nová verze

    Byla vydána verze 12.0.0 knihovny libvirt (Wikipedie) zastřešující různé virtualizační technologie a vytvářející jednotné rozhraní pro správu virtuálních strojů. Současně byl ve verzi 12.0.0 vydán související modul pro Python libvirt-python. Přehled novinek v poznámkách k vydání.

    Ladislav Hagara | Komentářů: 0
    15.1. 19:22 | Humor

    CreepyLink.com je nový zkracovač URL adres, 'díky kterému budou vaše odkazy vypadat tak podezřele, jak je to jen možné'. Například odkaz na abclinuxu.cz tento zkracovač převádí do podoby 'https://netflix.web-safe.link/logger_8oIlgs_free_money.php'. Dle prohlášení autora je CreepyLink alternativou ke zkracovači ShadyURL (repozitář na githubu), který dnes již bohužel není v provozu.

    NUKE GAZA! 🎆 | Komentářů: 3
    15.1. 12:33 | IT novinky

    Na blogu Raspberry Pi byla představena rozšiřující deska Raspberry Pi AI HAT+ 2 s akcelerátorem Hailo-10 a 8 GB RAM. Na rozdíl od předchozí Raspberry Pi AI HAT+ podporuje generativní AI. Cena desky je 130 dolarů.

    Ladislav Hagara | Komentářů: 3
    Které desktopové prostředí na Linuxu používáte?
     (15%)
     (5%)
     (0%)
     (10%)
     (19%)
     (3%)
     (6%)
     (2%)
     (11%)
     (41%)
    Celkem 484 hlasů
     Komentářů: 12, poslední 14.1. 21:12
    Rozcestník

    Podpora pro rozměrovou analýzu v programovacích jazycích

    25.4.2021 21:15 | Přečteno: 2693× | programování | Výběrový blog | poslední úprava: 25.4.2021 21:15

    Kdysi dávno jsem na root.cz četl článek o programovacím jazyku Ada, kde autor mimo jiné ukazoval, jak lze silný typový systém jazyka použít k tomu, aby za nás překladač hlídal fyzikální rozměr hodnot v programu podobně, jako jsme na to zvyklí u běžných datových typů. Nedávno jsem si na to znovu vzpomněl, chvíli si s tím hrál a v tomto zápisku dal dohromady triviální demonstraci současných možností podpory jednotek v jazycích Ada, F# a Python.

    Ada

    Demonstrace z toho článku o jazyku Ada vypadala nějak takto:

    type Metry is new Float;
    type Ctverecni_Metry is new Float;
    
    -- Přetížení operátoru násobení pro datový typ metry tak, aby vracel metry
    -- čtvereční.
    function "*" (Left, Right : Metry) return Ctverecni_Metry is
    begin
      return Ctverecni_Metry(Float(Left)*Float(Right));
      -- před násobením jsme přetypovali na float, abychom zabránili rekurzi
      -- takto donutíme překladač použít standardní násobení pro typ Float
    end;
    
    declare
      vyska : Metry := 10.0;
      sirka : Metry := 15.0;
      plocha_a : Ctverecni_Metry;
      plocha_b : Metry;
    begin
      plocha_a := vyska*sirka; -- tohle je ok
      plocha_b := vyska*sirka; -- zde nastane chyba prekladu
    end;

    Pamatuji si, že to na mě tenkrát udělalo dojem. Ale tehdy jsem moc programovacích jazyků neznal a ani jsem to dál nezkoumal. Na druhou stranu jsem si z toho taky mylně na chvíli odnesl dojem, že podobné věci jsou záležitostí silně typovaných a málo používaných jazyků jako Ada. Což ale není úplně přesné, jak si ještě ukážeme.

    Když jsem se k tomu teď ze zvědavosti vrátil a chtěl si to vyzkoušet (v repozitáři Fedory nebo Debianu lze najít balíček s GNU Ada překladačem GNAT), ukázalo se, že je třeba ten kód trochu vylepšit, aby to ve skutečnosti opravdu fungovalo. Což v tomto případě znamená, aby to šlo přeložit s chybou, která demonstruje, jak to hlídání jednotek pěkně funguje (-:

    procedure Example1 is
      type Meters is new Float;
      type Meters_Squared is new Float;
      function "*" (Left, Right : Meters) return Meters_Squared is
      begin
        return Meters_Squared(Float(Left)*Float(Right));
      end;
      function "*" (Left, Right : Meters) return Meters is abstract;
      len_a : Meters := 10.0;
      len_b : Meters := 15.0;
      surface : Meters_Squared;
      len_sum : Meters;
    begin
      len_sum := len_a + len_b; -- ok
      surface := len_a * len_b; -- ok
      len_sum := len_a * len_b; -- invalid
    end Example1;
    

    Když opominu uhlazení dělající z toho příkladu samostatný Ada program, bylo třeba přidat deklaraci function "*" (Left, Right : Meters) return Meters is abstract, která tuto variantu násobení zděděnou z typu Float potlačí. A překlad pak opravdu chybu v rozměru zachytí, i když ta chybová hláška vypadá trochu zvláštně (zkoušeno s gcc-gnat-10.2.1-9 na Fedoře 33):

    $ gnatmake -q example1.adb
    example.adb:16:20: expected type "Meters" defined at line 2
    example.adb:16:20: found type "Meters" defined at line 2
    gnatmake: "example.adb" compilation error

    Obecné modelování fyzikálních rozměrů tímto způsobem nemusí být zcela přímočaré ani praktické. I když jednodušší případy, kdy se obejdeme bez rozměrové analýzy, můžou fungovat pěkně, jak je vidět na příkladu práce s metry a mílemi z úvodního kurzu jazyka Ada.

    Pro jazyk Ada v přehledu metod rozměrové analýzy se dozvíme, že tohle bylo jasné už někdy v 80. letech, kdy se tento problém začal řešit. Např. N. H. Gehani v článku z roku 1985 popisuje použití typového systému s přetížením operátorů (podobně jako to dělá naše ukázka výše) a dochází k tomu, že to obecně nefunguje:

    Derived types only partially solve the problem of detecting the inconsistent usage of objects; some valid usages of objects are also not allowed. Moreover, the solution is inelegant and inconvenient to use.

    To vedlo k návrhu různých knihoven zavádějících datové struktury obsahující hodnotu spolu s jednotkou a funkce pro práci s nimi. A něco takového je možné implementovat v libovolném jazyce, i když konkrétní přístup a garance, co knihovna programátorovi dává, se můžou v závislosti na možnostech jazyka dost lišit.

    Překladač GNAT dnes implementuje systém pro kontrolu rozměrů veličin, který staví na tzv. Aspects ze standadru Ada 2012, a je doplněn knihovnou System.Dim.Mks s definicí základních fyzikálních jednotek dle SI.

    S použitím tohoto rozšíření by náš příklad vypadal takto:

    with System.Dim.Mks; use System.Dim.Mks;
    procedure Example2 is
      len_a : Length := 10.0*m;
      len_b : Length := 15.0*m;
      surface : Area;
      len_sum : Length;
    begin
      len_sum := len_a + len_b; -- ok
      surface := len_a * len_b; -- ok
      len_sum := len_a * len_b; -- invalid
    end Example2;
    

    A jak se můžeme přesvědčit, opravdu to funguje:

    $ gnatmake -q -gnat2012 example2.adb
    example2.adb:10:11: dimensions mismatch in assignment
    example2.adb:10:11: left-hand side has dimension [L]
    example2.adb:10:11: right-hand side has dimension [L**2]
    gnatmake: "example2.adb" compilation error

    Taková podpora jednotek je pak někde mezi implementací přímo v jazyce, a pouhou knihovnou.

    F#

    Jeden z mála programovacích jazyků s přímou podporou pro práci s jednotkami, o kterém jste možná už někdy slyšeli, je funkcionální jazyk F#. Typový systém tohoto jazyka totiž umožňuje s jednotkami přímo pracovat, takže např. typ float<m> reprezentuje desetinné číslo pro počet metrů, zatímco float je desetinné číslo bez jednotky. Popis jak to funguje najdete na stránce Units of measure.

    Předchozí příklad přepsaný do jazyka F# by vypadal nějak takto:

    [<Measure>] type m
    
    let len_a = 10.0<m>
    let len_b = 15.0<m>
    let len_sum : float<m>   = len_a + len_b // ok
    let surface : float<m^2> = len_a * len_b // ok
    let len_c   : float<m>   = len_a * len_b // invalid
    

    A když se jej pokusíme přeložit, skončíme na očekávané chybě v jednotkách:

    $ dotnet run
    /home/martin/projects/hello-fsharp/Program.fs(7,36): error FS0001: The unit of measure 'm' does not match the unit of measure 'm ^ 2' [/home/martin/projects/hello-fsharp/hello-fsharp.fsproj]
    
    The build failed. Fix the build errors and run again.

    Python

    Knihoven pro práci s jednotkami pro jazyk Python existuje hned několik (viz přehled Python modulů pro rozměrovou analýzu). Pro ukázku jsem zvolil knihovnu Pint, čímž ale nechci tvrdit, že jde o nejlepší nebo nejpopulárnější modul tohoto typu (ostatní knihovny jsem nezkoušel).

    Náš předchozí příklad musíme při převodu do pythonu trochu upravit. I když python typový systém má, proměnné nelze typ explicitně přiřadit, a navíc knihovna Pint typový systém pro reprezentaci jednotek stejně nepoužívá. Takže místo pokusu o přiřazení metrů čtverečních do proměnné s počtem metrů, zkusíme metry čtvereční s metry prostě sečíst:

    import pint
    
    ureg = pint.UnitRegistry()
    
    len_a = 10 * ureg.m
    len_b = 15 * ureg.m
    len_sum = len_a + len_b # ok
    surface = len_a * len_b # ok
    len_c = surface + len_b # invalid
    

    A vidíme, že při spuštění programu dostáváme očekávanou chybu:

    $ python example.py
    Traceback (most recent call last):
      File "/home/martin/tmp/example.py", line 9, in <module>
        len_c = surface + len_b
      File "/usr/lib/python3.9/site-packages/pint/quantity.py", line 1018, in __add__
        return self._add_sub(other, operator.add)
      File "/usr/lib/python3.9/site-packages/pint/quantity.py", line 110, in wrapped
        return f(self, *args, **kwargs)
      File "/usr/lib/python3.9/site-packages/pint/quantity.py", line 930, in _add_sub
        raise DimensionalityError(
    pint.errors.DimensionalityError: Cannot convert from 'meter ** 2' ([length] ** 2) to 'meter' ([length])

    Další rozdíl oproti předchozím příkladům pochopitelně je, že jde o běhovou chybu. Ale pokud vám záleží na odhalení těchto chyb už v době překladu, asi nebudete používat python.

    Ale i v jazyce jako python se imho může hodit, že vám počítač s jednotkami pomáhá:

    >>> import pint
    >>> ureg = pint.UnitRegistry()
    >>> current = (300 * ureg.watt) / (6 * ureg.volt)
    >>> current
    <Quantity(50.0, 'watt / volt')>
    >>> current.dimensionality
    <UnitsContainer({'[current]': 1})>
    >>> current.to_base_units()
    <Quantity(50.0, 'ampere')>
    >>> (current * 30 * ureg.minute).to(ureg.ampere*ureg.hour)
    <Quantity(25.0, 'ampere * hour')>

    A klepne vás přes prsty, pokud po něm chcete nesmysl:

    >>> (current * 30 * ureg.minute).to(ureg.watt*ureg.hour)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/lib/python3.9/site-packages/pint/quantity.py", line 605, in to
        magnitude = self._convert_magnitude_not_inplace(other, *contexts, **ctx_kwargs)
      File "/usr/lib/python3.9/site-packages/pint/quantity.py", line 554, in _convert_magnitude_not_inplace
        return self._REGISTRY.convert(self._magnitude, self._units, other)
      File "/usr/lib/python3.9/site-packages/pint/registry.py", line 944, in convert
        return self._convert(value, src, dst, inplace)
      File "/usr/lib/python3.9/site-packages/pint/registry.py", line 1804, in _convert
        return super()._convert(value, src, dst, inplace)
      File "/usr/lib/python3.9/site-packages/pint/registry.py", line 1410, in _convert
        return super()._convert(value, src, dst, inplace)
      File "/usr/lib/python3.9/site-packages/pint/registry.py", line 977, in _convert
        raise DimensionalityError(src, dst, src_dim, dst_dim)
    pint.errors.DimensionalityError: Cannot convert from 'minute * watt / volt' ([current] * [time]) to 'hour * watt' ([length] ** 2 * [mass] / [time] ** 2)

    (-:

    Závěr

    Pokud vás tohle téma zaujalo, doporučuji se podívat na článek Dimensional Analysis in Programming Languages, kde najdete rozsáhlý přehled implementací rozměrové analýzy v mnoha programovacích jazycích.

    A pokud nějakou knihovnu pro práci s jednotkami ve svém kódu používáte, dejte vědět v komentářích.

           

    Hodnocení: 100 %

            špatnédobré        

    Anketa

    Práci s jednotkami v nějakém programovacím jazyku jsem:
     (50 %)
     (9 %)
     (36 %)
     (5 %)
    Celkem 22 hlasů

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    26.4.2021 07:36 _
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Většinou na počítání, jak jinak ;-) Ale v kterem jayzku je ta kalkulačka napsaná fakt nevím.
    26.4.2021 12:29 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Hodně zajímavé... díky.
    -- OldFrog
    26.4.2021 13:51 Tomáš
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Pro mě to je novinka, díky za ni. Momentálně to nepoužiju, ale je dobré vědět, že něco takového existuje.
    NUKE GAZA! 🎆 avatar 26.4.2021 21:58 NUKE GAZA! 🎆 | skóre: 37 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích

    se muže hodit :D ;D

    27.4.2021 07:03 kotrcka | skóre: 23 | blog: Onééé 2 | Praha
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Na čo? Adventný kód tým nevyriešiš a ani na mimibazar sa to nehodí :-D
    Keďže tu účet nejde zrušiť, zmenil som si heslo na random a "zabudol ho".
    27.4.2021 19:15 OldFrog {Ondra Nemecek} | skóre: 36 | blog: Žabákův notes | Praha
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Hodí se to všude kde se počítá. Typicky tam, kde má výpočet nějaký vztah k reálnému světu (počty, balení, rozměry, hmotnosti, fyzikální vlastnosti, koordináty...) nebo kde se kladou extra podmínky k tomu, aby měl výpočet smysl. Je překvapivé, jak opomíjené to je téma. Dobrý typový systém by měl být standard, realite je ovšem jiná.

    V praxi se to dohání nejčastěji implementací pomocí knihoven - příklady: Geografická knihovna mi nedovolí sčítat zeměpisnou délku se šířkou a poskytne jakž takž nějakou záruku, že má prováděný výpočet reálný geografický smysl.

    Další příklad: Matematické knihovny pro počítání s určitou kategorií čísel, například BigDecimal nebo BigInteger. Sice nepohlídá jednotky, ale alespoň garantuje určité vlastnosti kladené na danou kategorii čísel. To samé knihovny pro komplexní čísla.
    -- OldFrog
    27.4.2021 20:59 Tomáš
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Taky záleží na tom, jak se to projeví na výkonu. Třeba v Pythonu se nám vyplácelo některé úkony řešit poněkud humpolácky manuálně, než to nechat na Pythonu. Nějaké počítání s jednotkami by nám to úplně zabilo.

    Taky je otázka, jak chytrá by taková knihovna mohla být. Třeba v geografických knihovnách je to samý sinus a kosinus, kde se dá nasekat plno chyb. Počítám, že tak chytré to asi nebude, aby to ohlídalo, že dosadím správný úhel.
    27.4.2021 21:47 marbu | skóre: 31 | blog: hromada | Brno
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Ideálně se to na výkonu neprojeví, viz ten příklad v Adě nebo F#, kde se ta kontrola se provede v rámci kompilace. Pro výpočty v Pythonu se často používá numpy, a i když ta knihovna pint podporu pro numpy má, nějaký další overhead tam určitě bude.
    There is no point in being so cool in a cold world.
    30.4.2021 09:15 Jindřich Makovička | skóre: 17
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Jinak C++ má boost::units, kde se taky všechno řeší při kompilaci. A std::chrono už zvládá časové jednotky taky obstojně.
    HO▽ORK△ avatar 28.4.2021 10:34 HO▽ORK△ | skóre: 4 | blog: HOVORKUV_CTVERECKOVANY_SVET_DO_KAZDE_DOMACNOSTI
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    28.4.2021 16:24 marbu | skóre: 31 | blog: hromada | Brno
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    Neřekl bych, že tu existuje něco jako limit na počet tučňáků nebo zákon o zachování jejich počtu, ale můžu se mýlit :)
    There is no point in being so cool in a cold world.
    28.4.2021 11:20 luky
    Rozbalit Rozbalit vše Re: Podpora pro rozměrovou analýzu v programovacích jazycích
    V C toto jde hlidat nastrojem sparse.

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.