Egy új programozási nyelv - esetelágazás
2011-07-11T10:56:43+02:00
2011-08-01T08:01:26+02:00
2022-07-18T21:15:24+02:00
  • Lassan elkészül a teljes leírás! Itt megnézhető a WeightScript Interpreter: www.w8.hu
    Mutasd a teljes hozzászólást!
  • Jelen esetben az előző példa még csak így működik:

    Select Case i Case 1, 2, 3 task123() End Select

    ill. így:

    Select Case "Alma" Case "Körte" Echo "az alma körte" Case "Alma" Echo "Alma:)" Case "Alma" Echo "még egy alma" End Select 'Eredmény: Alma:)

    De jó az ötlet! Megfontolandó.
    Mutasd a teljes hozzászólást!
  • ...várunk minden építő kritikát és ötletet...

    Kár, hogy nem derült ki, hogy milyen lenne az esetelágazása ennek az új nyelvnek, legalábbis a topic szempontjából érdekes lett volna.
    De gondolom a VB Select blokkjával kompatibilis szintaxisra gondolnátok.
    Mondjuk én nem vennék át minden szintaxist a VB-ből, de a VB Select blokkja nagyon jól ki van találva.
    A nyelvek közül, amiket ismerek vagy eddig tanulmányoztam, egy-két szempont kivételével a mai napig a legjobb esetelágazásnak tekintem.
    Amúgy én is nagyrészt a VB Select logikáját ültettem át, egy picit tovább fejlesztve az előző hozzászólásomban.
    Csak pár dolgot módosítanék a VB-ben:
    1. A "Select Case" kulcsszópárban a "Case" kulcsszót vagy teljesen elkéne hagyni, vagy a kompatibilitás miatt opcionálissá tenni, mert felesleges és szerintem zavaró is egyben.
    Azaz elég volna csak ennyi:
    Select i Case 1, 2, 3 task123() End Select


    2. Az "Is" kulcsszó tényleges referenicája (csak olvasható) lenne a Select fejében lévő kifejezésnek.
    Jelenleg csak relációs operátorokkal lehet használni, ami szerintem felesleges megkötés.
    Ezt a feautere-t tovább fejlesztve én is átvettem az "it" kulcsszóval az előző hozzászólásomban, amivel már bármilyen esetre ellehetne ágazni.


    3. Én beleraknék a nyelvbe funkcionális feature-öket is.
    Azaz pl. a Select blokknak lehetne visszatérési értéke, hasonlóan a többi blokknak is (if, while, for, ...).
    Mutasd a teljes hozzászólást!
  • A másik érdekesség - csak kíváncsi volnék a véleményetekre. Beépítettünk egy olyan függvényt amivel ActiveX-et is meghívhatsz a forráskódban. Egy tanult kollégám egyből felcsattant, hogy minek egy szerver oldali programozási nyelvbe ActiveX mivel azt kliens oldalra találták ki. Én azt mondom, hogy nagyon jó mert számos funkcióval bővíthető a megírt alkalmazásunk és az eredmény így is kliens oldalon látható. Arról nem is beszélve hogy az interpreter így más nyelveken is bővíthető. Mi erről a véleményed?

    pl:
    Include.ActiveX "C:\windows\system\valami.ocx", "dinamikus_nev" dinamikus_nev.Font.Size = 16 dinamikus_nev.Caption = "TesztSztring" Echo dinamikus_nev.Caption


    Eredmény: TesztSztring
    Mutasd a teljes hozzászólást!
  • A VB.NET-ben is megoldották valahogy. Ha a VB programozók a célközönség, talán érdemes az általuk ismert szintaxisra építeni.
    Mutasd a teljes hozzászólást!
  • Attempt To Do 'try End OhNo Do 'catch End Anyway Do 'finally End EndAttempt Exception dobása: You Failed at IO // throw new IOException

    Remélem tetszik
    Mutasd a teljes hozzászólást!
  • Jó a meglátásod! Ezt VB szintaxis esetében hogyan tudod elképzelni a gyakorlatban?
    Mutasd a teljes hozzászólást!
  • Gyorsan belenéztem a doksiba.

    A VB-s szintaxis ízlés dolga, arról nem nyilatkoznék, de "On Error Resume Next" és "On Error Goto 0"? 2011-ben? Szerintem ezt el kéne felejteni, és átállni kivétel-alapú hibakezelésre. De ez csak az én véleményem.
    Mutasd a teljes hozzászólást!
  • Üdv Mindenkinek!

    Mi most fejlesztünk egy szerver oldali prg-nyelvet.
    http://www.w8.hu/
    Még készül a leírás, de sok új funkciót tartalmaz. (MySql, Email i/o, SMS küldés, képszerkesztés, konvertálás, méretezés) Tananyagfejlesztésre van kihegyezve. De várunk minden építő kritikát és ötletet!
    Mutasd a teljes hozzászólást!
  • ...ami engem zavar (egyébként a sima C++-ban is), a meglevő kulcsszavak túlterhelése; a kód kevésbé lesz olvasható csak azért, mert egy új kulcsszó esetleg elrontaná a meglevő forrásokat.

    Egyetértek.
    Viszont az új kulcsszavakkal ott van a gond, mint amire már te is céloztál, hogy a meglévő forrásokkal elnevezés ütközések lennének.
    Nekem is jobban tetszene pl. egy intervallumos ciklust így jelölni:
    range (int i = 1 .. 100)

    A switch helyett pedig mondjuk ezt használni:
    int j = select (i) { when 1, 2, 3: select = 100; }
    (Ha valakinek van jobb ötlete az elnevezésekre, ne fogja vissza magát.)
    Valóban megtévesztő tud lenni a régi kulcsszavak túlterhelése, felőlem használhatunk újakat, amik ráadásul még kifejezőbbek is.


    Ha értéket akarsz adni valaminek valamelyik ágon belül, sokkal világosabb egy hagyományos értékadás ehelyett a speciális alak helyett. Igen, többször ki kell írni a változó nevét, de ez tényleg akkora nagy gond?

    Gondolom ilyesmire gondolsz:
    int j; select (i) { when 1, 2, 3: j = 1; when 4, 5, 6: j = 2; when 7, 8, 9: j = 3; }

    Ezzel összehasonlítva:
    int j = select (i) { when 1, 2, 3: select = 1; when 4, 5, 6: select = 2; when 7, 8, 9: select = 3; }
    Nem sok a különbség, de szerintem az utóbbinál azért vannak előnyök:
    - világos a szándék
    - jobban karbantartható a kód


    ha már értéklistán és tartományon kívül másra is akarsz illeszteni, nem lenne jobb egy if-else lánc?

    Mondok egy egyszerű példát.
    Tételezzük fel, hogy a select blokk csak egyenlőségre és intervallumra tudna elágazni, másra nem.
    És mondjuk van nekem egy elég komplex select elágazásom egy szám különféle eseteinek alapján.
    Elégedett vagyok a kóddal, mert világos a szándék, könnyen átlátható, jól karbantartható és nem utolsó sorban redundancia mentes, tehát szakmailag is úgy érzem, hogy minden a helyén van.
    Aztán egyszer csak jön egy olyan igény, hogy el kéne ágazni akkor is, ha az adott szám mondjuk nagyobb, mint 100 vagy mondjuk az adott szám páros szám.
    Nem egy komoly kihívás, viszont ilyet nem lehet megcsinálni egy olyan elágazó szerkezettel, ami csak egyenlőséget és intervallumot tud vizsgálni.
    Mit tud csinálni programozó?
    Átírja az egészet if szerkezetbe.
    Na innentől kezdve nem hiszem, hogy elégedett lenne bárki is a kóddal, erős hiány érzete lenne akárhányszor találkozik ezzel módosítással.
    Joggal lehet feltenni a kérdést, hogy a "nagyobb, mint 100" vagy a páros szám miért nem esete egy adott számnak?
    Miért csak az egyenlőség és az intervallum az eset?
    Miért kell emiatt egy kevésbé áttekinthető elágazást csinálni, ami tele van redundanciával és homályos lehet más programozó számára, hogy mi a cél, azaz úgy kell majd mindig visszafejtenie és rájönnie, hogy itt az i változó különböző eseteiről van szó.

    Ha pl. az "it" kulcsszó referenciája lenne a fejben lévő kifejezésnek, akkor a nagyobb, mint 100 vizsgálat könnyen megoldható lenne és emiatt még nem kéne elgondolkodni az if-re való váltásra:
    select (i) { when ................ ................ when ................ ................ when ................ ................ when it > 100: //az it kulcsszó referenciája a fejben lévő kifejezésnek (i) taskX(); when ................ ................ default: ................ }

    Aminél viszont már megfontolandó volna if-re átírni az pl. a párosszám (stb...) vizsgálat:
    select (i) { when ................ ................ when ................ ................ when ................ ................ when ................ ................ when it * (it % 2 == 0 ? 1 : -1): taskY(); default: ................ }

    Ugyanis rosszabbul olvasható, mint ez:
    if (................) { ................ } else if (................) { ................ } else if (................) { ................ } else if (................) { ................ } else if (i % 2 == 0) { taskY(); } else { ................ }
    Itt mérlegelni kéne az egész blokk szempontjából, hogy mi a fontosabb az olvashatóság vagy a redundancia mentesség.
    Szerencsére az ilyen szituáció elég ritka, viszont a programozónak lehetősége lenne a döntésre, hogy szerinte mikor melyik lenne a jobb választás.
    Mutasd a teljes hozzászólást!
  • Az én ízlésemnek ez a switch már "túl sokat tud", túl sok speciális esetet kell megtanulni hozzá. A másik, ami engem zavar (egyébként a sima C++-ban is), a meglevő kulcsszavak túlterhelése; a kód kevésbé lesz olvasható csak azért, mert egy új kulcsszó esetleg elrontaná a meglevő forrásokat.

    Ha értéket akarsz adni valaminek valamelyik ágon belül, sokkal világosabb egy hagyományos értékadás ehelyett a speciális alak helyett. Igen, többször ki kell írni a változó nevét, de ez tényleg akkora nagy gond?

    Hasonlóan, ha már értéklistán és tartományon kívül másra is akarsz illeszteni, nem lenne jobb egy if-else lánc? A fordító úgyis azt fog belőle csinálni, az általános esetre nincs más stratégia. (Folytonos tartomány esetén ugye lehet ugrótáblát generálni, egyéb esetben bináris keresést lehet alkalmazni az értéktartományon, de egyik esetben sem kell az összes értékkel hasonlítani. Ha viszont már függvényhívásaid vannak mellékhatással, kénytelen lesz a nyelv definiálni, hogy milyen sorrendben értékelődnek ki az ágak.)
    Mutasd a teljes hozzászólást!
  • Mivel nem írtam ki explicite a returnt, lehet, hogy én nem is akartam értéket visszaadni, de közben egy másik kód már épít erre a visszatérési értékre...
    "Explicit is better than implicit", ahogy a Zen of Python is mondja


    Ezzel én is egyet értek.
    Számomra is furcsa egy kicsit, hogy egy blokkutasítás visszatérési értéke a legutolsó értékkifejezés, mint pl. a Ruby-ban.
    int j = switch (i) { when 1, 2, 3: 100; //értékadás a j változónak szám literállal (ez kilógna a C szintaxisból) }
    A következő problémákat látom az utolsó "értékkifejezés"-sel kapcsolatban:
    - nem illik bele a C szintaxisba
    - értékkel visszatérő függvény esetén nem biztos, hogy értéket szeretnénk átadni a switch-when blokkal
    - ...

    Egy C függvény visszatérési értéke is explicit módon történik a return kulcsszóval, tehát szerintem itt is valami explicit módszer volna jobb.
    (Egy előnye azért van a legutolsó értékkifejezés-nek, mégpedig az, hogy strukturált megközelítés, ellenben a return-nel, ami gyakorlatilag egy ugró utasítás.)

    Én így képzelném el az explicit értékadást:
    string s = switch (i) { when 1, 2: switch = "xy"; // értékadás az s változónak when 3, 4: for (j .. k) {// megj: új szintaxisú intervallumos for ciklus func34(j); // van amikor ez volna az utolsó értékkifejezés if (j == 10) switch = "abc"; // értékadás az s változónak (egyszer) } default: // ebben az ágban nem akarom módosítani az s változó értékét Other(); }
    A switch kulcsszó az értékadás bal oldalán egy referenciát jelölne a blokk fejében lévő értékkifejezésre.
    Azért választottam a switch kulcsszót, mert:
    - szerintem szemléletes
    - nem kell bevezetni új kulcsszót
    - fellehetne használni arra is, hogy a switch blokk fejében lévő kifejezés bármilyen esetére ellehessen ágazni, pontosabban nem csak az egyenlőségre (==):
    switch (i) { when EqualIfPrime(switch): //elágazás, ha i prímszám task1(); when EqualIfInRange(switch, 50, 100)://elágazás, ha i értéke 50 és 100 között van és nem prímsz. task2(); when EqualIfGreater(switch, 200): //elágazás, ha i nagyobb, mint 200 és nem prímszám task3(); } int EqualIfPrime(int number) {// return IsPrime(number) ? number : -1 * number; if (IsPrime(number)) return number; else return -1 * number; } int EqualIfInRange(int number, int from, int to) { if (number >= from && number <= to) return number; else return -1 * number; } int EqualIfGreater(int number1, int number2) { if (number1 > number2) return number1; else return -1 * number1; }
    Tehát ezzel a módszerrel nem csak egyenlőségre, hanem bármilyen más esetre is ellehetne ágazni, de ettől függetlenül én még felvennék 2 speciális, de gyakori esetvizsgálatot, ami talán kilóg az eddigi vesszővel felsorolt esetek logikájából, de nagyon szemléletes és könnyen olvasható kódot kapunk.
    switch (i) { when 50 .. 100: // elágazás, ha i értéke 50 és 100 között van (range operátor) task2(); when switch > 200: // elágazás, ha i nagyobb, mint 200 (relációs operátor) task3(); }
    Továbbá én ezt is megengedném:
    switch (i) { when 9, 14, 50 .. 100, switch > 200: task(); // elágazás, ha i értéke 9 vagy 14, vagy 50 és 100 között van, vagy nagyobb, mint 200 }
    Vagyis az eddigi 1 helyett, 3 alapértelmezett vizsgálata lenne egy esetfelsorolásnak a kifejezés típusától függően.
    1. Ekvivalenica vizsgálat (==), ami eddig is volt:
    ha az adott eset egy értéket visszaadó kifejezés (szám literál, konstans, változó, értékkel visszatérő függvény, property, ...)

    2. Intervallum vizsgálat:
    ha az adott eset egy range operátoros kifejezés (..)

    3. Relációs vizsgálat:
    ha az adott eset egy switch kulcszóval megvalósított relációs kifejezés


    A range operátor (..) egy új "operátor" lenne, amit három helyen képzelnék el felhasználni:
    1. a for ciklus második szintaxisaként, mint intervallumos számláló ciklus tartománya:
    for (int i = 1 .. 100) //ciklus 1-től 100-ig
    2. a switch-when blokk esetfelsorolásaiban
    3. kettős operátorként logikai (bool) eredménnyel:
    bool b1 = 5 ? 1 .. 9 // true bool b2 = 100 ? 1 .. 9 // false

    Én a C szintaxis tovább fejlesztése oldaláról közelítettem meg a témát.
    Egy új nyelvben ez sokkal egyszerűbb lett volna.
    Remélem nem fárasztottam le senkit.
    Mutasd a teljes hozzászólást!
  • A kérdés jogos.
    Alapvetően én úgy gondoltam, hogy a kapcsoszárójelek elhagyásával a when és a default ágak továbbra is blokkok maradnának.
    Vagyis egy switch-when elágazásban ez hibás kód volna:
    switch (i) { // ez egy blokk when 1: // ez is blokk int j = 0; when 2: // ez is blokk j++; //ez hiba, mert j változónak másik SCOPE-ban van a deklarációja }

    Ugyanúgy if-fel:
    if (i == 1) { int j = 0; } else if (i == 2) { j++; //ez hiba, mert j változónak másik SCOPE-ban van a deklarációja }
    C# hibaüzenet: The name 'j' does not exist in the current context


    Viszont két dolog nem stimmel:
    1. az eredeti switch-ben az "ágak" nem blokkok.
    2. a switch-when szerkezet kilógna a C szintaxisból, mert a blokk jelölést {} sehol nem lehet elhagyni, ahol blokkot kell értelmezni

    Például a do-while ciklusban is kötelező a blokk jelőlés pedig elviekben ott felesleges lehetne:
    do { // } while (b);
    Ezek miatt módosítanám a switch-when blokkot.
    A szintaxis ugyanúgy maradna, de a when és a default ágak nem lennének blokkok akárcsak az eredeti switch-ben sem az elágazások.
    A fenti hiba továbbra is hiba maradna, de a fordító más hibaüzenet küldene:
    switch (i) { // ez blokk when 1: // ez most már nem blokk! int j = 0; when 2: // ez most már nem blokk! j++; //ez hiba, mert j változónak másik ÁGBAN-ban van a deklarációja }

    Ugyanez switch-ben:
    switch (i) { // ez blokk case 1: // ez nem blokk! int j = 0; break; case 2: // ez sem blokk! j++; //ez hiba, mert j változónak másik ÁGBAN-ban van a deklarációja break; }
    C# hibaüzenet: Use of unassigned local variable 'j'

    Jobban örültem volna, ha az esetágak mégiscsak blokkot maradtak volna, bár ennek olyan nagy jelentősége talán nincs.
    Viszont, ha mégis van, akkor vissza kéne térnem az első elképzelésemhez, amit azért vetettem, el mert függőlegesen nagyon terjeszkedő volt:
    var myvar = switch (i) { case (1, 2) { func1(); func2(); //értékadás a myvar változónak } case (3, 4, 5, 6) { func3(); func4(); func5(); func6(); //értékadás a myvar változónak } case (7, 8, 9) { func789(); //értékadás a myvar változónak } default { Other(); //értékadás a myvar változónak } } //18 sor

    Ha pedig valaki külön-külön sorban szereti jelölni a nyító és a záró kapcsoszárójeleket, úgy még jobban terjengős.
    var myvar = switch (i) { case (1, 2) { func1(); func2(); //értékadás a myvar változónak } case (3, 4, 5, 6) { func3(); func4(); func5(); func6(); //értékadás a myvar változónak } case (7, 8, 9) { func789(); //értékadás a myvar változónak } default { Other(); //értékadás a myvar változónak } } //23 sor
    Így végképp nem volna "versenyképes" még a "szószátyár" Visual Basic-kel szemben sem.

    Elképzelt VB.net kód értékadó blokkutasítással:
    Dim myvar = Select Case i Case 1, 2 func1() func2() ' értékadás a myvar változónak Case 3 To 6 func3() func4() func5() func6() ' értékadás a myvar változónak Case 7, 8, 9 func789() ' értékadás a myvar változónak Case Else Other() ' értékadás a myvar változónak End Select ' 14 sor
    A 23 és a 14 sor között már elég nagy a különbség.

    Tehát a kérdés az az, hogy egy esetelágazásnak is blokknak kéne lennie vagy sem?
    Mutasd a teljes hozzászólást!
  • Alapvetően tetszik a megoldásod, de C++ alatt láthatósági problémákat okozhat. Az alapszabály ott ugye az, hogy deklaráció bárhol szerepelhet a blokkon belül, a változó a blokk maradék részén látszik, és a blokk végén hívódik a destruktor.

    Példa:
    switch (i) { when 'a': ExpensiveObject stuff; stuff.frobnicate(); when 'b': // Itt most akkor látszik a "stuff" változó, vagy sem? // Ha látszik, mi az értéke? A konstruktorhívást átugrottuk... doStuff(); }

    Persze ugyanez a gond megvan a jelenlegi switch szerkezettel is, és a fordító úgy oldja meg, hogy hibát jelez (konstruktorhívást átugrani tilos). A kötelező blokkokkal megoldódna ez a lehetséges hibaforrás.
    Mutasd a teljes hozzászólást!
  • Továbbá szerintem a case kulcsszó itt már fölösleges, csak fölösleges karakterleütés.
    var myvar = eval(expression()) { 'a': fun1(); 'b', e1(), 'c': { fun2(); fun3(); fun4(); } }


    Valóban felesleges a case kulcsszó, viszont szerintem így nehezebben lesz olvasható a kód.
    Igazából vagy a case kulcsszó a felesleges vagy a kapcsoszárójelezés.
    Ezek alapján tovább gondolva a következő szintaxisra jutottam:
    var myvar = switch (i) { when 1, 2: func1(); func2(); //értékadás a myvar változónak when 3, 4, 5, 6: func3(); func4(); func5(); func6(); //értékadás a myvar változónak when 7, 8, 9: func789(); //értékadás a myvar változónak default: Other(); //értékadás a myvar változónak } //14 sor

    Én inkább a kapcsoszárójeleket {} hagynám el, ami amúgy is csak 2 karakterrel rövidebb, mint a when vagy a case kulcsszó, viszont így kifejezőbb kódot kapunk (legalábbis szerintem).
    A when kulcsszóra azért volna szükség, hogy a compiler megtudja különböztetni a régi fall through switch szintaxist az újabbtól.
    Előnyök:
    1. jobban olvasható a kód (bár ez szubjektív)
    2. a régi switch-hez eléggé hasonlít, azaz nem lóg ki megszokott C szintaxisból
    3. nem kell egy újabb esetelágazási utasítást felvenni (bár a switch szerintem sem a legjobb elnevezés...)
    4. csökken a függőleges terjeszkedése a blokknak, lévén, hogy az alblokkok kapcsoszárójelei ki lettek véve

    Néhány példa összehasonlításképp:

    Ugyanez nadamhu és hurka féle eval blokkal:
    var myvar = eval (i) { 1, 2: { func1(); func2(); //értékadás a myvar változónak } 3, 4, 5, 6: { func3(); func4(); func5(); func6(); //értékadás a myvar változónak } 7, 8, 9: { func789(); //értékadás a myvar változónak } default: { //(feltételezve) Other(); //értékadás a myvar változónak } } //18 sor


    Ugyanez a régi swith-csel és fall through-val:
    var myvar; switch (i) { case 1: case 2: func1(); myvar = func2(); //értékadás a myvar változónak break; case 3: case 4: case 5: case 6: func3(); func4(); func5(); myvar = func6(); //értékadás a myvar változónak break; case 7: case 8: case 9: myvar = func789(); //értékadás a myvar változónak break; default: myvar = Other(); //értékadás a myvar változónak break; } //25 sor


    Ugyanez if szerkezettel (redundánsan):
    var myvar; if (i == 1 || i == 2) { func1(); myvar = func2(); //értékadás a myvar változónak } else if (i >= 3 && i <= 6) { func3(); func4(); func5(); myvar = func6(); //értékadás a myvar változónak } else if (i == 7 || i == 8 || i == 9) { myvar = func789(); //értékadás a myvar változónak } else { myvar = Other(); //értékadás a myvar változónak } //14sor


    Ugyanez Ruby-ban:
    myvar = case i when 1, 2 func1() func2() # értékadás a myvar változónak when 3 .. 6 func3() func4() func5() func6() # értékadás a myvar változónak when 7, 8, 9 func789() # értékadás a myvar változónak else Other() # értékadás a myvar változónak end #14 sor


    Ugyanez Visual Basic.net-ben:
    Dim myvar Select Case i ' ebben a sorban a Case kulcsszó teljesen felesleges, zavaró és megtévesztő Case 1, 2 func1() myvar = func2() ' értékadás a myvar változónak Case 3 To 6 func3() func4() func5() myvar = func6() ' értékadás a myvar változónak Case 7, 8, 9 myvar = func789() ' értékadás a myvar változónak Case Else myvar = Other() ' értékadás a myvar változónak End Select ' 15 sor


    Remélem nem hibásak a példák (a legtöbbet sima notepad-ben írtam).
    Mutasd a teljes hozzászólást!
  • Felfoghatjuk úgy, hogy egyszerűen az if elseif-es megoldás tömörebb, világosabb, gyorsabban átlátható szintaktikai leírásáról van szó.


    Igen, erre akartam utalni, ilyenkor már nem switch-ről beszélünk...
    Például lehetne hívni eval-nak, szerintem jobban illene rá:

    var myvar = eval(expression()) { 'a': fun1(); 'b', e1(), 'c': { fun2(); fun3(); fun4(); } }
    Mutasd a teljes hozzászólást!
  • Ez jogos, hirtelen nem jutott eszembe :) .
    Mutasd a teljes hozzászólást!
  • Az meg tapasztalat szerint csak rosszhoz vezet, ha a kód 95%-ban valahogy működik egy operátor, és 5%-ban pedig másként.


    A vessző már eleve ilyen: alapértelmezésben operátor, kivéve azokon a helyeken, ahol elemelválasztó szerepet ad neki a szintaxis: függvény paraméterlistájában, tömb literálnál, deklarációs listánál, és talán még máshol is. Ennek fényében szerintem nem lenne probléma, ha egy "új switch" struktúrában is elválasztó szerepet kapna, főleg, hogy a vessző operátornak nincs sok értelme az adott környezetben (meg máshol se nagyon).

    Ha rajtam múlna, a vessző operátort úgy kipusztítanám a nyelvből, hogy nyoma se maradjon. Értelmes kód maximum a for ciklus fejében használja, bárhol máshol csak obfuszkálja a kódot. De ez már off, ez a téma a switch-ről szól
    Mutasd a teljes hozzászólást!
  • Tapasztalatom szerint a switch-et legtöbbször konstans case-ekkel szokták használni olyan nyelvekben is, ahol megengedett a nem konstans case. De nem látom értelmét, hogy lekorlátozzuk konstansokra, a fordítónak semmiből nem tart azt csinálnia, hogy ha csak konstansok vannak akkor valami brutál optimalizált kódot produkál, nem konstansok esetén meg egy egyszerű if elseif-nek megfelelő cuccot. Felfoghatjuk úgy, hogy egyszerűen az if elseif-es megoldás tömörebb, világosabb, gyorsabban átlátható szintaktikai leírásáról van szó.
    Mutasd a teljes hozzászólást!
  • Az, hogy minden ág értékei kiértékelődjenek szerintem nem jó ötlet, a legtöbb esetben fölösleges performanciapazarlás, meg a default is értelmét vestené. Nem jó ötlet. Pl. a Scala is az első igazig értékel ki, és csodálkonék, ha más nyelvek is nem így csinálnák.


    Szerintem se jó ötlet, csak arra próbáltam felhívni a figyelmet, hogy a switch-et elvileg úgy szokták alkalmazni (legalábbis c#-ban tuti), hogy egy ág kifejezése(azaz érték inkább) csak egyszer szerepelhet a listában. Míg a te megoldásoddal simán lehet többször.
    Mutasd a teljes hozzászólást!
  • Szemantikailag a következővel lenne ekvivalens a példám:


    var v = expression(); var myvar = if(v == 'a') fun1(); else if(v == 'b' || v == e1() || v == 'c') { fun2(); fun3(); fun4(); } }

    Természetesen a || operátor lusta kiértékelésű lenne, mint minden általam ismert normális nyelvben.

    Vagyis a sorrend számít: az első igaz ág lefutása után semmi nem értékelődik ki.

    Az, hogy minden ág értékei kiértékelődjenek szerintem nem jó ötlet, a legtöbb esetben fölösleges performanciapazarlás, meg a default is értelmét vestené. Nem jó ötlet. Pl. a Scala is az első igazig értékel ki, és csodálkonék, ha más nyelvek is nem így csinálnák.

    Előfordulhat persze, hogy olyasmit akar az ember, hogy minden kiértékelődjön, ezt nyilván sima if-ekkel megteheti:

    if(v == e1()) fun1(); if(v == e2()) fun2();

    Persze lehetne egy opciója a switchnk, hogy 'fullkiértékelésű' legyen, vagy a megszokott 'laza', de ez viszont már az én ízlésemnek a nyelv túlbonyolításának tűnik, szóval nem preferálnám.
    Mutasd a teljes hozzászólást!
  • Nekem az a bajom az ilyen megoldásokkal, hogy ha te leírsz egy kifejezést, pl a, b vagy a | b az operátornak számít C++-ban. És a legtöbb esetben el is várjuk, hogy elvégezze az adott műveletet a fordító (ha konstans) vagy a runtime.

    Az meg tapasztalat szerint csak rosszhoz vezet, ha a kód 95%-ban valahogy működik egy operátor, és 5%-ban pedig másként. C++-ban ilyennek nem igazán lenne helye, egy új nyelvben már persze okés. De ez persze egyéni vélemény, bár lehet csak én ragaszkodok mereven a megszokott dolgokhoz :) .
    Mutasd a teljes hozzászólást!
  • Összefoglalva tehát itt egy példa, ami minden említett feature-t felhasznál:



    var myvar = switch(expression()) { 'a': fun1(); 'b', e1(), 'c': { fun2(); fun3(); fun4(); } }

    És mi történik, ha e1() == 'a'-val?
    Az első eset fog lefutni vagy mindkettő?

    Cseréljük fel a sorrendet:

    var myvar = switch(expression()) { 'b', e1(), 'c': { fun2(); fun3(); fun4(); } 'a': fun1(); }

    Itt mindig kiértékelődik az e1() ? (kivéve, ha nem 'b'-ről vagy 'c'-ről van szó? És csak az első ág fut le e1() == 'a' esetén vagy mindkettő? Ha nem csak az első ág fut le, akkor milyen sorrendben történik?

    Nekem eddig a switch azt jelentette, hogy mindig egyértelműen egy ág fut le, és a Te példádban simán előfordulhat, hogy két ág feltétele is megegyezhet az expression()-el.
    Mutasd a teljes hozzászólást!
  • A switchnek pont a jump table generálás...
    ...manapság a legtöbb nyelv arra megy rá, egyszerű fejleszthetőség, a sebesség meg csak másodlagos...


    Sajnos a C szintaxisú nyelvek switch utasítása a mai formájában nem igazán alkalmas új feature-ök befogadására, főleg az elágazásokhoz tartozó felsorolási módszere és a break miatt.
    Lévén, hogy a switch utasítás kompatibilitási és egyéb jogos okok miatt (pl. sebesség, ugrótábla, stb.) benne fog maradni a C nyelvekben, valamint egy újabb elágazási blokkutasítást sem volna célszerű felvenni.
    Ezért (akárcsak a for ciklusnál) szerintem itt is egy másodlagos szintaxis lehetne a megoldás, mondjuk egy olyan szintaxissal, amit már LC is javasolt a legelején.

    switch (i) { case (1, 2, 3) { //alblokk func1(); func2(); func3(); } case (4, 5, 6) func456(); //csak egy utasítás default { funcOther(); } }

    Az új szintaxisban:
    1. a case után zárójelben lehetne felsorolni az eseteket
    2. az elágazások kapnának egy-egy új alblokkot (vagy egy szimpla utasítást).
    3. fall through nem lenne (esetleg megfontolandó volna erre egy új utasítást felvenni mondjuk pl. "fall" néven, bár nekem az elv nem tetszik)
    4. a kétféle switch szintaxist nem engedné keverni a compiler

    Így megmaradna a 40 éves kompatibilitás és tovább fejlődhetne az esetelágazás is.
    Plusz előny lenne még, hogy az új szintaxis talán jobban bele illene a C szintaxisba, lévén, hogy jobban "hasonlítana" a másik elágazó utasításhoz az if-hez a zárójelezés és az azt követő blokk miatt.
    Mutasd a teljes hozzászólást!
  • Nekem kellene kitalálnom a nyelvet valami ilyesmi lenne

    #feltetel = ertek ;
    #feltetel== 100 , elso();
    #feltetel== 200, masodik(),harmadik();
    #feltetel , alapertelmezett();
    Mutasd a teljes hozzászólást!
  • Érdekesnek tűnik. Sajnos szinte egyáltalán nem ismerem a Perl-t. Viszont sokszor láttam említve blogokban, és azokban mint egy fejlett nyelvként írtak róla, (ha jól értem a Perl5-öt szokták igazán fejlett nyelvként említeni, és nem az elődöket). Igazából a a Python, Ruby és Perl5-ről olyan kép él a fejemben, hogy fejlett, modern dinamikus nyelvek, de egyiket sem ismerem elég jól (jó, mondjuk azért a Ruby-t valamennyire).
    Mutasd a teljes hozzászólást!
  • És mit szólsz a perl switch-éhez?
    vagy a régebbi módszer amikor még nem volt switch a nyelvben:

    $exp = 20; SWITCH: { $exp == 20 && do { ......; last SWITCH; }; valamifeltétel && do { print "fall-through lesz";}; $exp =~ /\d/g && do {print "illeszkedik a mintára"; last SWITCH; }; print "default ág"; }

    de itt még találhattok szép switcheket
    Ja, és perlben minden blokk visszatér a legutolsó utasításával, szóval lefed minden követelményt, még többet is.
    Mutasd a teljes hozzászólást!
  • Ilyet én sem, mert egy metódusba ennyire mély logikát ém nem raknék.

    using connection, using command, using reader, while reader.Read, try/catch és egy if vagy switch. Ez már 6 szint és csak egyetlen célt valósít meg, amit szétszedni szerintem hülyeség (lehet még fokozni stream és/vagy Graphics kezeléssel ami kapcsolatban van az adatbázisból kapott adatokkal).
    De persze ez egy extrém példa.

    Egyébként meg azért jó, hogy olyan sokféle nyelv/platform létezik, mert így mindenki megtalálhatja a kedvencéd, aztán lehet flamelni egy "melyik a legjobb" topicban. :)

    Mutasd a teljes hozzászólást!
  • A switch C#-ban sem ad vissza értéket jelenleg sem, hisz nem ez a funkcionalitása.


    A C# nem rossz nyelv, de messze nem a nyelvek alfa-omegája. Mivel azt említetted, hogy végül a vb.net switch-ét fogjuk fletalálni, úgy értelmeztem, hogy a vb.net switch-e valami nagyon fejlett valami, ezért elég magas mércét alkalmaztam, és elég advanced nyelvek switch-jével mértem össze, mint pl. a Scala.

    Azt, hogy 'hisz nem ez a funkcionalitása', azt nem értem: ez tautológia, ha a C# switch-je nem expression, akkor nem expression. Az ok az, hogy a funkcionális és az imperatív nyelvek fúziója elég újkeletű dolog, a Java, C# kitalálásakor még ez az igény nem volt annyira elterjedt, mint ma.

    ugyanakkor nem látok ilyet egy képernyőn:


    Ilyet én sem, mert egy metódusba ennyire mély logikát ém nem raknék. Illetve ha ráállok egy nyitókapcsosra, egy jó szerkesztő azonnal highlightolja a párját.
    Én megértelek, mert a lisp, vagy clojure zárójelmennyisége az én ízlésemnek is durva, de a kapcsoszárójeles szintaktikailag C-utód nyelvek kapcsoszárójelmennyisége egy jó kompromisszum az én ízlésemnek.
    Mutasd a teljes hozzászólást!
  • Ha jól látom pl. egyáltalán nem funkcionális, a switch case nem is ad vissza értéket.

    A switch C#-ban sem ad vissza értéket jelenleg sem, hisz nem ez a funkcionalitása. Én arra egy külön "operátort" alkalmaznék a ?: opreátor mintájára.

    de így első ránézésre borzalmasan szószátyárnak tűnik.

    Az. Ennek megvan az előnye és a hátránya is. Mivel a jó IDE és intellisense miatt nem kell többet gépelni, mint C#-ban így a szószátyárság engem annyira nem zavar, ugyanakkor nem látok ilyet egy képernyőn:
    } } return false; } } return false; } } } } return true; }

    Amiről komment nélkül gőzöm nincs, hogy ki kivel van és melyik } jel mit zár le.
    Mutasd a teljes hozzászólást!
abcd