Vlákno názorů k článku Programovací jazyk C3: podmínky, rozvětvení a programové smyčky od atarist - s tím **nextcase** to tedy neni zadna vyhra....

  • Článek je starý, nové názory již nelze přidávat.
  • 30. 9. 2025 12:56

    atarist

    s tím **nextcase** to tedy neni zadna vyhra. Jako asi chapu, ze ceckovej break je asi vic error-prone. Ale mozna by tedy uz bylo lepsi doplnit do case nejake uzitecne patterny, jako | (or) nebo .. (rozsah). IMHO by to jazyk posunulo lepsim smerem (tady k Rustu ;)))

  • 30. 9. 2025 13:19

    radekm
    Stříbrný podporovatel

    Or je implicitní, když za case není žádný kód. Viz příklad z článku

    switch (x) {
          case 0:
              io::printfn("%d is zero", x);
          case 1:
          case 3:
          case 5:
          case 7:
          case 9:
              io::printfn("%d is odd number", x);
          case 2:
          case 4:
          case 6:
          case 8:
          case 10:
              io::printfn("%d is even number", x);
          default:
              io::printfn("I don't know what to say about %d", x);
    }

    nextcase řeší situaci, kterou AFAIK Rust vůbec neumí. Standardně skáče na další case, ale může skočit i někam jinam (viz case 1, který skočí na case 0 nahoru):

    fn void duff(int* to, int* from, int count)
    {
        int n = (count + 7) / 8;
        switch (count % 8)
        {
            case 0: *to++ = *from++; nextcase;
            case 7: *to++ = *from++; nextcase;
            case 6: *to++ = *from++; nextcase;
            case 5: *to++ = *from++; nextcase;
            case 4: *to++ = *from++; nextcase;
            case 3: *to++ = *from++; nextcase;
            case 2: *to++ = *from++; nextcase;
            case 1: *to++ = *from++; if (--n > 0) nextcase 0;
        }
    }

    30. 9. 2025, 13:20 editováno autorem komentáře

  • 30. 9. 2025 16:36

    Pavel Tišnovský
    Zlatý podporovatel

    no nějaký sofistikovanější pattern matching jako má Rust, v C3 není. Tady se asi naráží na limity toho, co v jazyku typu C3 ("lepší C") očekávat a kde už je lepší se poohlédnout po těžší váze :/

  • 30. 9. 2025 17:18

    BoneFlute

    V Rustu je takový skvělý pattern:


    match get_status_by(args) {
    Status::Success => println!("suc­cess"),
    Status::Fail(e) => println!("error {}", e),
    }

    Strašně moc jsem to "potřeboval" v C#, který toto neumí. No, nějak jsem to přes třídu, tovární metody a vnořený enum zpáchal. A trochu jsem se k tomu Rustímu kódu přiblížil.

    Chci tím říct, že ty sofistikovanější patterny, které by se nám ve switchi líbily stojí na schopnostech práce s typy, mimo jiné. Není to jen o konstrukci, ale i o tom, jak dobře kompilátor rozumí kódu.

  • 30. 9. 2025 22:38

    radekm
    Stříbrný podporovatel

    > Chci tím říct, že ty sofistikovanější patterny, které by se nám ve switchi líbily stojí na schopnostech práce s typy, mimo jiné.

    Přijde mi, že zrovna C# má pattern matching schopnější než řada funkcionálních jazyků. Skoro mi to přijde až zvrhlé - jde napsat třeba tohle:

    vehicle switch
    {
        Car {Passengers: 0}        => 2.00m + 0.50m,
        Car {Passengers: 1}        => 2.0m,
        Car {Passengers: 2}        => 2.0m - 0.50m,
        Car                        => 2.00m - 1.0m,
    
        Taxi {Fares: 0}  => 3.50m + 1.00m,
        Taxi {Fares: 1}  => 3.50m,
        Taxi {Fares: 2}  => 3.50m - 0.50m,
        Taxi             => 3.50m - 1.00m,
    
        Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,
        Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
        Bus => 5.00m,
    
        DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,
        DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
        DeliveryTruck => 10.00m,
    
        { }     => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle)),
        null    => throw new ArgumentNullException(nameof(vehicle))
    };

    Viz Tutorial: Use pattern matching to build type-driven and data-driven algorithms.

  • 30. 9. 2025 22:59

    radekm
    Stříbrný podporovatel

    > Tady se asi naráží na limity toho, co v jazyku typu C3 ("lepší C") očekávat

    Technicky by to nemusel být problém. Ale někteří autoři těchto nízkoúrovňových jazyků považují pattern matching za zbytečnost a discriminated uniony za anti-pattern z hlediska výkonu a využití paměti.

    Třeba Odin má IMO lepší discriminated uniony než třeba F#. Jejich výhodou je, že typ slouží jako discriminator. Takže stačí psát:

    Value :: union {
        bool,
        i32,
        f32,
        string,
    }
    
    value: Value = ...
    switch v in value {
    case string:
        ...
    case bool:
        ...
    case i32, f32:
        ...
    case:
        // Default case
        // In this case, it is `nil`
    }

    Ale pattern matching Odin také nemá.