Iterátory v novém VB

Tomáš Herceg       14.08.2008       C#, VB.NET, Offtopic       11501 zobrazení

Na blogu Paula Vicka, jednoho z lidí, kteří se přímo podílejí na vývoji a rozšiřívoání jazyka Visual Basic, vyšel zajímavý článek na téma iterátory. V jazyce C# jsou už poměrně dlouho, vypadá to nějak takto:

         private IEnumerable<int> Seq(int top)
{
for (int i = 0; i < top; i++)
yield return i;
}

private void Form1_Load(object sender, EventArgs e)
{
foreach (int i in Seq(5))
MessageBox.Show(i.ToString());
}

Jak to funguje? Máme funci Seq, která obsahuje cyklus od 0 do top - 1, kde top je parametr, který jsme funkci předali. V každém kroku cyklu se provede příkaz yield return i, to znamená, že se vrátí aktuální hodnota proměnné i, ale díky klíčovému slovu yield se výsledek předá jako prvek kolekce. Všimněte si, že funkce vrací IEnumerable<int>, což je kolekce nějakých integerů. Metoda se tedy zavolá a jednotlivé prvky kolekce "generuje" voláním yield return. Jakmile doběhne cyklus, dojde se na konec funkce a kolekce se uzavře, další prvky už nemá.

Takže zavoláním Seq(5) nám brátí kolekci čásel 0,1,2,3 a 4. Když ji foreach cyklem projdeme a pro každý prvek zobrazím MessageBox, uvidíme přesně tato čísla.

A přesně tohle bude velmi pravděpodobně umět i nový Visual Basic, jen syntaxe bude trochu složitější a robustnějši:

Module Module1
    Function FromTo(ByVal low As Integer, ByVal high As Integer) As IEnumerable(Of Integer)
        Return Iterator
                   If low <= high Then
                       Return low
                       Return Each FromTo(low + 1, high)
                    End If
               End Iterator
    End Function

    Sub Main()
        For Each i In FromTo(1, 5)
            Console.WriteLine(i)
        Next
    End Sub
End Module

Tento kousek kódu jsem si vypůjčil z dotyčného článku, podstatná je první metoda. Iterator a End Iterator ohraničují iterátor, ten je v tomto případě "anonymní", nemá žádný název. Klidně můžeme napsat něco jako Dim kolekce = Iterator: Return 123: Return 13: End Iterator. Je to prostě způsob, jak vygenerovat kolekci prvků.

Zajímavá featura, kterou už C# nemá, je možnost začlenit do generované kolekce kolekci jinou, to je to Return Each kolekce, což prostě do kolekce, kterou aktuálně generujeme, vrazí prvky z předané kolekce (ať už vznikla, jak chtěla, na tom nesejde, může to být obyčejné pole).

V komentářích se ale objevilo několik zajímavých názorů, že když už jsou iterátory anonymní, proč by nemohly být ty obyčejné, které by vypadaly třeba takto:

     Public Iterator MujIterator()
Return 1
Return 2
Return 3
End Iterator

Toto řešení je sice hezké a konzistentní, ale co když budu chtít mít vlastnost vracející vygenerovanou kolekci. Pak budu stejně muset použít iterátor anonymní. Někoho tam ještě napadlo tohle:

     Public Iterator Function MujIterator()
Return 1
Return 2
Return 3
End Function

Tato syntaxe by byla kompatibilní i s vlastnostmi, prostě bychom napsali Public Iterator ReadOnly Property ... a bylo by, ale na druhou stranu už to není konzistentní, tady totiž končíme pomocí End Function, kdežto anonymní iterátor končí End Iterator. Co se mě týče, buď bych nechal jen anonymní iterátory, nebo jen obyčejné. Raději bych ty anonymní, mají univerzálnější použití, i když v drtivé většině případů se stejně budou používat ve funkcích nebo vlastnostech.

 

hodnocení článku

1 bodů / 1 hlasů       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Diskuse: Iterátory v novém VB

Uznávám, že vymyslet kompikovanou a otravnou syntaxi pro jednoduchou věc dalo jistě spousty práce ... proč ale neinvestují čas do implementace něčeho užitečného a raději zkomplikovávají již vymyšlené? Zajímalo by mě, kdy MS konečně objeví Ameriku a implementují pořádný preprocesor nebo kvalitní chybové hlášky. O pořádné (hlavně paměťové) optimalizaci .net aplikací radši ani nesním, protože je to sen nereálný ....

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

.NET Framework 3.5 má lepší kompilátor, lépe inlinuje funkce a u některých aplikací je až o 40% výkonnější. Mě se po jeho nainstalování docela viditelně zrychlilo Visual Studio. Už se těším, až budeš v Redmondu a ukážeš jim, jak se to dělá.

A jinak s tou pamětí to opravdu není tak strašné, 8 bajtů overhead na jeden objekt není tolik. Nemůžeš po managed prostředí chtít, aby se chovalo jako céčko, jehož kompilátor se vyvíjí daleko déle a dají se tam dělat lepší optimalizace.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To máš dobré - moje Visual Studio je pomalé úplně stejně jako předtím

Proč by .netí kompilátor neměl umět dělat optimalizace tak jako Cčkový? Teoreticky díky kompilaci pro konkrétní stroj by to měl zvládat mnohem lépe.

8B sice není hodně, ale taky to není všechno, je třeba ještě započítat režii GC apod.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jaké chybové hlášky se vám zdají nekvalitní? Pokud vám nevyhovuje správa paměti Managed aplikací (která je mimochodem velmi kvalitní) a preprocesor, běžte si bastlit v neefektivním a zbytečně komplikovaném C++ pro ten pocit dominance nad vlastním kódem...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No, ono s tou efektivitou je to těžké. Buď je v tom efektivní programovat (.NET), anebo je efektivní výstupní kód (C++). Každý jazyk se hodí na něco jiného, ale na .NET bych zase tak nekydal, je to nejlepší managed platforma, která existuje. Té paměti opravdu nežere tolik a výkonná je taky dost, i když rezervy tam jsou. Dneska, když 4GB paměti stojí nějakých pár stokorun, tak bych to s tou pamětí zas tak tragicky neviděl.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

No však já myslím efektivitu z hlediska vývoje. C++ rozhodně není nástroj který by se dal označit jako RAD. To co by se smolilo v C++ půl dne, by se ve VB.NET/C# smolilo půl hodiny. Z hlediska výkonu u běžných Windows aplikací je výkon srovnatelný, teprve u nějakých specializovaných výpočtů nebo náročných aplikací může být znát rozdíl. Nechápu jak někdo může argumentovat paměťovou náročností .NET aplikací, když je dnes běžně 2 GB+ RAM a z toho je 75% nevyužito a proto není důvod nějak zvlášť šetřit. Obzvlášť při optimalizacích, které dokáže .NET Runtime (uvolnění paměti v případě potřeby).

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Je vidět, že nemáte Win Vista, ty tak 700-800MB paměti slupnou jako malinu pro sebe a své služby, Outlook a pár Visual Studií a různé drobnosti si také něco vezmou a nakonec je člověk rád za každých nespotřebovaných 10MB.

Ale zajímalo by mě, kde berete ten údaj, že běžné je >=2GB RAM - to je běžné v západních zemích a v nových strojích, ale soudě podle mého okolí rozhodně ne u běžných českých PC.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

S tím souhlasím, už jen proto, že mě zrovna žádná jiná managed platforma kromě Javy nenapadá. Java sice je mnohem lepší v multiplatformicitě, ale jinak pokulhává.

Ohledně ceny - jsi z levného kraje,taková bežná paměť do desktopu či noťase stojí přes 1k, rychlá do desktopu několik tisíc a u kvalitních serverových to jde až do desetitisíců za 8 či 16GB

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Vzhledem k pořizovací ceně stroje to není žádná položka, před týdnem jsem kupoval 4GB paměti do notebooku za 1500 Kč. U serverů je to dražší, jako ony servery jsou drahé samy o sobě.

Java je ještě daleko paměťově rozežranější než .NET, .NET je oproti ní nesrovnatelně lepší.

Pokud vyvíjíte malo aplikaci, pak problémy s pamětí řešit skoro nemusíte. Pokud děláte na velkém projektu, tak než ho dokončíte, tak je situace s pamětí zase výrazně lepší než na začátku.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pro pocit dominance možná programujete vy, já programuju pro peníz, který kápne z kvalitních aplikací, což se v některých případech (funkce pro práci s velkým množstvím dat atp) dělá mnohem lépe v C++.

Nekvalitních hlášek je víc, z poslední doby je to hlavně to, že Windows se neobtěžují mi napsat, která (unmanaged) DLL konkrétně chybí v případě, že načítám DLL, která tam sice je, ale některá z jejích importovaných Dllek už ne. V kombinaci s WinSxS to občas dělá problémy třeba na hodinu, které se sice občas dají řešit depends.exe, občas jen metodou pokusu a omylu.

Nebo třeba obrázková "Knihovna DLL (...)\Daq2.dll se pokouší o spravované spuštění uvnitř zámku zaváděcího modulu operačního systému. Nepokoušejte se spouštět spravovaný kód uvnitř funkce inicializace obrázku nebo funkce DllMain, neboť tato akce může způsobit zablokování aplikace.". Nebo třeba důvod pádu instalátoru Expression nástrojů.

Zde se projevuje moje skleróza, takže podobné hlášky velmi rychle zapomínám.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Jako problémy jsou všude, tady je hlavní průšvih, že hlášky jsou lokalizované do češtiny, takže z nich už nikdo nemá šanci poznat, co vlastně říkají.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Že si necháte do Windows nacpat český lokalizační balíček pro .NET Framework (kde jsou bohužel lokalizované i texty vyjímek) je jen vaše hloupost. Jinak stále ještě nechápu proč se zde zdržujete za účelem vyvolávání flame, vaše příspěvky ve mě vzbuzují pocit, že se v .NETu neorientujete a jediné co vám jde je vaše modla jménem C++, ovšem někdo vás nutí v .NETu psát a vy si zde vyléváte zlost...

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Pokud máte třeba české Windows Vista, nemáte na výběr, český .NET tam už je předinstalován a pryč ho nedáte. On ten .NET také není úplně dokonalý, je tam pár věcí, které by se daly vylepšit, nemusíme se zase tvářit, že je bez chyby.

Je to prostě něco za něco, .NET přináší jisté výhody a jistá omezení. Volba technologie je důležitá věc, na něco se C++ hodí, na něco se hodí méně.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: Iterátory v novém VB

Dle mého názoru by bylo mnohem lepší, kdyby iterátory byly podobně jako v C#:

For i as integer = 0 to 10
    Yield Return i
Next

Je to rozhodně hezčí konstrukce.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ale nemůžete to použít inline, je to právě vázané na funkci. Těžko pak napíšete něco takového:

For Each i In Iterator
                  Return něco
              End Iterator
    MsgBox(i)
Next

Musíte kvůli tomu dělat funkci. Neříkám, že tohle bych používal nějak extrémně často, ale na druhou stranu občas by se to hodit mohlo.

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback