Python je fajn jazyk, ale na niektoré veci sa nehodí; trebárs na prácu s dátumami a časom či na konkurentné programovanie. Existuje tam veľa bugov a celé API je vo vývoji. Napr. populárny requests či Flask nepodporujú asynchrónne rutiny. Naozaj je jednoduchšie zvoliť si vhodnejší jazyk/platformu ako je F#, Go, Clojure, Groovy, Haskell či Erlang. (Fakt nechápem ľudí, ktorí idú oveľa náročnejšou cestou Python/GIL/C knižnice). Možno tak o 5-10 rokov to bude iné.
Asynchrónne rutiny ale už vyzerajú celkom k svetu.
Kombinácia asyncio a httpx:
#!/usr/bin/python import httpx import asyncio async def get_async(url): async with httpx.AsyncClient() as client: return await client.get(url) urls = ['http://webcode.me', 'https://httpbin.org/get', 'https://google.com', 'https://stackoverflow.com', 'https://github.com'] async def launch(): resps = await asyncio.gather(*map(get_async, urls)) data = [resp.status_code for resp in resps] for status_code in data: print(status_code) asyncio.run(launch())
Ďalej tu máme vynikajúcu knižnicu Playwright; to je v podstate async
headless browser. Môžeme klikať, robiť screenshoty, vyplňovať
formuláre a pod.
#!/usr/bin/python import asyncio from playwright.async_api import async_playwright async def run(playwright): chromium = playwright.chromium # or "firefox" or "webkit". browser = await chromium.launch() page = await browser.new_page() await page.goto("http://webcode.me") title = await page.title() print(title) await browser.close() async def main(): async with async_playwright() as playwright: await run(playwright) asyncio.run(main())
Souhlas, situace neni idealni. Existuje nekolik implementaci asynchronnich requests a asynchronni webove frameworky, ale treba django plne asynchronni zatim neni. Vetsinou masivni asynchronnost u backendu postavenem nad sql stejne nevyuzijete, bottlneck je databaze.
24. 3. 2022, 02:03 editováno autorem komentáře
Protože ve standardní knihovně je to opravdu strašné, je tam hrozně moc typů a je to strašně rozlezlé. To vůbec nemluvím o časových pásmech, ale to se v posledních verzí hodně zlepšilo. Trochu mi to připomíná, jak to bylo v Java před verzí 8. Škoda, že tohle v Pythonu nedotáhnou, protože používat pro práci s datem externí knihovnu mi přijde divný.
Ako už bolo povedané, je to tam nesystematicky pomiešané v rôznych balíčkoch, plus si konkurujú viaceré externé knižnice. Ale ani jedna ani zďaleka nepostihuje dostatočne prácu s dátumami a časom.
Ide totiž o mimoriadne náročnú problematiku. Žiadna datetime knižnica nie je úplná. (Ono to je prakticky práca bez konca.)
Koľko je rôznych kalendárov! Niektoré krajiny mali alebo majú viaceré kalendáre...
Asi najviac prepracované to má standard JVM & Time4J. https://github.com/MenoData/Time4J
Ostatné platformy sú riadne pozadu. The right tool for the right job.
24. 3. 2022, 17:42 editováno autorem komentáře
A ešte nemôžem obísť F#. Najnovšia verzia vydaná teraz na jeseň
umožňuje elegantnú integráciu s .NET taskami.
open System.Net.Http open System.Text.RegularExpressions open System.Threading.Tasks let fetchTitleAsync (url: string) = task { use client = new HttpClient() let! html = client.GetStringAsync(url) let pattern = "<title>\s*(.+?)\s*</title>" let m = Regex.Match(html, pattern) return m.Value } let sites = [| "http://webcode.me" "http://example.com" "https://bing.com" "http://httpbin.org" "https://ifconfig.me" "http://termbin.com" "https://github.com" |] let titles = sites |> Array.map fetchTitleAsync |> Task.WhenAll |> Async.AwaitTask |> Async.RunSynchronously titles |> Array.iter (fun title -> printfn $"%s{title}")
Async kód, computation expressions & custom DSL.
Príklad asynchrónne zadá do vyhľadávača heslo, klikne na selektovaný odkaz,
počká si na odpoveď a spraví screenshot. Plus si to všetko zabalíme do
elegantného DSLka.
Dokáže nejaký iný jazyk tomuto konkurovať?
#r "nuget: Microsoft.Playwright" open Microsoft.Playwright open System.Threading.Tasks type PlaywrightBuilder() = member _.Yield _ = task { let! pw = Playwright.CreateAsync() let! browser = pw.Firefox.LaunchAsync(BrowserTypeLaunchOptions(Headless = true)) return! browser.NewPageAsync() } [<CustomOperation "visit">] member _.Visit(page: Task<IPage>, url) = task { let! page = page let! _ = page.GotoAsync(url) return page } [<CustomOperation "screenshot">] member _.Screenshot(page: Task<IPage>, name) = task { let! page = page let! _ = page.ScreenshotAsync(PageScreenshotOptions(Path = $"{name}.png")) return page } [<CustomOperation "write">] member _.Write(page: Task<IPage>, selector, value) = task { let! page = page let! _ = page.FillAsync(selector, value) return page } [<CustomOperation "click">] member _.Click(page: Task<IPage>, selector) = task { let! page = page let! _ = page.ClickAsync(selector) return page } [<CustomOperation "wait">] member _.Wait(page: Task<IPage>, seconds) = task { let! page = page let! _ = page.WaitForTimeoutAsync(seconds) return page } [<CustomOperation "waitFor">] member _.WaitFor(page: Task<IPage>, selector) = task { let! page = page let! _ = page.WaitForSelectorAsync(selector) return page } let playwright = PlaywrightBuilder() playwright { visit "https://duckduckgo.com/" write "input" "root.cz" click "input[type='submit']" click "text=/Root\.cz/" waitFor "text=Root.cz - informace nejen ze světa Linuxu" screenshot "root" } |> Async.AwaitTask |> Async.RunSynchronously
красота
"Dokáže nejaký iný jazyk tomuto konkurovať?"
Jasně dokáže, třeba Scala, která má lepší typový systém a dokonce je pod kapotou i jednodušší než F#. Problém F# je že to jsou vlastně dva jazyky slepené do jednoho. .NET runtime je objektový a tohle stále do F# někde probublává. Ale jinak žádná, je to na míle lepší než Python :D
To je na mě? Sorry, nevidím tu dobře odsazení. Jestli jo, tak například Agda (je to popsané v knize Verified functional programming in Agda). V té knize je odkaz na Cayenne (tento jazyk neznám, ale údajně to tam jde taky). Já si to cvičně napsal v Idrisu, aniž bych znal tu implementaci z výše uvedené knihy, ono to jde napsat v tomto typu jazyků jen jedním způsobem. Je to hezké cvičení ze silných typových systémů. Možná (snad) se tady tomu bude někdy věnovat kolega Tišnovský :)
Díky. Tohle chování je díky závislostním typům? Pokud ano, tak by to měla Scala 3 také zvládnout myslím. Jen mně teď v tom konkrétním případě nenapadá k čemu bych to využil. V tom tvém případě vrací funkci, já ale interpolaci vždy používám tak, že tam narvu známé argumenty a vracím hodnotu. Nebo mi něco uniká.
Ano, používají se záv. typy. Příklad použití je třeba (format “Error at line %d: %s”) line msg
s tím, že již během typové kontroly se kontrolují typy obou proměnných v závislosti na formátovacím řetězci. To v závorce je ta funkce zavolaná s dvěma argumenty, dostanu tedy řetězec. Stejně jako v C, jen holt je to celé typové bezpečné. Já tohle beru jako cvičení, ale praktické použití to IMHO má, na rozdíl od některých jiných příkladů :)
Tady je ten článek o Cayenne s příkladem typově bezpečného formátování: http://citeseer.ist.psu.edu/viewdoc/download;jsessionid=B4FF3E0F00535ACBCDF4FED1ADE5499F?doi=10.1.1.47.155&rep=rep1&type=pdf
@all
Mal som na mysli reálne, nie na papieri. :)
Teoreticky môžu konkurovať JS/TS, Go, Python, C#. Žiadny iný jazyk nemá knižnicu pre headless browsing. JVM jazyky majú, ale nepodporuje asynchrónne programovanie.
Tipoval by som, že najbližšie k tomu má Clojure. Zatiaľ do Clojure len fušujem, ale viem, že DSLko dokáže spraviť, predpokladám, že aj ekvivalent computational expressions. Ale žiaľ nemá podporu pre async Playwright.
(Add OOP. Scala nevie vypísať hello world bez toho, aby sme funkciu museli vopchať do objektu.)
To není pravda. Scala 3 má na míle lepší typový systém než F# a hello world taky zvládne.https://docs.scala-lang.org/scala3/book/taste-hello-world.html Nějaký další problém?
https://www.scala-lang.org/blog/2016/02/03/essence-of-scala.html
27. 3. 2022, 09:58 editováno autorem komentáře
OK. Netušil som, že od Scala 3 je možné pomocou @main anotácie. + pre Scalu.
Lež tu sme ušli od pôvodnej rečníckej otázky. Tá sa týkala async workflows/kooperatívnych async rutín a DSL v jednoduchom, elegantnom programe. Nie typového systému.
(Ináč netuším prečo, ale tu na roote sa často diskusia zvŕtne na datové typy.)
DSL a async se ve Scale řeší taky pěkně. Ale nic proti F#. To proč nemá takový typový systém je by-design. Ale co v něm je implementováno, je řešeno velmi pěkně. Bohužel trpí díky MS a jeho pověsti.
https://www.reddit.com/r/fsharp/comments/pkz66r/don_syme_talks_about_downsides_of_type_classes/
30. 3. 2022, 17:06 editováno autorem komentáře