REDGUY: podívej, to, že programátor ví, co dělá, a které objekty jsou na sobě nezávislé a které ne, to by minimálně _měla_ být pravda, i když samozřejmě předpokládá to, že programátor rozumí prostředí, ve kterém pracuje.
i kdybych nevyhlásil jiný cíl, než že chci jazyk s blbuvzdornou a inutitivní syntaxi pro vícevláknový během, který bude schopen generovat ze zdrojáku mezikód pro platformy, které to jednoduše neumožňují, i pro ty, které to umožňují, tak je to dostatečné zdůvodnění, proč ten projekt rozjíždět (víš, že jsem o tom mluvil už dřív...)
co se nových platforem go a rust týče, tak start nového vlákna (nebo taky ne - přesné chování není definováno, může a nemusí se to spustit v novém vlákně...) pomocí klíčového slova "go" je tam příjemně intuitivní a dost možná to do svého projektu převezmu (jako název mám regnutou jednu doménu, už léta...ale zatím tomu říkejme třeba "xCh Basic", po vzoru ZX Basic :-) i když to s Basicem historickým ani microsoftím teda nebude mít společného celkem nic)
Problém je, že já bych chtěl doplnit nějakou logiku, která sama rozhodne, jestli se nová vlákna mají startovat, nebo jestli zůstáváme v hlavním vlákně (to se dá doplnit čítačem počtu volání toho "go", a v případě smyčky se známým počtem iterací, což je tak nějak pointa, by runtime znal režii, kterou má start vlákna a taky by znal - minimálně po prvním průchodu cyklu - dobu, kterou trval poslední podobný segment - takže by runtime sám vyhodnotil, jak moc má smysl to paralelizovat - což zase řekněme, že ví programátor líp, nebo to může záviset na vstupních datech...)
aby bylo jasné, jak to myslím:
Klasické sekvenční procházení (jo - dvojtečka pravděpodobně bude volitelná nebo možná nebude dovolená vůbec - nebude to Python, byl by to jen syntaktický cukr, protože jednořádkové if a for jsou ošklivé :-))
for prvek in seznam
zpracuj prvek
print prvek, "zpracovan"
A tohle by bylo procházení v předem nedefinovaném počtu threadů, podle toho, jaké parametry nastavíme runtimu (nebo jak runtime sám vyhodnotí momentální možnosti systému)
for prvek in seznam
go
zpracuj prvek
print prvek, "zpracovan"
print "jedeme dal..."
Takhle by se mohlo zapisovat čekání na ukončení vlákna (moje inspirace, možná by se vyplatilo se podívat, jak to píšou v tom Go :-) zatím je to inspirované spíš Python konstrukcí try ~ except
for prvek in seznam
go
zpracuj prvek
print "vlakno zpracovalo", prvek
wait
print "hlavni proces ma k dispozici zpracovany", prvek
print "jedeme dal..."
(volání fukcí bez úvozovek je převzaté z Basicu - opět, o syntaxi teprve začínám přemýšlet a nechci nikoho mást tím, že to bude vypadat hned od začátku jako Python, který to není :-) současně bude go bude řešit takové věci, aby se dal použít intuitivní zápis a hodnotu proměnné "prvek" v daném scope mi nepřepsalo jiné vlákno, což bude docela úlet, ale podle mě nejjednodušší bude, aby si o přístup k neduplikované verzi proměnné z nadřazeného scope bylo nutné v "go" scope explicitně zažádat (globální proměnné uvnitř volaných funkcí budou ovšem už zase globální - to je pro změnu inspirace v C)
Prostě si stanovím, že tam, kde odbočuju do vlákna pomocí "go", bych dal prostě counter dosud neukončených vláken (počítadlo běžících threadů by mělo být celkem nekontroverzně implementovatelné), no a v kombinaci s nějakým monitoringem, kolik třeba thready alokují paměti, by se každý další průchod křižovatkou rozhodoval, jestli startovat thread, nebo ne (důvodem by mohlo být jak moc threadů, tak moc paměti alokované neukončenými thready).
jakýkoliv paralelizovatelný kód přitom z principu musí být možné provozovat sekvenčně na "hloupých" platformách (v tomhle případě by asi vlákna zvládaly targety C a nodejs... Python to rozumně umí až od trojky, PHP to zase snad prý neumí v režimu skriptů pro webserver, což je tedy zrovna asi platforma, na kterou budu cílit).
Přitom si jen vezmi hlídání toho, že ve vlákně by se měly používat reentrantní verze funkcí ze standardní knihovny, zatímco mimovlákno to potřeba není, by v ručně psaném vícevláknovém kódu zkrátka byly k zbláznění. Takhle mi code generátor sám pořeší, aby každé odstartované vlákno mělo vlastní kopii proměnných ve scope (podtýkám, že typicky půjde o kopie refererencí/pointerů na objekt - ne o kopii celého objektu), a hloupější cílové platformy se o "zvláknovatelnosti" nedozví vůbec - a je to.
Už jen to, abych z jediného zdrojáku mohl vygenerovat paralelně obyčejnou i thread-safe verzi kódu, aniž bych nad tím musel dál přemýšlet, je dostatečná motivace začít nad něčím takovým přemejšlet :-) (tedy v podstatě - přemýšlím nad tím, jak to udělat, abych už nemusel přemýšlet :-)
Všechna CPU jsou už řadu let vícejádrová a já v podstatě pořád programuju tak, jako se programovalo před 20 lety, když ta jádra byla v nejlepším případě tak 2 a jedno trvale žral systém. A přemýšlet nad tím, kolik vlastně těch threadů mám pustit, se mi fakt nechce a chci aby o tom za mě přemýšlel počítač, který to ví líp (zatímc to, jestli se o to vůbec můžeš pokusit, naopak zase JÁ vím líp...)