Portál AbcLinuxu, 24. říjen 2017 10:08

Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery

22. 3. 2012 | Daniel Kolesa
Články - Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery  

Na začátek bych se chtěl omluvit, že seriál nějakou dobu neběžel. To bylo z různých důvodů, hlavně tedy různé věci mimo PC. Nyní ale pokračujeme, dnes dokončíme ty funkce, co jsme načali, přidáme si nějaké ty delegáty, pak cykly, podmínky, a přijde řada i na pole a práci s nimi a také trochu pointery, které jsou s poli těsně spjaty.

Příště se chci podívat na asociativní pole, základní problematiku objektů (struktury a třídy, nebudeme jim věnovat příliš velkou pozornost jako např. v Javě, C# nebo C++, protože budeme pracovat hodně i s jinými paradigmaty, ale probrat je je třeba), modulů a kondicionální kompilaci. Dále se pak zaměříme na const/immutable, string mixiny a přejdeme plynule na nějaké ty templates a generické programování. Pak ještě budeme řešit správu chyb a několik jiných věcí v jazyce, a nakonec přejdeme na psaní nějaké reálné, celkem velké aplikace, kde využijeme už naučených technik a probereme pár nových.

Obsah

Lekce 6 – funkce a delegáty – pokračování

link

V minulém díle jsme načali problematiku funkcí. Teď už bychom měli umět nějakou tu základní funkci vytvořit, předat jí argumenty a vrátit hodnotu. Stačí to ale? Co když chceme zevnitř funkce modifikovat nějakou neglobální proměnnou, nebo ji jen přečíst? Jak spravovat u funkcí chyby? Co je to takový function overloading? Nebo funkce s variabilním počtem argumentů? Na to všechno se dnes podíváme.

Design kontraktem

link

Design kontraktem je jedna z nejlepších věcí v D. Jedná se v podstatě o systém podmínek, které se dají aplikovat na funkce a také na třídy (o tom v kapitole o třídách). Podobně lze programovat i C++, ale výsledek je často neohrabaný. D přišlo se speciální syntaxí. Základní nápad za kontrakty je jednoduchý. Kontrakt je v podstatě pouze výraz. Takový výraz se musí vyhodnotit jako pravda, jinak program obsahuje chybu a ta se musí opravit.

Assert

link

Assert je základním kontraktem. Je přítomen v mnoha jazycích, včetně C/C++. D není žádnou výjimkou. Assert je to, o čem jsem se zmínil nahoře – výraz, který se musí vyhodnotit jako pravda.

Použije se např. takto:

void foo(bool x)
{
    assert(!x);
}

To zařídí, aby když hodnota předaná funkci foo je pravdivá, tak se jedná o chybu v programu, a běh programu se tudíž ukončí. Je možné předat i zprávu, která se vypíše na výstup při chybě:

assert(false, "Sem by se program vůbec neměl dostat.");

Kromě toho existuje ještě tzv. static assert. Ten se oproti normálnímu assertu vyhodnocuje při kompilaci. To umožňuje některé chyby zachytit už před tím, než se program zkompiluje. Syntaxe je stejná, jen se přidá slovíčko static:

static assert(x == 5);

Oproti Cčku, které prostě ukončí program, v D se dá chybný assert chytit jako výjimka. Design kontraktem v D ale nespočívá pouze v assertu.

Pre a post kontrakty

link

Pre a post kontrakty jsou bloky kódu, které se vyhodnocují jako podmínky před spuštěním funkce a po spuštění funkce. Zapisují se nějak takto:

in
{
.... pre-kontrakt ....
}
out (result)
{
.... post-kontrakt ....
}
body
{
.... tělo funkce ....
}

Příkladem si můžeme uvést funkci, která shodí program, pokud první argument je menší než 4, druhý argument menší než 16, nebo pokud návratová hodnota je větší než 65536.

int foo(int a, int b)
in
{
    assert(a >= 4);
    assert(b >= 16);
}
out (result)
{
    assert(result <= 65536);
}
body
{
    return a * b;
}

Pokud funkce nevrací nic a chceme post-kontrakt, pak není třeba uvádět (result), a syntaxe je totožná s in. Na kontraktech není nic složitého, je to primitivní koncept, a přitom je velice užitečný v praktickém programování.

Overloading funkcí

link

Často chceme mít několik variant té samé funkce s různými argumenty. V Cčku je nutné každou takovou funkci pojmenovat jinak. To je často dosti nepraktické, ale v C nutné. V D je to jednoduché:

void foo() { }
void foo(int x) { writeln(x); }

V takovém případě si D při volání foo zjistí, jestli některá z funkcí sedí. Pokud ne, program se nezkompiluje. Pokud jich sedí více, také se nezkompiluje.

Předávání funkcí jako argumenty

link

Je jednoduché:

void foo(ret function(args) x) { x(...); }

Např.

void foo(int function(float) x) { writeln(x(3.14f)); }
foo(function int(float y) { writeln(y); return 5; });

V tomto příkladě jsem de facto předal literál funkce. Samozřejmě je možné předat jakoukoliv funkci, která je dostupná v aktuálním kontextu.

Template funkce

link

Tady se poprvé seznámíme s problematikou templates, nebo česky šablon. Už název napovídá, že template funkce bude „předloha“ k vygenerování nějaké reálné funkce. Ti, co mají nějakou předchozí zkušenost např. s C++, už ví; oproti C++ ale D přináší mnohem lepší syntaxi, která se o moc neliší od syntaxe normálních funkcí.

Template funkci zapíšeme jako:

návratový_typ název(template argumenty)(argumenty)
{
....
}

Co jsou to ty template argumenty? Ty v podstatě specifikují argumenty, které se vyhodnocují při kompilaci. Většinou u nich nespecifikujeme typ. V takovém případě se nejedná o hodnotu, ale o typ samotný. Template argumenty se dají využít jako typy reálných argumentů:

void print(T)(T arg) { writeln(arg); }

Když takovou funkci zavoláme s jakýmkoliv typem, který je podporován funkcí writeln, bude to fungovat. Při zavolání takové template funkce se z předané hodnoty zjistí typ T, a na jeho základě se vygeneruje funkce, která se pak teprve volá.

Pokud není možné typ vydedukovat z argumentů, pak je nutné jej explicitně specifikovat. Například:

T a(T)() { return T.init; }

Vlastnost .init už byla zmíněna dříve, specifikuje výchozí hodnotu takového typu. Takovou funkci pak zavoláme s pomocí vykřičníku:

auto x = a!int();

O auto jsme se ale ještě nezmínili. Jedná se o jednu z možností, kterou poskytuje typová inference v D. Pokud je možno typ proměnné zjistit z hodnoty, pak auto se automaticky nahradí tím pravým typem. Znamená to, že

auto x = 5;

fungovat bude, ale jen

auto x;

už ne. Každopádně to byla jen taková odbočka. Pokud specifikujeme více template argumentů, které se nedají zjistit, dáme je do závorek:

x!(int, float)();

Template argumenty nemusí být jenom typy. Mohou to být i celá čísla jakéhokoliv typu, imutabilní řetězce a literály jakéhokoliv typu. Příklad s čísly:

void foo(int T)() {}
foo!5();

To se hodí např. při různých výpočtech při kompilaci. Imutabilní řetězce:

int foo(string code)() { mixin(code); }
foo!"return 5;"();

Takový výraz bude mít hodnotu 5. Mixin je funkce, která umožňuje řetězce známé při kompilaci „zabudovat“ do kódu. To se hodí např. pro tvorbu domain-specific jazyků. Zatím se jimi ale zabývat nebudeme.

Pokud template argument má typ alias, jedná se o literál jakékoliv hodnoty. To se hodí u lambda funkcí. Za chvíli o nich bude řeč.

Template argumenty je možné specializovat. Například:

void foo(T      )() { ... } /* pro všechno
ostatní */
void foo(T : int)() { ... } /* specializace pro int */

Ještě bych se měl zmínit o tzv. variadických templates. Pokud jako poslední template argument zapíšeme NÁZEV..., pak to znamená tzv. template parameter tuple. Ten nemá explicitně specifikovaný typ, musí být striktně poslední a může být jen jeden. Může reprezentovat jak typy, tak hodnoty. Obsahuje pak všechny template parametry, které nebyly explicitně specifikovány předtím. Dá se s ním pracovat jako s polem (přistupovat na jednotlivé prvky přes [index], řezat apod. – viz pozdější kapitola o polích).

Jinak o templates nebude asi nějaká zvláštní kapitola. Místo toho je budu zmiňovat průběžně tak, aby se je programátor naučil používat přirozeně. Templates nemusí být jen funkce. Mohou být i template struktury, třídy, nebo klidně i templates jako samotné.

Funkce s variabilním počtem argumentů

link

Občas se hodí funkcím předat blíže nespecifikovaný počet argumentů. K tomu slouží tzv. variadické funkce. D je podporuje ve čtyřech formách.

Jako v C

link

Tato cesta se hodí, pokud tvoříme interface k C v D. Má stejné nedostatky, jako v C, tzn:

Argumenty jsou přístupné přes pointer _argptr. Pokud znáte C, nemělo by toto dělat problém. Pokud ne, zatím nebude důvod tuto cestu použít. Modul core.vararg poskytuje template funkci va_arg, umožňující získat hodnotu.

Příklad:

import std.stdio, core.vararg;
extern (C) void print_all_as_int(int n, ...)
{     /* Cyklus foreach - probereme v další lekci, tady v
podstatě pouze spustí writeln pro každou hodnotu od 0 do n, kde n není
zahrnuto */
    foreach (i; 0 .. n)
        writeln(va_arg!int(_argptr));
}

Jako v D

link

Jedná se o podobnou cestu. Také je přítomen pointer _argptr. Řeší ale některé nedostatky:

K _argptr přidává ještě další skrytou proměnnou _arguments, která je v podstatě polem obsahující informaci o počtu argumentů a typ každého.

import std.stdio, core.vararg;

void print_float_int_or_error(...)
{    /* .length vrátí délku pole */
    foreach (i; 0 .. _arguments.length)
    {
        if (_arguments[i] ==
typeid(int)) writeln(va_arg!int(_argptr));
        else if (_arguments[i] ==
typeid(float)) writeln(va_arg!float(_argptr));
        else assert(false);
    }
}

Typově bezpečně

link

Tato cesta se hodí, když všechny argumenty jsou stejného typu, tzn. mohou vytvořit pole. Například:

void print_ints(int[] args ...) { writeln(args); }

V podstatě se všechny tyto argumenty přetransformují do jednoho pole.

Typově bezpečně se všemi typy

link

Zdaleka nejelegantnější cesta. Hodí se kdykoliv, kdy je třeba pracovat s mnoha typy, a tyto typy jsou známy při kompilaci. Dá se použít skoro vždycky a nemá žádné další nároky např. na paměť, hodně se toho děje při kompilaci. Využíváme zde template funkcí, které jsme probrali nahoře, přesněji parameter tuple.

Například:

void print_all_args(T...)(T args) { foreach(arg; args) writeln(arg); }

Vzhledem k tomu, že parameter tuple obsahuje všechno, co se předá, použití jej jako pravých argumentů funkce vyústí v to, že se dá předat funkci kolik pravých argumentů chceme. Funguje to stejně, jako kdybychom všechny argumenty předali explicitně. Díky manipulaci template parameter tuples jako s poli lze přes toto iterovat pomocí už zmíněného cyklu foreach; cykly budeme probírat za chvíli. Taková funkce vypíše všechny argumenty předané funkci. Přes args přistupujeme k hodnotám; přes T přistupujeme k typům.

Delegáty

link

Teď se podíváme na delegáty. Kromě delegátu se dá použít i název closure, popř. v užším slova smyslu lambda funkce. Jedná se o tzv. fat pointer. Skládá se ze dvou částí, pointeru na funkci samotnou a pointeru na kontext (stack frame). Kontext obsahuje lokální proměnné scope, která takový delegát uzavírá. V praxi to znamená, že je možné z delegátu modifikovat a číst proměnné z vnějšího kontextu. D implementuje pravé closures; pokud starý kontext zanikne, je zkopírován a uložen v delegátu. To umožňuje delegáty různě vracet apod.

Vnořené funkce

link

Nejjednodušší případ delegátů. Tyto funkce jsou delegáty z logických důvodů; programátor může očekávat, že bude moci přistupovat k vnějším proměnným.

void foo()
{
    int i = 5;
    void bar() { ++i; }
    bar();
    assert(i == 6);
}

Vnořené funkce jako delegáty mají výhodu i v tom, že se z nich dají dělat template delegáty:

void foo()
{
    int i = 5;
    void bar(T)(T arg) { writeln(arg); ++i; }
    bar(5); bar("hello"); bar(3.14f);
    assert(i == 8);
}

Pokud chce programátor opravdu, aby taková funkce nebyla delegátem, stačí před návratový typ přidat slovo static:

void foo()
{
    static void bar() { writeln("not a delegate!"); }
    bar();
}

Lambda funkce s dlouhým zápisem

link

Lambda funkce jsou takové delegáty, které většinou vyhodnocují výraz, ale mohou i složitější věci. D si zjistí, jestli taková lambda funkce přistupuje ke kontextu, a podle toho ji udělá buď delegátem, nebo obyčejnou funkcí. Pokud jsme si jisti, že je delegátem, pak ji můžeme předat podobně, jako funkci:

int i;
void foo(int delegate(int, int) x) { writeln(x(5, 10)); }
foo((a, b) { ++i; return a + b; });

Jak lze vidět, nespecifikoval jsem při volání typy. To není ani nutné, protože D v tomto případě využije tzv. typovou inferenci k dedukci typu z deklarace/definice funkce foo. Z ukázky lze vidět další věc – při předávání delegátů jako argumentů platí stejná pravidla jako u funkcí, včetně literálů, které se dají zapsat dlouze jako delegate ret(...) { ... }.

Tento kód má bohužel jednu nevýhodu, a to dost zásadní. Pokud D vyhodnotí, že se nejedná o delegát, kompilace selže (pokud se nepoužije dlouhý zápis zmíněný v předchozím odstavci). Proto je zde lepší využít template funkcí:

void foo(T)(T x) { writeln(x(5, 10)); }
foo((int a, int b) { return a + b; });

V tomto případě se ale objevuje další nevýhoda – není možné využít typovou inferenci. Místo toho zkusme něco takového:

void foo(alias x)() { writeln(x(5, 10)); }
foo!((a, b) { return a + b; })();

Co že toto dělá? Stejně jak jakékoliv T, U nebo cokoliv v template argumentech specifikuje typ, alias specifikuje literál jakékoliv hodnoty. V našem případě je to literál funkce/delegátu. Protože alias se v tomto případě vyhodnocuje až při volání, není nutné znát typy argumentů a tudíž je možné využít typovou inferenci. Ke zjištění typů pak dojde z hodnot. Template argumenty předáváme, jak už jsem dříve zmínil, přes !(...). Template funkce, která bere lambda funkci jako alias, musí být globální, ne součást nějakého běžícího kontextu.

Lambda funkce s krátkým zápisem

link

Jedná se o stejný princip, ale vzhledem k tomu, že klasické lambda funkce jsou dosti dlouhé, je přítomna v D alternativní syntaxe.

Vezmeme předchozí případ s aliasem. Jak můžeme nahradit to škaredé volání foo!((a, b) { return a + b; })(); ? Snadno:

foo!((a, b) => a + b)();

Zápis

(argumenty) => návratová_hodnota

je zkrácený zápis lambda funkce. Výrazy jako:

(a) => a * a;
popř.
(a, b) => a * b;

se dají přímo přeložit do

(a) { return a * a; }
, popř.
(a, b) { return a * b; }

Domácí úkol

link
  1. Napište funkci, která přijímá argumenty typů int a float a vrací jejich násobek. Pre-kontrakt bude ověřovat, zda int argument je větší než 10. Post-kontrakt bude ověřovat, zda návratová hodnota je větší než 50.
  2. Napište template funkci, která bere delegát jako alias a vrací jeho návratovou hodnotu.
  3. Napište variadickou funkci, která selže při kompilaci, pokud počet předaných argumentů přesáhne 10 (Použijte vlastnost .length pole argumentů)

Lekce 7 – podmínky, cykly, enumerace

link

Co je nám platné, pokud známe funkce a proměnné bez znalosti cyklů a podmínek? Tyto konstrukce jsou fundamentálními prvky v procedurálním programování. Bez nich nemůžeme snadno řídit průběh kódu. Také se podíváme na enumerace. Tak jdeme na to :-)

Podmínky

link

Jak už název naznačuje, podmínky větví běh kódu. Bez žádného dalšího okecávání, napíšeme si podmínku:

if (VÝRAZ)
{
    ....pravda....
}
else
{
    ....nepravda....
}

Pokud VÝRAZ platí, spustí se blok kódu pro „pravda“. Pokud ne, spustí se blok ve větvi else. Pro jednoduché jednořádkové podmínky nejsou třeba složené závorky:

if (x == 5)
    foo();
else
    bar();

Větev „else“ není vždy potřeba. Tudíž je možné zapsat:

if (y == 10) x();

Binární operátor == porovnává dvě hodnoty. Lze použít samozřejmě už dříve použité operátory:

int y = 5;
if (y + 5 == 10) writeln("pravda!");

Opak operátoru == je operátor !=. Větvit můžeme dále, pomocí else if. Například:

if (x == 5) { ... }
else if (x == 10) { ... }
else { ... }

Pro porovnávání hodnot ještě používáme operátory < (menší), > (větší), <= (menší nebo rovno), >= (větší nebo rovno). Např.

if (x < 5) writeln("x je menší než 5");

Můžeme testovat několik podmínek pomocí operátorů && (AND) a || (OR). Příklad:

if (x == 5 && y == 10) ... /* Pokud x je rovno 5 a zároveň y 10
*/
if (x == 5 || y == 10) ... /* Pokud alespoň jedna z podmínek platí */

Unární operátor ! převrací hodnotu výrazu. Např:

bool x = true;
if (!x) ....

Uvnitř podmínek můžeme používat i přiřazování, pokud dáme výraz do dalšího páru závorek.

if ((x += 10) == 20) ...

Speciální podmínka static if testuje při kompilaci. Hodí se to při programování s templates.

void foo(int i)()
{
    static if (i == 5) ....
    else static if (i == 10) ....
    else ....
}

Ternární operátor umožňuje krátký zápis jednoduchých podmínek:

(x == 5) ? pravda : nepravda

Takové výrazy je možné psát např. i ve volání funkcí, což se hodí při psaní kompaktního kódu:

void foo(int x) { ... }
foo(y ? 1 : 5);

V souvislosti s podmínkami bych měl uvést ještě is(). To umožňuje kontrolovat typy. Např.

void foo(T)()
{
    if (is(T == int)) ....
    else ....
}

Samozřejmostí je kombinace se static if. Výraz is(T == int) kontroluje přesně typ. Nahrazením == dvojtečkou lze kontrolovat implicitně konvertovatelné typy na tento typ:

is(T : int)

Výrazů s is() je možné využít pro specializaci template funkcí:

void foo(T)() if (is(T == int)) { ... }

Switch

link

Speciálním případem podmínek je switch. Ten umožňuje efektivně testovat na mnoho hodnot bez toho, abychom museli psát spoustu if větví. Syntaxe:

switch (výraz) { case HODNOTA:.... kód .... break; case NĚCO: .... kód .... break; default: break; }

je ekvivalentní s

if (výraz == HODNOTA) ... else if (výraz == NĚCO) ...

Na konci každé case většinou musíme dát break;, jinak se přejde na další case. Toho se dá využít pro testování několika hodnot se stejným kódem:

int i = 10;
switch (i)
{
    case 5:
    case 10:
        writeln("5 nebo 10");
        break;
    case 15:
        break;
    default:
        break;
}

Kód v default je ekvivalentní s větví else u standardní podmínky. D nabízí kromě toho ještě např. goto case, který přejde na nějaký case.

case 5:
    goto case 10;
    break;
case 10:
    break;

Oproti C, C++ apod., D umožňuje testovat nejen integrální hodnoty, ale i např. řetězce:

string x = "hello";
switch (x)
{
    case "hello": writeln("hello!"); break;
    default: break;
}

Case mohou obsahovat i několik hodnot:

case 5, 6, 7, 8, 9, 10: break; /* od 5 do 10 */

Mohou být použity i hodnoty proměnných.

int i = 50;
....
case i: ... break;

Kromě toho existuje ještě final switch, který má několik omezení:

Cykly

link

Podmínky samotné většinou nestačí. Často potřebujeme něco opakovat. K tomu má D několik cyklů.

While

link

Nejjednodušší je cyklus while. Opakuje, dokud je splněna podmínka. Například:

int i = 5;
while (i < 150) ++i;

Pokud v cyklu while použijeme break;, vystoupíme z cyklu. Např. tímto dosáhneme podobné funkcionality.

int i = 5;
while (true)
{
    if (i == 150) break;
    ++i;
}

Další slovíčko continue; přeskočí na další iteraci. Např.

int i = 5;
while (true)
{
    if (i == 150) { ++i; continue; }
    ++i; writeln(i);
}

Tento příklad vypisuje čísla od 6 až do nekonečna, kromě 150, která nebude vypsána.

Do .. while

link

Cyklus

do { .... } while (výraz)

je identický s while, s jedním rozdílem; kód v bloku se spustí alespoň jednou, až pak se začne testovat podmínka.

For

link

Cyklus for je takový vylepšený while. Jeho syntaxe je taková:

for (inicializace; podmínka; post-iterace) { ... }

Část „inicializace“ se spustí první. Potom se cyklí, dokud je splněna podmínka. V části „post-iterace“ se provede něco, co má být spuštěno po každém cyklu. Například

for (int i = 5; i < 150; ++i) writeln(i);

vypíše čísla od 5 do 149. Break a continue fungují s jedním rozdílem; část post-iterace se spustí i při break nebo continue. To znamená že

for (int i = 5; i < 150; ++i) if (i == 100) continue; else
writeln(i);

sice nevypíše 100, ale provede správně inkrementaci. Cyklus for se v D nepoužívá tak často, protože cyklus foreach je pro většinu případů vhodnější.

Foreach

link

Cyklus foreach je přídavek jazyka D ke klasickým C nebo C++ cyklům. Umožňuje iterovat přes číselný rozsah, pole, asociativní pole, template argument tuple i uživatelské iterovatelné struktury.

Ekvivalent for (int i = 0; i < 10; ++i):

foreach (i; 0 .. 10) { ... }

Typová inference se stará o typ i. Samozřejmě je možné jej i explicitně specifikovat. Iterace přes pole:

int[] x = [ 5, 10, 15, 20 ];
foreach (v; x) writeln(v); /* vypíše každý prvek pole */

Pole jsme sice ještě nedělali, ale tento příklad by měl dávat smysl. Iterovat je možné i s indexem:

int[] x = [ 5, 10, 15, 20 ];
foreach (idx, val; x) writefln("x[%d] == %d", idx, val);

V případě asociativních polí by hodnota idx byla klíčem aktuálního prvku. Jinak je indexem (0 až délka-1).

Cyklus foreach jsme vlastně zmínili už v našem příkladě s variadickou funkcí. To funguje na stejném principu, jako pole.

Tím bych cykly zakončil; budeme je samozřejmě dále využívat v praxi. Cílem nyní není popsat úplně každou funkci, to bychom tu byli týden a ještě by tento díl nebyl stále u konce; cílem je popsat základní ideu a dále rozšiřovat při praktickém použití.

Enumerace

link

Může se zdát trochu divné je dělat zde, ale budou velice užitečné a proto je chci probrat hned. Enumerace je de facto kolekce konstant. V C, C++ (před C++11) jsou pouze číselné. V D mohou být jakéhokoliv typu. Základní enumeraci definujeme

enum Jméno
{
    A, B, C, D
}

Potom můžeme dělat instance enumerací:

Jméno x = Jméno.C;

Hodnota A bude 0, B 1, C 2, D 3. Explicitně specifikovat hodnoty je možné, dobrou konvencí je specifikovat první prvek jako 0. Následující prvky budou mít vždy o 1 větší hodnotu.

enum X
{
    A = 5,
    B, C, D
}

D umožňuje, jak už jsem řekl, dělat enumerace mnoha typů. Např. pro řetězce

enum X: string
{
    A = "foo",
    B = "bar",
    C = "baz"
}

Takové enumerace přirozeně potřebují explicitně specifikované hodnoty. Výchozím typem pro enumerace je int. Enumerace je možné přirozeně předávat jako argumenty a castovat z/do původních typů, ze kterých vycházejí. K čemu je toto dobré? Většinou se využívají pro set vlastností, které ovlivňují hodnotu něčeho. V praktických úlohách na ně dojde.

Domácí úkol

link
  1. Napište program, který vytiskne pomocí cyklu sudá čísla od 2 do 160.
  2. Napište variadickou funkci, která vypíše všechny číselné argumenty jí předané, nečíselné ignoruje, a ke každému číselnému přidá 2 (využijte foreach, podmínky a výrazu is()).
  3. Přepište úkol 1 do ostatních typů cyklů.

Lekce 8 – pole a práce s nimi

link

Znalost funkcí a výrazů pro kontrolu průběhu programu je hezká věc a tvoří už celkem solidní znalostní základ. Teď se naučíme pracovat s poli. D to dělá pro uživatele relativně jednoduché. Asociativní pole probereme později.

Typy polí

link

Pole můžeme rozdělit na dva typy. Prvním typem jsou statická pole, druhým dynamická pole. Statická pole mají fixní velikost a ta musí být známa už při kompilaci. Statická pole jsou na stacku a jsou analogická se statickými poli v ANSI C (ne C99).

Deklarují se:

typ[velikost] pole;

například:

char[512] buf;

Velikost statického pole nesmí přesáhnout 16 MB. Je to hodnotový typ, předává se také vždy po hodnotě a lze jej vracet z funkcí. V tom je rozdíl od C. V C se statická pole předávají po pointeru.

Alternativní způsob deklarace jakéhokoliv pole je

typ pole[velikost];

stejně jako v C, ale nepoužívejte tuto možnost, je to spíš jen pro snadnější migraci.

Dynamická pole jsou alokována dynamicky, tudíž většinou na heap. Deklarují se

typ[] pole;

například

int[] x;

V defaultu je paměť dynamických polí spravována automaticky garbage collectorem, stejně jako všechno ostatní v D. Dynamická pole jsou předávána referencí.

Inicializace polí

link

Pole inicializujeme většinou pomocí literálu, nebo vůbec:

int[] x = [ 5, 10, 15 ];

Takové pole bude mít délku 3. U statických polí jsou všechny neinicializované prvky nastaveny na nulu. Dynamická pole můžeme inicializovat i na void, pak je obsah nedefinován, ale to je nebezpečná optimalizace.

Slices

link

Před práci s poli je nutné ujasnit si dva pojmy. V D se rozlišuje pole a slice (řez). Pole je buď statické pole přímo, nebo dynamicky alokované pole bez uložené délky, stejně jako v C (např. při alokaci pomocí calloc). To, s čím uživatel bude v naprosté většině případů pracovat, je slice. Slice je reprezentován pointerem na první element pole a délkovou informací, ke vždy na stacku.

typ[] x;

je de facto slice. Ukazuje na nějaký pointer (v tomto případě nulový pointer) a délkovou informaci má nastavenou v defaultu na nulu. Jak už název napovídá, slices se budou moci dále řezat na kratší kousky. Pokud máme např. pole, které je reprezentováno prvky

0-1-2-3-4-5-6-7

a chceme slice od 3 do 5, pointer se nastaví na pointer elementu 3 a délková informace taky na 3.

Práce s poli

link

Inicializujme si pole z literálu, např.

int[] arr = [ 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 ];

Dojde k alokaci paměti pro pole, vytvoření slice nad polem a to je ten samotný int[]. To neplatí pro statická pole, kde literály jsou samozřejmě na stacku. Když si pole vypíšeme pomocí

writeln(arr);

tak by se mělo správně vytisknout.

Teď chceme nastavit druhý prvek na 11. To můžeme udělat snadno

arr[1] = 11;

Když si zjistíme délku pole:

writeln(arr.length);

mělo by se vypsat 10. Pokud chceme rozšířit pole na délku dejmetomu 15, můžeme tuto vlastnost modifikovat:

arr.length = 15;

Pak si můžeme nastavit hodnoty jednotlivých prvků. Pokud nová délka je menší, nedojde k realokaci, je to ekvivalentní se slice [0 .. nová_délka]. Teď dejmetomu chceme získat podpole, které začíná prvkem s hodnotou 15 a končí 35. To je snadné:

int[] sub = arr[2 .. 6];

Nedojde k žádnému kopírování. Tento řez polem bude sdílet paměť s původním polem. To znamená, že změna hodnoty v původním poli se projeví i v řezu. Teď chceme z tohoto podpole vyřezat první prvek. Uděláme:

sub = sub[1 .. $];

$ se substituuje za délku pole. Je ekvivalentní s sub.length.

int[] x = arr;

jen vytvoří nový slice původního arr, tudíž nedojde ke kopii a x bude jen referencí původního pole. Pomocí [] lze vytvořit slice celého pole:

int[] x = arr[];

což je ekvivalentní s arr[0 .. $]. Teď chceme nastavit několik prvků arr na stejnou hodnotu. Provedeme

arr[0 .. 4] = 42;

Teď chceme nastavit první dva prvky na různé hodnoty. Provedením

arr[0 .. 2] = [ 3, 5 ];

se nastaví první dva prvky na 3 a 5. Co když chceme připojit k našemu arr jiné pole? Snadné:

arr ~= [ 150, 140, 130 ];

Když slice je jen další reference na pole, občas potřebujeme i duplikovat původní pole. To se dá udělat vlastnosti .dup.

int[] arr2 = arr.dup;

Teď chceme obrátit pořadí prvků v arr. Slices mají vlastnost .reverse. Tudíž můžeme udělat:

arr[] = arr.reverse;

Kromě .dup existuje i .idup, který vytvoří duplikát s imutabilními prvky, ale o tom později. Existuje i .sort, který pole seřadí, ale plánuje se jej zbavit, protože knihovna většinou bude mít lepší výsledky. Proto to nebudeme zde řešit. .sizeof vrátí délku vynásobenou velikostí jednoho prvku (což je .sizeof vlastnost toho prvku). Vlastnost .init vrátí pro dynamická pole null (jakožto nulový pointer) a pro statická pole literál výchozích hodnot prvků.

Slices umožňují kontrolu polí, takže pokud se zjistí při kompilaci změna mimo rozsah pole, program se nezkompiluje, a pokud se zjistí za běhu, vytvoří výjimku. O výjimkách se budeme bavit později, zatím nejsou potřeba. Aby se nesnižoval výkon, tato kontrola je povolena pouze, když program není zkompilován jako release.

Na závěr velmi krátká (a vcelku neefektivní – chtělo by to lepší pivot apod. :)) implementace algoritmu quicksort pomocí slices:

import std.stdio: writeln;

auto filter(alias pred, T)(T[] arr)
{
    T[] r; foreach (v; arr) if (pred(v)) r ~= v; return
r;
}

void main()
{
    T[] qsort(T)(T[] xs)
    {
        return (!xs.length ? [] :
            qsort(filter!(x => x <xs[0])(xs[1..$])) ~
            xs[0..1] ~ qsort(filter!(x => x>=xs[0])(xs[1..$])));
    };
 
    auto x = [ 4, 150, 3, 8, 163, 141, 98, 56, 99, 108 ];
    writeln(qsort(x));
}

Podobné implementace lze najít např. pro Haskell a jiné funkcionální jazyky.

Pointery

link

Pointery, česky ukazatele, jsou de facto pouze čísly, jejich velikost je v 32 nebo 64 bitů, dle architektury (D nepodporuje 16bitové architektury). Jejich hodnotou je určitá adresa v paměti. Nulový pointer ukazuje na nulu, to znamená na nic, v D se zapisuje jako null (aby se předešlo konfliktům s nulou, jako v C++). Pointery jsou v C použity na spoustu věcí, např. k předávání „po referenci“, k práci s poli – v tom případě pointer ukazuje na první prvek pole apod. Pointery jsou samozřejmě i v D. Pokud máme pole, např.

int[] x = [ 5, 10, 15, 20, 25 ];

pak pointer na 5 získáme

int* y = x.ptr;

Takový pointer pak můžeme předat třeba nějaké C funkci. Získáním pointeru se vzdáme délkové informace. Kromě získávání pointerů ze slices je možný i opačný postup.

int[] z = y[0 .. 5];

To vytvoří v podstatě identický slice jako v případě x. Vzhledem k tomu, že neznáme délku, musíme ji manuálně specifikovat. Takové chování umožňuje alokovat dynamická pole klasickými metodami jako v C, např.

import core.stdc.stdlib;
int[] arr = (cast(int*)calloc(5, int.sizeof))[0 .. 5];

Samozřejmě, u takového pole nelze měnit .length vlastnost a musíme se jej manuálně zbavit:

free(arr.ptr);

K použití pointerů by ve většině případů v D neměl být důvod. Jazyk poskytuje dost funkcí, které mohou pro high level programování pointery úplně nahradit, ale vzhledem k tomu, že D je také systémovým jazykem, jsou pointery přítomny (a i z důvodu kompatibility s C knihovnami). Teď se jimi moc zabývat nebudeme, to ani není cílem. Jen bych chtěl upozornit, že kód v C:

int *x, *y, *z;

se v D zapíše

int* x, y, z;

Pointerová aritmetika apod. v D funguje naprosto stejně, jako v C. Pracovat s pointery jako s poli se také dá, identicky s C. U pointerů na struktury neexistuje -> pro přístup k jednotlivým prvkům, používá se ., stejně jako u normálních instancí:

Foo *bar = new Foo();
/* writeln(bar->x); špatně */
writeln(bar.x); /* dobře */

V souvislosti s pointery, D má ještě pole typu void[], které má pointer typu void*. Stejně jak není možné provést dereferenci void* pointeru, tak není možné vzít jeden prvek takového pole.

Matice

link

Dva a vícedimenzionální pole v D nejsou. Místo toho vytvoříte stejně jako v C „pole polí“. Příklad:

int[5][5] foo;

Řetězce

link

Řetězce v D jsou poli znaků. Rozlišujeme tři typy řetězců v D, podle velikosti jednotky:

O jejich literálech už bylo řečeno v předchozí kapitole. Literály jsou typu immutable(char)[] (mutabilní pole imutabilních znaků), popř. wchar, dchar. Pro lepší čitelnost má immutable(char)[] alias nazvaný string. Pro práci s řetězci platí stejná pravidla, jako pro pole, dají se spojovat, duplikovat, řezat apod.

Oproti C nejsou řetězce v D zakončeny nulou, protože se slices to nemá význam. Literály jsou ale zakončeny, pro kompatibilitu s C funkcemi.

Implicitní konverze

link

Všechny pointery v D (kromě function pointerů a delegátů) se dají převést na void*. Statická pole T[x] se dají implicitně převést na T[], const(T)[] a void[]. Dynamická pole se dají převést na const(T)[] a void[]. Z toho vyplývá, že const(T)[] se dá použít jako např. typ argumentu tam, kde fungují jak imutabilní řetězce, tak mutabilní řetězce. V takových případech se ale místo const doporučuje použít inout(T)[].

Domácí úkol

link
  1. Vytvořte program, který pomocí slicingu rozdělí jakýkoliv vstupní řetězec na slova (pro nalezení mezery použijte z modulu std.string funkci indexOf).
  2. Vytvořte variadickou funkci, která spojí všechna pole daná argumenty do jednoho a vrátí jej.
  3. Vytvořte funkci, která obrátí druhou polovinu pole.

Seriál Programování v jazyce D (dílů: 4)

První díl: Programování v jazyce D: Úvod a první kroky (1), poslední díl: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery.
Předchozí díl: Programování v jazyce D (3): Typy, proměnné, práce s čísly, literály a funkce

Další články z této rubriky

LLVM a Clang – více než dobrá náhrada za GCC
Ze 4 s na 0,9 s – programovací jazyk Vala v praxi
Reverzujeme ovladače pro USB HID zařízení
Linux: systémové volání splice()
Programování v jazyce Vala - základní prvky jazyka

Diskuse k tomuto článku

22.3.2012 09:38 Ladicek | skóre: 28 | blog: variace | Havlíčkův brod
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Odpovědět | Sbalit | Link | Blokovat | Admin
Se skřípěním zubů bych pochopil i kondicionální kompilaci, ale co je to set cyklů??
Ještě na tom nejsem tak špatně, abych četl Viewegha.
q66 avatar 22.3.2012 13:50 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
No, soubor cyklů.
q66 avatar 22.3.2012 17:42 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Změněno :)
22.3.2012 09:55 jekub
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Odpovědět | Sbalit | Link | Blokovat | Admin
"Tento příklad vypisuje čísla od 6 až do nekonečna"

nefunguje :-(
22.3.2012 11:26 JS
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Zkusil jste to nechat bezet nekonecne dlouho?
22.3.2012 11:39 EtDirloth | skóre: 4
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
netreba
q66 avatar 22.3.2012 13:53 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Omlouvám se, vypadlo mi tam v závorce "true". Nechám opravit, až se vrátím domů. A to bych přísahal, že jsem před zasláním testoval všechny kousky kódu, co v článku jsou :)
Jardík avatar 22.3.2012 14:13 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
řekl bych, že ani tak nejde o to true jako spíše o to, že do intu jde nacpat nějaká maximální hodnota a tak nekonečna nedosáhnete, ani když to poběží nekonečně dlouho, vždycky to přeteče.
Věřím v jednoho Boha.
q66 avatar 22.3.2012 14:15 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
To je pravda :) Ale nebuďme příliš pedantičtí (v angličtině se takový člověk označuje jako "smartass") - běží to "jakože" do nekonečna.
q66 avatar 22.3.2012 17:42 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Příklad opraven.
Petr Bravenec avatar 22.3.2012 11:40 Petr Bravenec | skóre: 43 | blog: Bravenec
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Odpovědět | Sbalit | Link | Blokovat | Admin
for (inicializace; podmínka; post-iterace) { ... }
Část „inicializace“ se spustí první. Potom se cyklí, dokud je splněna podmínka.

Opravdu?
Petr Bravenec - Hobrasoft s.r.o.
q66 avatar 22.3.2012 13:50 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Co je za problém? První se inicializuje, před každou iterací se ověří podmínka, pokud ne, cyklus skončí, jinak se cyklí dál.
Bystroushaak avatar 22.3.2012 11:59 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Odpovědět | Sbalit | Link | Blokovat | Admin
Jsem rád za další díl, každá aktivita okolo D je potěšující, ale dnes se mi to zdálo dost zmatené. Kdybych nevěděl o čem je řeč, tak to nepochopím.
The operating system: should there be one?
q66 avatar 22.3.2012 13:54 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Něco konkrétního? Abych mohl vylepšit.
Bystroushaak avatar 22.3.2012 16:11 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Přišlo mi to takové zmatené. Možná nebylo nejšťastnější toho dát tolik najednou, osobně bych to rozdělil na víc dílů a popsal víc.
q66 avatar 22.3.2012 16:18 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Mým cílem není teď popsat všechno. Souhlasím, že je to možná na jeden díl trochu moc, ale tak to prostě vyšlo. Každopádně různé ty okrajové případy apod. budou popsány v průběhu seriálu. Teď chci jen rozebrat ten základ, a pak se chci pustit do nějaké větší praktické aplikace, na kódu se vše vysvětlí nejlépe, ale zatím je potřeba popsat ten základ a to je na tom všem nejtěžší..
Josef Kufner avatar 22.3.2012 14:13 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Od toho jsou předchozí díly seriálu ;-)
Hello world ! Segmentation fault (core dumped)
Bystroushaak avatar 22.3.2012 16:15 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ty jsem samozřejmě četl taky. Spolu s knihou D programming language a oficiálním tutoriálem/manem na stránkách D.

Možná je to tím že sám jsem to docela pitval na několik stánek a tady je to hodně zhuštěně podáno.
q66 avatar 22.3.2012 16:20 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
viz příspěvek nahoře. Ale jakákoliv kritika se hodí. Až to bude všechno venku, chci to stáhout, spojit do jednoho celku, provést revizi, vyčistit na základě připomínek a vydat. A přeložit do angličtiny.
Josef Kufner avatar 23.3.2012 12:33 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Nečetl jsem to nijak důkladně, spíš jen prolítnul příklady, ale srozumitelné mi to přišlo. Pokud čtenář už pár jazyků jakš takš ovládá, neměl by mít problém. Rozpitvávat to na mnoho stran by byla ztráta času jak pro čtenáře, tak pro autora.
Hello world ! Segmentation fault (core dumped)
q66 avatar 23.3.2012 13:07 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Počítám se základní znalostí logiky programování, Cčkaři/C++/C#/Java mají výhodu, ale snažím se na tu znalost moc nespoléhat.
Jardík avatar 22.3.2012 14:38 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Odpovědět | Sbalit | Link | Blokovat | Admin
Já bych řekl, že D nepřináší zas tak nic zásadního, kvůli čemu by stálo za to opustit C++. Mám tam assert, static_assert, variadic templates, auto, lambda fce, range-based for, typed enums, mám tu utf8 string literáli, utf-16, utf32 (u8"", u"", U""), naprogramovat assert vyhazující výjimku je otázka několika sekund, ...
Věřím v jednoho Boha.
q66 avatar 22.3.2012 14:48 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Lambda funkce v C++ nemají automatickou typovou inferenci, closures v C++ nejsou polymorfické, templates v D a v C++ jsou co se týče použitelnosti úplně někde jinde, C++ nemá static if, což je při programování s templates dost zásadní, range-based for je jen alias k obyčejnýmu for, tudíž neumožňuje vlastní počet indexů (např. v D můžu udělat foreach(a, b, c, d, e, f; můj_objekt_definující_správnou_metodu)), auto nefunguje pro návratový hodnoty bez decltype jako v D (v D můžu prostě specifikovat návratový typ jako auto a vůbec se nestarat o nějaký decltype, prostě vracet co chci, kde chci)
q66 avatar 22.3.2012 14:57 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Mimochodem, dva logicky ekvivalentní kusy kódu v C++ a v D http://ideone.com/pLzNu , http://ideone.com/UgZlo
Bystroushaak avatar 22.3.2012 16:16 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Lol, ta koncovka u toho C++ příkladu .. http://ideone.com/UgZlo :D
q66 avatar 22.3.2012 16:21 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Vskutku zlo :)
Bystroushaak avatar 22.3.2012 18:06 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Luboš Doležel (Doli) avatar 22.3.2012 17:04 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Já mám pocit, že D představuje to, kam se C++ mohlo dostat, kdyby se na něm opravdu makalo. Standardizace C++ mi připomíná standardizaci OpenGL - trvá to dlouho a je to pak zklamání.
23.3.2012 19:49 Program
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ono spíš C++ zatěžuje zpětná kompatibilita. Ať už byly některé vlastnosti C++ špatné od začátku (pro flejmaře: jiné zase dobré), nebo jsou důsledkem kompatibility s C, či vůbec takový C přístup. C++ se dnes snaží "emulovat" chování vyspělejších jazyků, ale výsledek je hrozně neohrabaný.
26.3.2012 09:29 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Každý jazyk v okamžiku prvního standardu začne zastarávat.

C++ jako jazyk je určen pro případy, kdy maximální rychlost a minimální spotřeba zdrojů a plná kontrola nad programem je prioritou. Z toho vyplývá neohrabanost.

Je snadné implementovat high level featuru v prostředí, kde spotřeba paměti, rychlost kódu ani další atributy nejsou klíčové. U C++ se musí vše implementovat maximálně úsporně – a to kód zanáší.

Když vezmu, co štve v C++ mě, je to toto:

1) Rozlišování . a -> u přístupů. Kompilátor má dostatek kontextu, aby je rozlišil sám. Mohlo se ke všemu přistupovat tečkou a bylo by.

2) Integerové typy jsou příliš závislé na implementaci a to důsledně. Takže si nejste třeba jistí, zda standardní knihovna pro práci se soubory zvládne či nezvládne 64bitovou délku či poizici v souboru, protože je to long, a ten může být cokoli od 32 bitů nahoru.

3) Nerozlišování NULL a celočíselné nuly.

Ostatní věci, které se mi nelíbí v době vzniku C++ nemohly být známy, takže je neuvádím.

Hlavně by se D mělo snažit aby využilo možnost a znalosti o současnosti a vylepšilo co se dá. Zatím se mi zdá, že D se moc nepochlapilo. Škrtlo namespacy, škrtlo vícenásobnou dědičnost, šktlo podporu 16bitových platforem. A řada chování D je minimálně nedomyšlená.
oryctolagus avatar 26.3.2012 10:09 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
1) Tohle je náhodou docela šikovné u smart pointerů, iterátorů a podobných "obalujicích" typů... Bez -> by se muslo použít něco jako smartptr.get().fooBar() a to zavání Javou :-D

2) No to ano, to je problém... Výhodou je portabilita, nevýhodou je, že se to pak musí řešit stylem boost::stdint a podobné... Nicméně C99 a C++11 toto řeší tím, že tento přístup standardizují (viz), což si myslim, že je dobré...

3) Řeší C++11 - nullptr
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.
26.3.2012 10:17 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ad 1) Vymyslel by se jiný syntaktický cukr. :-) A nebo by se staly součástí jazyka přímo.

Ad 2) Pořád si nemohu pomoci, ale skutečně portabilní typy vyřešila geniálně Ada.

Ad 3) Neřeší, protože jakýkoli výraz, parametry metody, atd., která čeká pointer stále přijme celočíselnou nulu.
oryctolagus avatar 26.3.2012 10:45 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ad 3) Já myslím, že oni by to třeba i rádi změnili, ale to prostě nepůjde kvůli zpětné kompatibilitě...
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.
26.3.2012 18:28 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Taky si to myslím.
26.3.2012 18:53 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Třeba v GCC to bude varování, které půjde převést na chybu, stejně jako je teď používání Céčkových přetypování. Ale kvůli zpětné kompatibilitě samozřejmě bude možné použít i starý přístup.
q66 avatar 26.3.2012 15:10 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
"...Z toho vyplývá neohrabanost..."

proč tedy D co se týče neohrabanosti daleko lépe řešeno a přitom v některých případech výkonnostně C++ převyšuje?

"...plná kontrola nad programem je prioritou..."

v D mám nad programem stejnou kontrolu, jako v C++, možná ještě o něco vyšší (díky lepšímu metaprogrammingu, traits apod.)

"...spotřeba paměti, rychlost kódu ani další atributy nejsou klíčové..."

Jak už jsem zmínil, idiomatický D kód umí být stejně rychlý a paměťově náročný jako C++, přitom bezpečnější a kratší; pokud je potřeba opravdu minimální množství runtime kódu, vždycky je možné implementovat si vlastní runtime (např. bez exceptions apod.)

"...škrtlo namespacy..."

Protože byly zbytečné - systém pravých modulů je plně nahrazuje, kromě toho se D kompiluje asi 6x rychleji než C++ díky tomu, že nemá preprocesor.

"...škrtlo vícenásobnou dědičnost..."

Používat OO v prostředí, kde je potřeba vysoký výkon, je kvůli virtuálním metodám apod. blbost, tam kde není třeba vysoký výkon, multiple inheritance se dá vždy nahradit pomocí interfaces a mixinů.

"...škrtlo podporu 16bitových platforem..."

Má dnes smysl podporovat 16bitové platformy? Ne, nemá - hlavně u jazyka jako D, kde je pravděpodobnost použití na 16bitové platformě tak jedna ku tisíci.

"řada chování D je minimálně nedomyšlená"

Pár příkladů?
26.3.2012 17:15 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
„proč tedy D co se týče neohrabanosti daleko lépe řešeno a přitom v některých případech výkonnostně C++ převyšuje?“

Pokud jste ochoten se vsadit (zadarmo to dělat nebudu), tak Vám klidně na každý Váš D kód napíše C++ ekvivalent, který nebude pomalejší, než D.

Ono C++ se musí umět a zatím všechny důkazy o tom, že C++ je pomalejší než něco (obvykle Java, teď vidím inovaci D) – vznikly z toho, že testující neumí C++.

---

„v D mám nad programem stejnou kontrolu, jako v C++, možná ještě o něco vyšší (díky lepšímu metaprogrammingu, traits apod.)“

Sice nechápu jak metaprogramming, traits a další přispívají k lepší kontrole.

Nicméně C++ je jazyk dělaný na kontrolu každého možného aspektu výsledného kódu, tj. možnost ovlivnit vše co má vliv na výkon, efektivitu, spotřebu prostředků a další. A to je primární cíl a účel C++.

---

„Jak už jsem zmínil, idiomatický D kód umí být stejně rychlý a paměťově náročný jako C++, přitom bezpečnější a kratší; pokud je potřeba opravdu minimální množství runtime kódu, vždycky je možné implementovat si vlastní runtime (např. bez exceptions apod.)“

Viz moje odpověď ad 1)

---

„Protože byly zbytečné - systém pravých modulů je plně nahrazuje, kromě toho se D kompiluje asi 6x rychleji než C++ díky tomu, že nemá preprocesor.“

Samozřejmě, že je nepotřebuje – jako cokoli co D nemá. A pokud by to neplatilo platí předchozí věta. Protože co D nemá je nepotřebné. Jak jinak.

Jak rychle se program kompiluje mě vcelku nezajímá. Doby kdy na tom záleželo jsou v zásadě pryč. S inkrementální kompilací v C++ je vše co potřebuji do sekundy, když vyvíjím. Jestli se to urychlí na šestinu sekundy mi je vcelku opravdu fuk. A jestli je délka kompilace release verze minutu, nebo půl hodiny mi je jedno, tak ocením spíše max. optimalizaci.

---

„Používat OO v prostředí, kde je potřeba vysoký výkon, je kvůli virtuálním metodám apod. blbost, tam kde není třeba vysoký výkon, multiple inheritance se dá vždy nahradit pomocí interfaces a mixinů.“

Já vím, že D nedokáže jiné, než virtuální metody. I proto je dost diskutabilní použití D v té rychlosti a efektivitě, kterou tu předhazujete na začátku. Prostě v rámci rychlosti, kdybyste to chtěl rozjet na max. Vás D donutí nepoužívat objekty. A jste na tom z hlediska luxusu hůře než C++ a musíte programovat low level na rozdíl od C++.

Vícenásobná dědičnost není plně nahraditelná ani interfacy ani mixiny ani jejich kombinací.

---

„Má dnes smysl podporovat 16bitové platformy? Ne, nemá - hlavně u jazyka jako D, kde je pravděpodobnost použití na 16bitové platformě tak jedna ku tisíci.“

V době, kdy se houfně přechází na mobilní platformy, kdy použití embedded věcí se rozšiřuje jako rakovina – to smysl má. Ne všude je ARM a ne všude je to ekonomické.

C++ s tím nemá problém.

---

„Pár příkladů?“

Dal jsem jich dost v různých příspěvcích pod tímto článkem. Některé máte i o několik odstavců výše.
q66 avatar 26.3.2012 17:41 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
"Pokud jste ochoten se vsadit (zadarmo to dělat nebudu), tak Vám klidně na každý Váš D kód napíše C++ ekvivalent, který nebude pomalejší, než D."

Řekl jsem snad, že C++ je pomalejší? Řekl jsem, že D umí být stejně rychlé, a to je rozdíl.

"Samozřejmě, že je nepotřebuje – jako cokoli co D nemá. A pokud by to neplatilo platí předchozí věta. Protože co D nemá je nepotřebné. Jak jinak."

K tomuto vyvození jsi došel jde?

"Já vím, že D nedokáže jiné, než virtuální metody. I proto je dost diskutabilní použití D v té rychlosti a efektivitě, kterou tu předhazujete na začátku. Prostě v rámci rychlosti, kdybyste to chtěl rozjet na max. Vás D donutí nepoužívat objekty. A jste na tom z hlediska luxusu hůře než C++ a musíte programovat low level na rozdíl od C++."

Další blbost - D samozřejmě umí i nevirtuální metody (viz. "final", buď může být final celá třída, v tom případě nebudou žádné virtuální metody, nebo může být final jen samotná metoda)
26.3.2012 18:19 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
„Řekl jsem snad, že C++ je pomalejší? Řekl jsem, že D umí být stejně rychlé, a to je rozdíl.“

Alzheimer je sviňa, já Vás ocituji: “proč tedy D co se týče neohrabanosti daleko lépe řešeno a přitom v některých případech výkonnostně C++ převyšuje?“

---

„K tomuto vyvození jsi došel jde?“

K tomu, že Vy i jiní argumentujete, že „D to nemá, protože nepotřebuje“.

---

„Další blbost - D samozřejmě umí i nevirtuální metody (viz. "final", buď může být final celá třída, v tom případě nebudou žádné virtuální metody, nebo může být final jen samotná metoda)“

Aha, získal jsem v tom případě nový náhled na čistotu syntaxe programovacího jazyka. Nalepit final a zamezit tak potomkování jen proto, že potřebuji dosáhnout nevirtuální metodu. Ehm ehm, to čisté D.
q66 avatar 26.3.2012 18:39 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Nevidím tu problém - pokud má být veřejná metoda nevirtuální, udělá se final a nepřepisuje se (to neplatí pro private metody, které se mohou přepisovat, i když jsou final, tam se to hodí); jinak jsou metody virtuální s tím, že D kompilátor zná hierarchii třídy, tudíž má prostor k další optimalizaci.
26.3.2012 18:23 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Řekl jsem snad, že C++ je pomalejší? Řekl jsem, že D umí být stejně rychlé, a to je rozdíl.
proč tedy D co se týče neohrabanosti daleko lépe řešeno a přitom v některých případech výkonnostně C++ převyšuje?
q66 avatar 26.3.2012 18:30 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Všimni si toho "některých".
26.3.2012 18:54 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Toho jsem si právě všiml, a tak by mě zajímalo: kterých?
q66 avatar 26.3.2012 19:02 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Nejedná se o jazyk samotný (tam záleží hlavně na kompilátoru apod.) ale třeba: 1) D má výkonný CTFE; spousta věcí se dá zpracovat mimo runtime; C++ sice nějakou podporu taky má, ale je to omezené. 2) Standardní knihovna - hlavně při práci se stringy; slices mohou být dost efektivní. 3) Paralelizace - D má paralelní cykly (viz např. http://dlang.org/phobos/std_parallelism.html#parallel ). Ono by asi toto vše šlo naprogramovat i v C++ (pokud nejsou potřeba např. traits, nemyslím type traits, ale static reflection, které C++ do velké míry nemá), ale nebylo by to zdaleka tak jednoduché a praktické.
q66 avatar 26.3.2012 17:42 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
"Dal jsem jich dost v různých příspěvcích pod tímto článkem. Některé máte i o několik odstavců výše."

Nic konkrétního tu nevidím. Jen samé plky o ničem. Že ty budeš z té "staré" generace českých programátorů, co si myslí, že ví všechno nejlíp?
Josef Kufner avatar 26.3.2012 18:14 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Vícenásobná dědičnost není plně nahraditelná ani interfacy ani mixiny ani jejich kombinací.
Například kdy?
Hello world ! Segmentation fault (core dumped)
26.3.2012 18:33 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Třeba v okamžiku, kdy potřebujete podědit více tříd s implementacemi metod v předcích a zároveň potřebujete aby nová třída byla přetypovatelná na kteréhokoli předka, tedy byla typem všech předků.

q66 avatar 26.3.2012 18:45 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
A něco konkrétního by nebylo? :P
q66 avatar 26.3.2012 18:41 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Mimochodem, pouze poznámka; odkdy je ne-OO kód vždy low-level? Procedurální kód může být též high level, v D se ještě přidává funkcionální paradigma.
26.3.2012 18:35 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
v D mám nad programem stejnou kontrolu, jako v C++, možná ještě o něco vyšší (díky lepšímu metaprogrammingu, traits apod.)
Tak to chci vidět, jak naimplementujete v D třístavovou logiku, kterou používá třeba SQL, pro objekt, který nemá defaultní konstruktor, pokud teda nechcete všechno cpát na haldu jak Java. V C++ buď sáhnete po Boost.Optional nebo si něco podobného napíšete za pár minut.
q66 avatar 26.3.2012 18:42 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
D umožňuje dát třídy i na stack; pomocí klíčového slova "scope".
26.3.2012 18:46 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
To vím, ale to vám pro implementaci té třístavové logiky nepomůže
q66 avatar 26.3.2012 18:52 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Lepší je se zeptat - co tomu oproti C++ brání? Řekl bych de facto nic. Co se týče boost::optional; nevidím jediný důvod, proč by to samé nešlo implementovat i v D; resp. D už to má, v podobě Nullable - http://dlang.org/phobos/std_typecons.html#Nullable
27.3.2012 12:39 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Rozdíl mezi Nullable a Boost.Optional je poměrně zásadní: Nullable je u tříd jenom takový větší pointer, zatímco Boost.Optional ukládá samotnou instanci do prostoru vyhrazeného uvnitř sebe. Pokud např. použijete jiné alokátory (třeba sdílenou paměť nebo lock-free per-thread buffery), Boost.Optional stačí uložit tam a uloží tam rovnou i svůj objekt, zatímco objekt v Nullable budete muset složitě honit, aby se do té vyhrazené paměti taky dostal.
q66 avatar 27.3.2012 14:04 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
To jde v D také celkem snadno implementovat. Emplace a je to.
oryctolagus avatar 25.3.2012 00:31 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Já mám pocit, že D představuje to, kam se C++ mohlo dostat, kdyby se na něm opravdu makalo. Standardizace C++ mi připomíná standardizaci OpenGL - trvá to dlouho a je to pak zklamání.
Souhlasím, nicméně u toho D bych zas viděl jako potenciální problém velký "rozmach" tohoto jazyka.

Co jsem tak koukal, oproti C++ má D brutální množství speciálních výrazů, hlavně teda klíčových slov, případně různých speciálních položek objektů a jejich členů. Například množství klíčových slov pro parametr funkce. Nebo všechny ty Object.op* při operator overloadingu. A tak dále. Přijde mi hodně náročný tohle všechno zvládnout.

Autoři D v mnoha ohledech kritzují C++ pro přílišnou složitost, nerozumím tedy tomu, proč, ač na jedné straně složitost snižují, na straně druhé sami přidávají hafo dosti složitých featur, u kterých není jisté, jestli je někdo někdy vůbec bude používat.
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.
Bystroushaak avatar 25.3.2012 12:22 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
No, budu doufat že jsem nadprůměrně inteligentní, protože já s těmi featurami problém nemám :D

Autoři jazyka hodně dají na průkaznost toho, co program bude opravdu dělat, k čemuž se právě různé rozšířené parametry používají. Trochu si tím tak škrtají o funkcionální jazyky (pokud se tedy ošklivě nepletu, začal jsem se jimi zabývat relativně nedávno).
q66 avatar 25.3.2012 17:46 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ano, má dost klíčových slov apod. ale dohromady to všechno sedí, nic se nekryje jako v C++ a hlavně je gramatika jazyka nezávislá na kontextu, takže se dá parsovat bez přítomnosti celého frontendu, což věci dost zjednodušuje.

Co se týče těch featur - většinou je používám, a problém s nimi nemám. Všechno je dobře integrované.
oryctolagus avatar 25.3.2012 18:06 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ok... no dost možná to je tím, že ten jazyk zatím málo znám.

Jinak další věc, která by mě zajímala, je stabilita standardu. U C++ je tahle stabilita snad příliš silná, u D jsem trochu na rozpacích - rozdíl mezi D1 a D2 byl značný. Dá se očekávat za pár let další taková změna, nebo to byla jen porodní bolest jazyka?
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.
q66 avatar 25.3.2012 18:28 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Mluvil jsem o tomto samém s jedním z autorů (Andrei Alexandrescu) a říkal, že se D3 neplánuje. Co se týče stability standardu, ještě není stabilní, nicméně aktuální featury už by se neměly měnit, možná něco přibude; pracuje se na stabilizaci. Standardní knihovna stabilní ještě není (přibude nový I/O modul apod.). Nicméně, pokud se něco ve standardní knihovně nahradí, stará se označí jako "deprecated" a autoři programů mají několik měsíců čas si svůj program zaktualizovat.

Btw, co se týče D1 vs D2; ten rozdíl není tak markantní, jak se říká. Sice toho hodně přibylo, ale D2 stále obsahuje de facto celý subset D1 (kromě některých věcí, jako že v D2 jsou string literály vždycky imutabilní, změny v template systému, tranzitivní const apod.). Zmigrovat kód z D1 na D2 není až takový problém, hlavně se jedná o přepsání některých výrazů.
25.3.2012 18:35 Martin Petr | Třinec/Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
... pokud se něco ve standardní knihovně nahradí, stará se označí jako "deprecated" a autoři programů mají několik měsíců čas si svůj program zaktualizovat.
Tohle bohužel v žádném případě není řešení problému.

Zpětná kompatibilita.

Zpětná kompatibilita.

Zpětná kompatibilita.

Jazyk, který ji nerespektuje, nemá nejmenší šanci se pro sadit jako něco více než jazyk pro hobby projekty.

I teď po letech se smutkem sleduju, jak se ještě stále nevyřešilo "schizma" mezi Python2 a Python3 částí pythoního světa. Ten jazyk mám opravdu moc rád, ale vždycky, když v něm chci něco začít něco psát, tak mě tahle jeho bipolarita odrazuje.
q66 avatar 25.3.2012 18:40 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ale zpětná kompatibilita je featura stabilního jazyka. Vzhledem k tomu, že nejméně standardní knihovna D2 není ještě stabilní verzí, tak se dělají změny. :) Až bude vše API-stabilní (počítám, že max do roka tomu tak bude) tak může být i zpětná kompatibilita.
26.3.2012 09:35 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Python 3 by mohl udělat jednoduchou věc: Ohlásit že od teď až navždy je zpětná kompatibilita svatá.
26.3.2012 10:15 Martin Petr | Třinec/Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
To bych uvítal, i když to nevidím reálně.

Ovšem to nemění nic na faktu, že existuje obrovské množství kódu (logicky mnohem větší množství kódu, než které bylo napsáno od vydání Pythonu 3), do kterého bylo investováno nehorázné množství času a peněz. Co s ním, až začne stará větev interpreteru zaostávat? U hobby projektů není problém, ve firmách už to tak růžově nevidím... Pythonu by to mohlo v očích managorů a dalších docela dost ublížit, protože kdo ví, co se ještě s Pythonem může udát v budoucnosti. A ani bych se jim jim upřímně řečeno nedivil.
Josef Kufner avatar 26.3.2012 11:41 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ono je lepší, když se zpětná kompatibilita drží jen vrámci major verze (tedy 3.inf je zpětně kompatibilní s 3.0), protože jinak není jak odstranit zastaralé či chybně navržené části jazyka, jak je vidět u C++ a pak to vypadá jak hovniválova kulička.

Mezi major verzemi pak stačí jen dobře popsat nekompatibilní změny, umožnit instalaci obou verzí současně a třeba i nechat ve zdrojáku tuhle verzi zapsat, aby překladač mohl včas zakřičet (ať už warning nebo error).
Hello world ! Segmentation fault (core dumped)
oryctolagus avatar 26.3.2012 16:52 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Donbře, jenže tohle měli vývojáři Pythonu ohlásit dřív, než bylo pozdě. Kdyby prostě už mnohem dířv ohlásili, že kompatibilita bude udržována jen v rámci major verzí, mohly se na to vývojáři i distribuce lépe přípravit a nebyl by to takovej šílenej zmatek jako to je. Mohl se od začátku zavést nějaký stabilní mechanismus, jakým skript řekne, kterou chce verzi a informuje se o tom, co je v systému isntalování a nějak na to může reagovat. Afaik takhle to je v .NET a není to blbej nápad.

Přijde mi, že D se potenciálně řítí do přesně stejných problémů. Jestliže dnes nemají zcela jasno v tom, jestli za 5 let náhodou nepřijdou s D3 a porušením kompatibility, tak je to dost špatný pro nasazení jazyka.
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.
26.3.2012 17:38 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
To není. Neznám jediný jazyk, který by se nekompatibilně měnil mezi major verzemi a přežil by střednědobý horizont.

Ono totiž v jazyce, který nezaručuje nekompatibilní změny se seriózně programovat nedá.

Každé změna syntaxe jazyka znamená, že Vás léty odladěný kód je opět v alfaverzi. A můžete znovu testovat, ladit, zkoušet a je velké riziko skrytých chyb.

Takže jazyky, které nezaručují zpětnou kompatibilitu se uvaří na tom, že mnoho projektů drží jednu, dvě i několik major verzí pozadu. A bytí a nebytí takového programovacího jazyka záleží na tom, kolik major verzí pozadu bude schopen a jak dlouho udržovat.

Přežijí dlouhodobě jen ty jazyky, které zpětnou kompatibilitu zaručují.

Zkuste si představit třeba v unixech, že se nekompatibilně změní shell. Najednou se prostě změní syntaxe sh a bude to fungovat jinak. Nebo že programovací jazyk C se nekompatibilně změní a ať si Linus znovu přepisuje těch pár desítek miliónů řádek kernelu, ať si je znovu otestuje, hledá chyby. Zastaví se na půl roku veškerá práce na linux kernelu a bude se dělat jen to. Jakmile to Céčko udělá podruhé, první co Linux udělá je, že najde jiný programovací jazyk, který tyhle excesy nebude dělat.

Řada projektů má milióny řádek. Pro takové projekty nemůžete nekompatibilně měnit jazyk. A pokud ano, je jisté, že jazyk má utrum. Ty náklady mu nikdo nedaruje.

Chcete-li udělat nekompatibilní změny, je lépe založit nový jazyk. Ovšem je třeba ho do detailů promyslet a není to sranda. Mnoho jazyků trpí tím, že se autor uchrtí na jeden aspekt jazyka a ostatní stojí za starou bačkoru.
Josef Kufner avatar 26.3.2012 18:17 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
To není. Neznám jediný jazyk, který by se nekompatibilně měnil mezi major verzemi a přežil by střednědobý horizont.
PHP.
Hello world ! Segmentation fault (core dumped)
26.3.2012 18:23 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Od roku 1997, což je možné považovat za začátek doby kdy se PHP/FI přestalo prezentovat jako sada separátních funkcí a přepsalo se do programovacího jazyka není zase tak dávno.

Jazyk D je jen o 2 roky mladší.
Josef Kufner avatar 26.3.2012 18:59 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Těch 15 let ale není nijak málo, tedy spíš to je 17, protože PHP2 bylo zveřejněno už v roce 1995. Vlastně je to skoro celá historie webu (první server byl v roce 1990, W3C vzniklo v roce 1993). A v současné době se PHP opravdu masově používá, narozdíl od D.

Btw, C++ vzniklo v roce 1983 a první norma až v roce 1998. Vezmeme-li v úvahu, že tehdy se spolu s tím teprve vynalézalo prakticky použitelné objektově orientované programovaní (první byla Simula v 1967 a Smalltalk je ze 70. let, ale ani jeden z nich se moc nechytnul), tak můžem těch 10 let navíc, co C++ má, v klidu zanedbat, neboť tvůrci novějších jazyků už mají k dobru návod a hromadu zkušeností.
Hello world ! Segmentation fault (core dumped)
26.3.2012 09:01 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
„hlavně je gramatika jazyka nezávislá na kontextu“

Jak by řekli v Big Bang Theory: Is that relevant factor?

Mě osobně vůbec nezajímá, jestli kompilátoru parsování jazyka dá víc práce.

Selský rozum mi říká, že jazyk je primárně pro programátory a ne pro ulehčování práce tvůrcům kompilátorů.

Ostatně stejně vzniknul Pascal – Wirth taky navrhoval jak je príma parsování. A pak člověk přemýšlel kde dát středník a kde ne, protože to v duchu taky musel pársovat za kompilátor.

Pokud nějaký jazyk je propagován tím, že se dobře parsuje, dám si k němu automaticky mínus, protože to znamená nedostatek argumentů pro jazyk. A pokud je před to použito ještě slovo „hlavně se to dobře parsuje“, pak palec dolů a dál se tím nezabývám.

To jak bych se choval normálně. Vždy se rozhoduji pouze podle toho, co to pro mě jako programátora znamená, to, jestli se bude parser jazyka dělat tak či onak je mimo moje zorné pole a nezajímá mě to. Navíc jazyk používá milióny programátorů ale jen pár lidí bude psát parser.

Mimochodem, D je asi první jazyk, který nemá nic jako rozdělení řádky typu \

Zato si nezapomněli přidat, že znak 0x00, nebo znak 0x1A, kdekoli se vyskytne ve zdrojáku, ukončí parsing. Opravdu velmi čistý parsing. Skvělý. (Sarkasmus)

Nicméně D znám, a před několika lety jsem ho testoval, zda se nevybodnout na C++ a nepřejít. A velmi rychle mi došlo, že D je jako když pejsek s kočičkou vařili dort. Jsou tam dobré věci, ale nalepené bez rozmyslu. C a C++ jsou daleko konzistentnější jazyky a logičtěji postavené. Just my opinion.

Upřímně, já kdybych překopával C++, přidal bych do něj prvky Ady z hlediska typů a high level věci bych opsal z nějakého high level jazyka. Leccos by dopadlo podobně jako v D, ale zachoval bych vícenásobnou dědičnost.

Navíc D je stále v procesu, že se přeorává, možná někdy v budoucnu bude jasná norma. Pak teprve bude čas na hodnocení. Dokud se stále uvažuje, že nějaké .sort zmizí, je to stále alfa verze jazyka.

Je škoda, že D nevyužil možnosti oproti C++ lépe zpracovat tradiční typy snad kromě fixnutí na konkrétní velikosti.

Vůbec mám pocit, že se řešilo pouze high level.
Josef Kufner avatar 26.3.2012 11:45 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Zato si nezapomněli přidat, že znak 0x00, nebo znak 0x1A, kdekoli se vyskytne ve zdrojáku, ukončí parsing. Opravdu velmi čistý parsing. Skvělý. (Sarkasmus)
Tohle má PHP taky, akorát lepší: __halt_compiler().
Hello world ! Segmentation fault (core dumped)
26.3.2012 17:42 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
A assembler má často slovo end, za kterým se vše ignoruje.

V TeXu máte \bye.

Stejně tak jako Pascal je vše mezi begin a end a co je za tím se ignoruje.

Ovšem novátorské je použití netisknutelných znaků.

A navíc je to okořeněno tím, že třeba znak 0x00 na začátku zdrojáku být může, to neznamená nutně konec zdrojáku. Tam to může být třeba BOM znak, který to akceptuje.

Fakt vrchol čistoty a promyšlenosti.
Bystroushaak avatar 26.3.2012 14:38 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Jak by řekli v Big Bang Theory: Is that relevant factor?
Pro programátora to přeci také znamená usnadnění. Když porovnám šablony v C++ a v D, je to obrovský rozdíl co se týče snadnosti čtení.
Jsou tam dobré věci, ale nalepené bez rozmyslu.
Ne. Ve skutečnosti tam nic takového není a všechno má svůj smysl. V konferencích se vedou diskuze o všem, co se přidává/mění a vše musí být odůvodněné podstatnými argumenty.

Když jsem četl knihu od Andreie Alexandrescu, měl jsem silný pocit osvícení, jelikož vysvětluje prakticky všechno, kde se to vzalo a proč. D tak na mě naopak působí jako úžasně konzistentní jazyk, kde nic není jen tak pro dobrý pocit a nad vším se přemýšlelo.
Nicméně D znám, a před několika lety jsem ho testoval, zda se nevybodnout na C++ a nepřejít.
D před pár lety a D dnes je docela podstatný rozdíl.
Mimochodem, D je asi první jazyk, který nemá nic jako rozdělení řádky typu \
Jak jsem to četl, napadlo mě že je to fakt nevýhoda, ale když jsem se pak snažil vymyslet nějaký příklad kde je to nutné použít, tak jsem na nic nepřišel, takže se rád nechám osvítit.
26.3.2012 17:55 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
„Pro programátora to přeci také znamená usnadnění. Když porovnám šablony v C++ a v D, je to obrovský rozdíl co se týče snadnosti čtení.“

Ale řeč byla o způsobu parsování.

---

„Ne. Ve skutečnosti tam nic takového není a všechno má svůj smysl. V konferencích se vedou diskuze o všem, co se přidává/mění a vše musí být odůvodněné podstatnými argumenty.“

To ovšem chce úvodní parametr zvaný „jaké budou priority D“. Ono totiž nic není dobře ani špatně, je to jenom jakou zvolíte matematickou optimalizační funkci.

Proto mě překvapuje neustálé šití do C++, protože priritou D rozhodně nemohlo být nahrazení C++, protože D na to nemá parametry ani potřebné featury. Tudíž předpokládám, že prioritou D je něco jiného.

Pro řadu lidí může být D pěkný jazyk, a nebo se jim může strašně líbit – což beru. Ale pokud se D bude prezentovat srovnáváním s C++, tak to prohraje. Ne proto, že by byl špatný, ale protože se instaluje do pozice „toho druhého jazyka“ a jak známo, tahle pozice se strašně špatně obhajuje. Pokud bude D maličko lepší, než C++ hypoteticky, tak to nestojí nikomu za to zabývat se D. Teprve kdyby něčím doslova omráčil zhruba stejným rozdílem jako byl rozdíl mezi C a C++ by D zvítězil.

Myslím, že srovnáváním s C++ si jazyk škodí a možná i proto bude mít problém.

---

„Když jsem četl knihu od Andreie Alexandrescu, měl jsem silný pocit osvícení, jelikož vysvětluje prakticky všechno, kde se to vzalo a proč. D tak na mě naopak působí jako úžasně konzistentní jazyk, kde nic není jen tak pro dobrý pocit a nad vším se přemýšlelo.“

Alexandrescu psal i pro C++. Jeho knihy pro mě byly přínosné, ale jako jeden ze směrů.

---

„D před pár lety a D dnes je docela podstatný rozdíl.“

Principiálně nijak výrazný.

---

„Jak jsem to četl, napadlo mě že je to fakt nevýhoda, ale když jsem se pak snažil vymyslet nějaký příklad kde je to nutné použít, tak jsem na nic nepřišel, takže se rád nechám osvítit.“

Když na tom trváte, já Vám to tedy řeknu: Na to abyste jeden řádek mohl rozdělit do více řádků. :-)
Bystroushaak avatar 26.3.2012 18:48 Bystroushaak | skóre: 32 | blog: Bystroushaakův blog | Praha
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Když na tom trváte, já Vám to tedy řeknu: Na to abyste jeden řádek mohl rozdělit do více řádků. :-)
To mě samozřejmě také napadlo, ale jaký je konkrétní příklad?

String můžu rozdělit následovně:
string a = "dloooouhy string......................"
           "pokracovani, ktere se mi neveslo na predchozi radek";
Ostatní výrazy lze oddělit prostě pokračováním na dalším řádku.

Možná u názvu superdlouhé funkce? Ale to by byla zase úžasná prasárna. Tak fakt nevím.
oryctolagus avatar 26.3.2012 19:27 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Afaik v C++ to je dobrý maximálně tak na definici víceřádkových maker, což už je imho samo o sobě prasárna...
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.
27.3.2012 13:47 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Prasárna to být nemusí, běžně se dělá třeba:
#define METHOD(params) \
    doSomething(params, __FILE__, __LINE__)
oryctolagus avatar 27.3.2012 14:19 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
No mně se to nelíbí, ale tak ono to je subjektivní...

Mimochodem, hodnota makra __FILE__ je na kompilátoru, není standardizována (může tam být cesta absolutní, relativní,... je to dost nahouby makro)... Pokud člověk používá například cmake, je lepší něco jako
foreach(i ${my_sources})
  set_property(SOURCE ${i} PROPERTY COMPILE_DEFINITIONS MY_FILE="${i}")
endforeach(i)
a v ostatních systémech obdobně... To jen tak naokraj.
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.
q66 avatar 27.3.2012 14:24 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
btw, __FILE__, __LINE___, __DATE__ a __TIME__ jsou v D standardizovány :) Je to dobrý na debugování.
27.3.2012 16:28 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
__FILE__ obsahuje cestu, pomocí které kompilátor daný soubor našel, takže pokud na příkazové řádce dostal relativní cestu, je relativní.

Ta property nefunguje správně, protože hodnota __FILE__ odpovídá cestě k aktuálnímu souboru (který může být includovaný).
q66 avatar 26.3.2012 15:19 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
"Jak by řekli v Big Bang Theory: Is that relevant factor?"

Samozřejmě že je - závislost gramatiky na kontextu je z hlediska čistoty jazyka špatně, ale hlavně to dost ztěžuje interoperabilitu s tím jazykem z jiných jazyků - je v podstatě nemožné bez celého frontendu C++ kompilátoru podporovat C++ z jiného jazyka, oproti C. Kromě gramatiky závislé na kontextu je toto dáno špatnou specifikací C++ ABI, kde není definován např. name mangling, takže každý vendor si toto dělá jinak. Kromě toho více parsování == pomalejší kompilace.

Ta analogie s Pascalem je naprosto irelevantní - D je syntakticky daleko čistší jazyk než C++ a běžnému uživateli dává daleko více smysl. Jak už dole Bystroushaak zmínil, např. při template metaprogrammingu, což je z velké části dáno i jednoznačně definovanou syntaxí.

"Mimochodem, D je asi první jazyk, který nemá nic jako rozdělení řádky typu \"

Jediné místo, kde se tohle v C/C++ hodilo, jsou makra preprocesoru. V D je to naprosto zbytečné.

"Nicméně D znám, a před několika lety jsem ho testoval, zda se nevybodnout na C++ a nepřejít. A velmi rychle mi došlo, že D je jako když pejsek s kočičkou vařili dort. Jsou tam dobré věci, ale nalepené bez rozmyslu. C a C++ jsou daleko konzistentnější jazyky a logičtěji postavené. Just my opinion."

Aha, před pár lety. Tudíž opravdu aktuální a relevantní informace, že?

"Navíc D je stále v procesu, že se přeorává, možná někdy v budoucnu bude jasná norma. Pak teprve bude čas na hodnocení. Dokud se stále uvažuje, že nějaké .sort zmizí, je to stále alfa verze jazyka."

Nepřekopává se - jazyk je de facto daný v TDPL (ještě se později přidala podpora SIMD a krátké syntaxe lambda funkcí, ale to jsou jen přídavky a nerozbíjí kompatibilitu se starým kódem). Co se týče .sort, to už je deprecated, a má dávno náhradu v knihovně - je tam ZATÍM pro kompatibilitu se starším kódem.

"Vůbec mám pocit, že se řešilo pouze high level."

D je primárně high level jazyk, ale umožňuje systémové programování stejně jako C - existuje kompletní kernel napsaný v D, jen si napsali vlastní minimální runtime.
26.3.2012 18:13 Miloslav Ponkrác
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
„Samozřejmě že je - závislost gramatiky na kontextu je z hlediska čistoty jazyka špatně“

Ale s prominutím, mně je nějaký hypotetická čistota u kloaky. Bez urážky. Tím to nemyslím zle.

Mně zajímá jediné: Je jazyk praktický? Je jazyk udržovatelný? Má standard a záruky kompatibility do budoucna? Jaké jsou pro něho nástroje?

---

„ale hlavně to dost ztěžuje interoperabilitu s tím jazykem z jiných jazyků - je v podstatě nemožné bez celého frontendu C++ kompilátoru podporovat C++ z jiného jazyka, oproti C.“

To je naprosto správně. Protože podporovat jeden jazyk z jiného znamená ten první zmrvit a očesat a zjednodušit.

---

„Kromě gramatiky závislé na kontextu je toto dáno špatnou specifikací C++ ABI, kde není definován např. name mangling, takže každý vendor si toto dělá jinak. Kromě toho více parsování == pomalejší kompilace.“

Nedefinování C++ ABI = možnost efektivnější kompilace a hledání cesty k efektivnější implementaci do budoucna.

Rychlost kompilace není u C++ ani tak daná syntaxí jazyka, protože parsing je zlomeček toho co kompilátor dělá. Kompilaci spíše zdržují includy, a to díky diskovým přístupům, ale to není věcí toho zda je gramatika závislá na kontextu.

---

„Ta analogie s Pascalem je naprosto irelevantní - D je syntakticky daleko čistší jazyk než C++ a běžnému uživateli dává daleko více smysl.“

Kdybych byl jedovatý, řekl bych, že běžný uživatel moc toho v C++ ani D nenaprogramuje.

Já souhlasím, že C++ má nectnosti, sem tam špinavou syntaxi. Není dokonalé.

Stejně tak jako bude D těsná kamizola, až se standardizuje a po pár letech si autoři začnou rvát vlasy, proč některé featury neudělali maličko jinak.

Ale znovu. Nečistou syntaxi bych kritizoval třeba u Perlu, kde ta prasečina se opravdu blíží write only kódu. U normálně udržovatelné syntaxe běžných jazyků to není nic moc co by mě zajímalo.
26.3.2012 18:44 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Kompilaci spíše zdržují includy, a to díky diskovým přístupům, ale to není věcí toho zda je gramatika závislá na kontextu.
A ty řeší precompiled headers, což je možné právě díky té neexistenci standardizovaného ABI.
26.3.2012 18:40 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
D je syntakticky daleko čistší jazyk než C++
No zrovna Déčkové operátory jsou zářný příklad, jak se to dělat nemá.
Jak už dole Bystroushaak zmínil, např. při template metaprogrammingu, což je z velké části dáno i jednoznačně definovanou syntaxí.
V C++ mají šablony taky jednoznačně danou syntaxi ;-) A míchání parametrů šablon a funkcí v definicích bych nazval všelijak, jen ne přehledné.
Josef Kufner avatar 26.3.2012 19:07 Josef Kufner | skóre: 67
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Ono když se podíváš na jakékoliv složitější použití šablon v C++, tak to má do přehledného daleko. Dokumentace k Boostu obsahuje "pěkných" ukázek hromadu.
Hello world ! Segmentation fault (core dumped)
27.3.2012 12:44 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
To nevyvracím, ale syntaxe Déčka to teda moc nevylepšila, nehledě na to, že spoustu dost podstatných věcí neumožňuje, jako třeba specializaci jinde, než je definice (což je potřeba pro šablonovanou serializaci).
q66 avatar 27.3.2012 14:09 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Samozřejmě že vylepšila; některé věci se dají v D zapsat v polovině kódu v porovnání s C++, syntaxe je čistší a není dvojznačná. Kromě toho, jakákoliv C++ template se dá přepsat v D. Myslím, že Andrei Alexandrescu je jeden z lidí, o kterém se dá říct, že C++ templates opravdu rozumí a zná jejich nedostatky, a ty byly v D opraveny.
27.3.2012 16:33 Sten
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
No zrovna používání kulatých závorek pro parametry šablon i funkcí IMO dvojznačné je (samozřejmě ne pro kompilátor, ale to není ani v C++).

Specializace v jiném souboru, než je definice, v D na rozdíl od C++ nejde. Podle mě je to bug, podle vývojářů D je to feature.
q66 avatar 27.3.2012 16:38 q66 | skóre: 32 | blog: Q's CZ devblog
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery

Od C++11 lze v C++ zapsat if (x<a<b>>>y<c<d>>) .. to je podle mě dvojznačné. Kulaté závorky jsou OK. Co se týče specializace - vždy se to dá udělat, i když trochu jinak. Vzhledem k tomu, že templates jsou založené na parosvání textu, je to v kombinaci s moduly jasné, že to nejde stejně, jako v C++. Ale věci, jako template mixins apod., tomu dost pomáhají.

oryctolagus avatar 24.3.2012 23:58 oryctolagus | skóre: 29 | blog: Untitled
Rozbalit Rozbalit vše Re: Programování v jazyce D (4): Funkce a delegáty – pokračování, podmínky, cykly, pole, pointery
Odpovědět | Sbalit | Link | Blokovat | Admin
s/ke vždy na stacku/je vždy na stacku
Existuje 10 druhů lidí: Ti, co nerozumí binární soustavě, ti, co ano, a ti, kteří znají i balancovanou ternární.

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.